From 25f89385d3ec13cb4b0a975c2279ee8f27720254 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 26 Apr 2017 18:53:23 -0700 Subject: [PATCH 0001/1581] Add a clock that uses System.currentTimeMillis() and System.nanoTime(). --- .../instrumentation/internal/MillisClock.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 core/src/main/java/com/google/instrumentation/internal/MillisClock.java diff --git a/core/src/main/java/com/google/instrumentation/internal/MillisClock.java b/core/src/main/java/com/google/instrumentation/internal/MillisClock.java new file mode 100644 index 0000000000..9c7e347a1a --- /dev/null +++ b/core/src/main/java/com/google/instrumentation/internal/MillisClock.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.internal; + +import com.google.instrumentation.common.Clock; +import com.google.instrumentation.common.Timestamp; + +/** + * A {@link Clock} that uses {@link System#currentTimeMillis()} and {@link System#nanoTime()}. + */ +public final class MillisClock extends Clock { + private static final MillisClock INSTANCE = new MillisClock(); + + private MillisClock() {} + + /** + * Returns a {@code MillisClock}. + * + * @return a {@code MillisClock}. + */ + public static MillisClock getInstance() { + return INSTANCE; + } + + @Override + public Timestamp now() { + return Timestamp.fromMillis(System.currentTimeMillis()); + } + + @Override + public long nowNanos() { + return System.nanoTime(); + } +} From 6ca6f910ffa31b98838fc802aef6f42aeb254a3d Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 26 Apr 2017 18:53:47 -0700 Subject: [PATCH 0002/1581] Add a clock for testing. --- .../instrumentation/internal/TestClock.java | 85 +++++++++++++++++++ .../internal/TestClockTest.java | 56 ++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 core/src/main/java/com/google/instrumentation/internal/TestClock.java create mode 100644 core/src/test/java/com/google/instrumentation/internal/TestClockTest.java diff --git a/core/src/main/java/com/google/instrumentation/internal/TestClock.java b/core/src/main/java/com/google/instrumentation/internal/TestClock.java new file mode 100644 index 0000000000..ec529859b5 --- /dev/null +++ b/core/src/main/java/com/google/instrumentation/internal/TestClock.java @@ -0,0 +1,85 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.internal; + +import com.google.instrumentation.common.Clock; +import com.google.instrumentation.common.Timestamp; +import java.math.BigInteger; + +/** + * A {@link Clock} that allows the time to be set for testing. + */ +public final class TestClock extends Clock { + private static final int NUM_NANOS_PER_SECOND = 1000 * 1000 * 1000; + + private Timestamp currentTime = Timestamp.create(0, 0); + + private TestClock() {} + + /** + * Creates a clock initialized to time 0. + * + * @return a clock initialized to time 0. + */ + public static TestClock create() { + return new TestClock(); + } + + /** + * Creates a clock with the given time. + * + * @param time the initial time. + * @return a new {@code TestClock} with the given time. + */ + public static TestClock create(Timestamp time) { + TestClock clock = new TestClock(); + clock.setTime(time); + return clock; + } + + /** + * Sets the time. + * + * @param time the new time. + */ + public void setTime(Timestamp time) { + currentTime = validateNanos(time); + } + + @Override + public Timestamp now() { + return currentTime; + } + + @Override + public long nowNanos() { + return getNanos(currentTime).longValue(); + } + + private static Timestamp validateNanos(Timestamp time) { + BigInteger nanos = getNanos(time); + if (nanos.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0 + || nanos.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) { + throw new ArithmeticException("Nanoseconds overflow: " + time); + } + return time; + } + + // Converts Timestamp into nanoseconds since time 0. + private static BigInteger getNanos(Timestamp time) { + return BigInteger.valueOf(time.getSeconds()) + .multiply(BigInteger.valueOf(NUM_NANOS_PER_SECOND)) + .add(BigInteger.valueOf(time.getNanos())); + } +} diff --git a/core/src/test/java/com/google/instrumentation/internal/TestClockTest.java b/core/src/test/java/com/google/instrumentation/internal/TestClockTest.java new file mode 100644 index 0000000000..31e7b763bf --- /dev/null +++ b/core/src/test/java/com/google/instrumentation/internal/TestClockTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.internal; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.instrumentation.common.Timestamp; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for {@link TestClock}. + */ +@RunWith(JUnit4.class) +public final class TestClockTest { + private static final int NUM_NANOS_PER_SECOND = 1000 * 1000 * 1000; + + @Test + public void setAndGetTime() { + TestClock clock = TestClock.create(Timestamp.create(1, 2)); + assertThat(clock.now()).isEqualTo(Timestamp.create(1, 2)); + clock.setTime(Timestamp.create(3, 4)); + assertThat(clock.now()).isEqualTo(Timestamp.create(3, 4)); + } + + @Test + public void measureElapsedTime() { + TestClock clock = TestClock.create(Timestamp.create(10, 1)); + long nanos1 = clock.nowNanos(); + clock.setTime(Timestamp.create(11, 5)); + long nanos2 = clock.nowNanos(); + assertThat(nanos2 - nanos1).isEqualTo(1000 * 1000 * 1000 + 4); + } + + @Test(expected = ArithmeticException.class) + public void catchOverflow() { + TestClock.create(Timestamp.create(Long.MAX_VALUE / NUM_NANOS_PER_SECOND + 1, 0)); + } + + @Test(expected = ArithmeticException.class) + public void catchNegativeOverflow() { + TestClock.create(Timestamp.create(Long.MIN_VALUE / NUM_NANOS_PER_SECOND - 1, 0)); + } +} From acbe7ab79d53c6960d482226bdb430924161d56a Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 27 Apr 2017 10:11:26 -0700 Subject: [PATCH 0003/1581] Use Guava's LongMath instead of BigInteger to catch overflow. --- .../instrumentation/internal/TestClock.java | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/internal/TestClock.java b/core/src/main/java/com/google/instrumentation/internal/TestClock.java index ec529859b5..746e642402 100644 --- a/core/src/main/java/com/google/instrumentation/internal/TestClock.java +++ b/core/src/main/java/com/google/instrumentation/internal/TestClock.java @@ -13,9 +13,9 @@ package com.google.instrumentation.internal; +import com.google.common.math.LongMath; import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.Timestamp; -import java.math.BigInteger; /** * A {@link Clock} that allows the time to be set for testing. @@ -64,22 +64,17 @@ public Timestamp now() { @Override public long nowNanos() { - return getNanos(currentTime).longValue(); + return getNanos(currentTime); } private static Timestamp validateNanos(Timestamp time) { - BigInteger nanos = getNanos(time); - if (nanos.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0 - || nanos.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) { - throw new ArithmeticException("Nanoseconds overflow: " + time); - } + getNanos(time); return time; } - // Converts Timestamp into nanoseconds since time 0. - private static BigInteger getNanos(Timestamp time) { - return BigInteger.valueOf(time.getSeconds()) - .multiply(BigInteger.valueOf(NUM_NANOS_PER_SECOND)) - .add(BigInteger.valueOf(time.getNanos())); + // Converts Timestamp into nanoseconds since time 0 and throws an exception if it overflows. + private static long getNanos(Timestamp time) { + return LongMath.checkedAdd( + LongMath.checkedMultiply(time.getSeconds(), NUM_NANOS_PER_SECOND), time.getNanos()); } } From 9922475691f3e85932354493502cda13bd5dbe10 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 27 Apr 2017 09:52:43 -0700 Subject: [PATCH 0004/1581] Make TestClock thread-safe. --- .../google/instrumentation/internal/MillisClock.java | 2 ++ .../com/google/instrumentation/internal/TestClock.java | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/internal/MillisClock.java b/core/src/main/java/com/google/instrumentation/internal/MillisClock.java index 9c7e347a1a..035c6e82c7 100644 --- a/core/src/main/java/com/google/instrumentation/internal/MillisClock.java +++ b/core/src/main/java/com/google/instrumentation/internal/MillisClock.java @@ -15,10 +15,12 @@ import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.Timestamp; +import javax.annotation.concurrent.ThreadSafe; /** * A {@link Clock} that uses {@link System#currentTimeMillis()} and {@link System#nanoTime()}. */ +@ThreadSafe public final class MillisClock extends Clock { private static final MillisClock INSTANCE = new MillisClock(); diff --git a/core/src/main/java/com/google/instrumentation/internal/TestClock.java b/core/src/main/java/com/google/instrumentation/internal/TestClock.java index 746e642402..00a36028ba 100644 --- a/core/src/main/java/com/google/instrumentation/internal/TestClock.java +++ b/core/src/main/java/com/google/instrumentation/internal/TestClock.java @@ -16,13 +16,17 @@ import com.google.common.math.LongMath; import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.Timestamp; +import javax.annotation.concurrent.GuardedBy; +import javax.annotation.concurrent.ThreadSafe; /** * A {@link Clock} that allows the time to be set for testing. */ +@ThreadSafe public final class TestClock extends Clock { private static final int NUM_NANOS_PER_SECOND = 1000 * 1000 * 1000; + @GuardedBy("this") private Timestamp currentTime = Timestamp.create(0, 0); private TestClock() {} @@ -53,17 +57,17 @@ public static TestClock create(Timestamp time) { * * @param time the new time. */ - public void setTime(Timestamp time) { + public synchronized void setTime(Timestamp time) { currentTime = validateNanos(time); } @Override - public Timestamp now() { + public synchronized Timestamp now() { return currentTime; } @Override - public long nowNanos() { + public synchronized long nowNanos() { return getNanos(currentTime); } From ccf35e0449143600f38a1abd3ac360a3773aece4 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 27 Apr 2017 09:59:28 -0700 Subject: [PATCH 0005/1581] Add TestClock.advanceTime(Duration). --- .../instrumentation/internal/TestClock.java | 16 ++++++++++++++++ .../instrumentation/internal/TestClockTest.java | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/core/src/main/java/com/google/instrumentation/internal/TestClock.java b/core/src/main/java/com/google/instrumentation/internal/TestClock.java index 00a36028ba..92332b1bca 100644 --- a/core/src/main/java/com/google/instrumentation/internal/TestClock.java +++ b/core/src/main/java/com/google/instrumentation/internal/TestClock.java @@ -15,6 +15,7 @@ import com.google.common.math.LongMath; import com.google.instrumentation.common.Clock; +import com.google.instrumentation.common.Duration; import com.google.instrumentation.common.Timestamp; import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.ThreadSafe; @@ -61,6 +62,21 @@ public synchronized void setTime(Timestamp time) { currentTime = validateNanos(time); } + /** + * Advances the time by a duration. + * + * @param duration the increase in time. + */ + // TODO(sebright): Consider adding an 'addDuration' method to Timestamp. + public synchronized void advanceTime(Duration duration) { + currentTime = + validateNanos( + Timestamp.create( + LongMath.checkedAdd(currentTime.getSeconds(), duration.getSeconds()), + currentTime.getNanos()) + .addNanos(duration.getNanos())); + } + @Override public synchronized Timestamp now() { return currentTime; diff --git a/core/src/test/java/com/google/instrumentation/internal/TestClockTest.java b/core/src/test/java/com/google/instrumentation/internal/TestClockTest.java index 31e7b763bf..0fee071a11 100644 --- a/core/src/test/java/com/google/instrumentation/internal/TestClockTest.java +++ b/core/src/test/java/com/google/instrumentation/internal/TestClockTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.instrumentation.common.Duration; import com.google.instrumentation.common.Timestamp; import org.junit.Test; import org.junit.runner.RunWith; @@ -35,6 +36,13 @@ public void setAndGetTime() { assertThat(clock.now()).isEqualTo(Timestamp.create(3, 4)); } + @Test + public void advanceTime() { + TestClock clock = TestClock.create(Timestamp.create(1, 500 * 1000 * 1000)); + clock.advanceTime(Duration.create(2, 600 * 1000 * 1000)); + assertThat(clock.now()).isEqualTo(Timestamp.create(4, 100 * 1000 * 1000)); + } + @Test public void measureElapsedTime() { TestClock clock = TestClock.create(Timestamp.create(10, 1)); From 4914e1330491f4cf53f164e2c026ec05abf5e27c Mon Sep 17 00:00:00 2001 From: Yang Song Date: Thu, 27 Apr 2017 17:44:01 -0700 Subject: [PATCH 0006/1581] Split RpcConstants into two files. (#259) * Split RpcConstants into two files. * Replace usage of deprecated RpcConstants. --- .../instrumentation/stats/RpcConstants.java | 3 + .../stats/RpcMeasurementConstants.java | 155 +++++++ .../stats/RpcViewConstants.java | 382 ++++++++++++++++++ .../stats/RpcConstantsTest.java | 1 + .../stats/RpcMeasurementConstantsTest.java | 64 +++ .../stats/RpcViewConstantsTest.java | 78 ++++ .../instrumentation/stats/SupportedViews.java | 4 +- .../MeasurementDescriptorToViewMapTest.java | 7 +- .../stats/StatsContextTest.java | 9 +- .../stats/StatsManagerImplTest.java | 73 ++-- .../instrumentation/stats/StatsTest.java | 2 +- 11 files changed, 734 insertions(+), 44 deletions(-) create mode 100644 core/src/main/java/com/google/instrumentation/stats/RpcMeasurementConstants.java create mode 100644 core/src/main/java/com/google/instrumentation/stats/RpcViewConstants.java create mode 100644 core/src/test/java/com/google/instrumentation/stats/RpcMeasurementConstantsTest.java create mode 100644 core/src/test/java/com/google/instrumentation/stats/RpcViewConstantsTest.java diff --git a/core/src/main/java/com/google/instrumentation/stats/RpcConstants.java b/core/src/main/java/com/google/instrumentation/stats/RpcConstants.java index 57df9cf01b..5a89e564d5 100644 --- a/core/src/main/java/com/google/instrumentation/stats/RpcConstants.java +++ b/core/src/main/java/com/google/instrumentation/stats/RpcConstants.java @@ -26,6 +26,9 @@ /** * Constants for collecting rpc stats. */ +// Deprecated, please use RpcMeasurementConstants for MeasurementDescriptor constants, and +// RpcViewConstants for ViewDescriptor constants. +@Deprecated public final class RpcConstants { // Rpc tag keys. public static final TagKey RPC_STATUS = TagKey.create("OpStatus"); diff --git a/core/src/main/java/com/google/instrumentation/stats/RpcMeasurementConstants.java b/core/src/main/java/com/google/instrumentation/stats/RpcMeasurementConstants.java new file mode 100644 index 0000000000..6de20bc4a1 --- /dev/null +++ b/core/src/main/java/com/google/instrumentation/stats/RpcMeasurementConstants.java @@ -0,0 +1,155 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; +import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; +import java.util.Arrays; +import java.util.List; + +/** + * Constants for collecting rpc stats. + */ +public final class RpcMeasurementConstants { + + // Rpc tag keys. + public static final TagKey RPC_STATUS = TagKey.create("OpStatus"); + public static final TagKey RPC_CLIENT_METHOD = TagKey.create("method"); + public static final TagKey RPC_SERVER_METHOD = TagKey.create("method"); + + // Constants used to define the following MeasurementDescriptors. + private static final List bytes = Arrays.asList(BasicUnit.BYTES); + private static final List scalar = Arrays.asList(BasicUnit.SCALAR); + private static final List seconds = Arrays.asList(BasicUnit.SECONDS); + + // RPC client {@link MeasurementDescriptor}s. + public static final MeasurementDescriptor RPC_CLIENT_ERROR_COUNT = + MeasurementDescriptor.create( + "grpc.io/client/error_count", + "RPC Errors", + MeasurementUnit.create(0, scalar)); + public static final MeasurementDescriptor RPC_CLIENT_REQUEST_BYTES = + MeasurementDescriptor.create( + "grpc.io/client/request_bytes", + "Request bytes", + MeasurementUnit.create(0, bytes)); + public static final MeasurementDescriptor RPC_CLIENT_RESPONSE_BYTES = + MeasurementDescriptor.create( + "grpc.io/client/response_bytes", + "Response bytes", + MeasurementUnit.create(0, bytes)); + public static final MeasurementDescriptor RPC_CLIENT_ROUNDTRIP_LATENCY = + MeasurementDescriptor.create( + "grpc.io/client/roundtrip_latency", + "RPC roundtrip latency msec", + MeasurementUnit.create(-3, seconds)); + public static final MeasurementDescriptor RPC_CLIENT_SERVER_ELAPSED_TIME = + MeasurementDescriptor.create( + "grpc.io/client/server_elapsed_time", + "Server elapsed time in msecs", + MeasurementUnit.create(-3, seconds)); + public static final MeasurementDescriptor RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES = + MeasurementDescriptor.create( + "grpc.io/client/uncompressed_request_bytes", + "Uncompressed Request bytes", + MeasurementUnit.create(0, bytes)); + public static final MeasurementDescriptor RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES = + MeasurementDescriptor.create( + "grpc.io/client/uncompressed_response_bytes", + "Uncompressed Response bytes", + MeasurementUnit.create(0, bytes)); + public static final MeasurementDescriptor RPC_CLIENT_STARTED_COUNT = + MeasurementDescriptor.create( + "grpc.io/client/started_count", + "Number of client RPCs (streams) started", + MeasurementUnit.create(0, scalar)); + public static final MeasurementDescriptor RPC_CLIENT_FINISHED_COUNT = + MeasurementDescriptor.create( + "grpc.io/client/finished_count", + "Number of client RPCs (streams) finished", + MeasurementUnit.create(0, scalar)); + public static final MeasurementDescriptor RPC_CLIENT_REQUEST_COUNT = + MeasurementDescriptor.create( + "grpc.io/client/request_count", + "Number of client RPC request messages", + MeasurementUnit.create(0, scalar)); + public static final MeasurementDescriptor RPC_CLIENT_RESPONSE_COUNT = + MeasurementDescriptor.create( + "grpc.io/client/response_count", + "Number of client RPC response messages", + MeasurementUnit.create(0, scalar)); + + + // RPC server {@link MeasurementDescriptor}s. + public static final MeasurementDescriptor RPC_SERVER_ERROR_COUNT = + MeasurementDescriptor.create( + "grpc.io/server/error_count", + "RPC Errors", + MeasurementUnit.create(0, scalar)); + public static final MeasurementDescriptor RPC_SERVER_REQUEST_BYTES = + MeasurementDescriptor.create( + "grpc.io/server/request_bytes", + "Request bytes", + MeasurementUnit.create(0, bytes)); + public static final MeasurementDescriptor RPC_SERVER_RESPONSE_BYTES = + MeasurementDescriptor.create( + "grpc.io/server/response_bytes", + "Response bytes", + MeasurementUnit.create(0, bytes)); + public static final MeasurementDescriptor RPC_SERVER_SERVER_ELAPSED_TIME = + MeasurementDescriptor.create( + "grpc.io/server/server_elapsed_time", + "Server elapsed time in msecs", + MeasurementUnit.create(-3, seconds)); + public static final MeasurementDescriptor RPC_SERVER_SERVER_LATENCY = + MeasurementDescriptor.create( + "grpc.io/server/server_latency", + "Latency in msecs", + MeasurementUnit.create(-3, seconds)); + public static final MeasurementDescriptor RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES = + MeasurementDescriptor.create( + "grpc.io/server/uncompressed_request_bytes", + "Uncompressed Request bytes", + MeasurementUnit.create(0, bytes)); + public static final MeasurementDescriptor RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES = + MeasurementDescriptor.create( + "grpc.io/server/uncompressed_response_bytes", + "Uncompressed Response bytes", + MeasurementUnit.create(0, bytes)); + public static final MeasurementDescriptor RPC_SERVER_STARTED_COUNT = + MeasurementDescriptor.create( + "grpc.io/server/started_count", + "Number of server RPCs (streams) started", + MeasurementUnit.create(0, scalar)); + public static final MeasurementDescriptor RPC_SERVER_FINISHED_COUNT = + MeasurementDescriptor.create( + "grpc.io/server/finished_count", + "Number of server RPCs (streams) finished", + MeasurementUnit.create(0, scalar)); + public static final MeasurementDescriptor RPC_SERVER_REQUEST_COUNT = + MeasurementDescriptor.create( + "grpc.io/server/request_count", + "Number of server RPC request messages", + MeasurementUnit.create(0, scalar)); + public static final MeasurementDescriptor RPC_SERVER_RESPONSE_COUNT = + MeasurementDescriptor.create( + "grpc.io/server/response_count", + "Number of server RPC response messages", + MeasurementUnit.create(0, scalar)); + + // Visible for testing. + RpcMeasurementConstants() { + throw new AssertionError(); + } +} diff --git a/core/src/main/java/com/google/instrumentation/stats/RpcViewConstants.java b/core/src/main/java/com/google/instrumentation/stats/RpcViewConstants.java new file mode 100644 index 0000000000..72d6223683 --- /dev/null +++ b/core/src/main/java/com/google/instrumentation/stats/RpcViewConstants.java @@ -0,0 +1,382 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_ERROR_COUNT; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_FINISHED_COUNT; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_METHOD; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_REQUEST_BYTES; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_REQUEST_COUNT; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_RESPONSE_BYTES; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_RESPONSE_COUNT; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_SERVER_ELAPSED_TIME; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_STARTED_COUNT; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_ERROR_COUNT; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_FINISHED_COUNT; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_METHOD; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_REQUEST_BYTES; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_REQUEST_COUNT; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_RESPONSE_BYTES; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_RESPONSE_COUNT; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_SERVER_ELAPSED_TIME; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_SERVER_LATENCY; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_STARTED_COUNT; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES; +import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_STATUS; + +import com.google.instrumentation.common.Duration; +import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; +import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Constants for exporting views on rpc stats. + */ +public final class RpcViewConstants { + + // Common histogram bucket boundaries for bytes received/sets DistributionViewDescriptors. + static final List RPC_BYTES_BUCKET_BOUNDARIES = Collections.unmodifiableList( + Arrays.asList(0.0, 1024.0, 2048.0, 4096.0, 16384.0, 65536.0, 262144.0, 1048576.0, 4194304.0, + 16777216.0, 67108864.0, 268435456.0, 1073741824.0, 4294967296.0)); + + // Common histogram bucket boundaries for latency and elapsed-time DistributionViewDescriptors. + static final List RPC_MILLIS_BUCKET_BOUNDARIES = Collections.unmodifiableList( + Arrays.asList(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 13.0, 16.0, 20.0, 25.0, 30.0, + 40.0, 50.0, 65.0, 80.0, 100.0, 130.0, 160.0, 200.0, 250.0, 300.0, 400.0, 500.0, 650.0, + 800.0, 1000.0, 2000.0, 5000.0, 10000.0, 20000.0, 50000.0, 100000.0)); + + // Rpc client {@link ViewDescriptor}s. + public static final DistributionViewDescriptor RPC_CLIENT_ERROR_COUNT_VIEW = + DistributionViewDescriptor.create( + "grpc.io/client/error_count/distribution_cumulative", + "RPC Errors", + RPC_CLIENT_ERROR_COUNT, + DistributionAggregationDescriptor.create(), + Arrays.asList(RPC_STATUS, RPC_CLIENT_METHOD)); + public static final DistributionViewDescriptor RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW = + DistributionViewDescriptor.create( + "grpc.io/client/roundtrip_latency/distribution_cumulative", + "Latency in msecs", + RPC_CLIENT_ROUNDTRIP_LATENCY, + DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), + Arrays.asList(RPC_CLIENT_METHOD)); + public static final DistributionViewDescriptor RPC_CLIENT_SERVER_ELAPSED_TIME_VIEW = + DistributionViewDescriptor.create( + "grpc.io/client/server_elapsed_time/distribution_cumulative", + "Server elapsed time in msecs", + RPC_CLIENT_SERVER_ELAPSED_TIME, + DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), + Arrays.asList(RPC_CLIENT_METHOD)); + public static final DistributionViewDescriptor RPC_CLIENT_REQUEST_BYTES_VIEW = + DistributionViewDescriptor.create( + "grpc.io/client/request_bytes/distribution_cumulative", + "Request bytes", + RPC_CLIENT_REQUEST_BYTES, + DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + Arrays.asList(RPC_CLIENT_METHOD)); + public static final DistributionViewDescriptor RPC_CLIENT_RESPONSE_BYTES_VIEW = + DistributionViewDescriptor.create( + "grpc.io/client/response_bytes/distribution_cumulative", + "Response bytes", + RPC_CLIENT_RESPONSE_BYTES, + DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + Arrays.asList(RPC_CLIENT_METHOD)); + public static final DistributionViewDescriptor RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_VIEW = + DistributionViewDescriptor.create( + "grpc.io/client/uncompressed_request_bytes/distribution_cumulative", + "Uncompressed Request bytes", + RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, + DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + Arrays.asList(RPC_CLIENT_METHOD)); + public static final DistributionViewDescriptor RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_VIEW = + DistributionViewDescriptor.create( + "grpc.io/client/uncompressed_response_bytes/distribution_cumulative", + "Uncompressed Response bytes", + RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, + DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + Arrays.asList(RPC_CLIENT_METHOD)); + public static final DistributionViewDescriptor RPC_CLIENT_REQUEST_COUNT_VIEW = + DistributionViewDescriptor.create( + "grpc.io/client/request_count/distribution_cumulative", + "Count of request messages per client RPC", + RPC_CLIENT_REQUEST_COUNT, + DistributionAggregationDescriptor.create(), + Arrays.asList(RPC_CLIENT_METHOD)); + public static final DistributionViewDescriptor RPC_CLIENT_RESPONSE_COUNT_VIEW = + DistributionViewDescriptor.create( + "grpc.io/client/response_count/distribution_cumulative", + "Count of response messages per client RPC", + RPC_CLIENT_RESPONSE_COUNT, + DistributionAggregationDescriptor.create(), + Arrays.asList(RPC_CLIENT_METHOD)); + + + // Rpc server {@link ViewDescriptor}s. + public static final DistributionViewDescriptor RPC_SERVER_ERROR_COUNT_VIEW = + DistributionViewDescriptor.create( + "grpc.io/server/error_count/distribution_cumulative", + "RPC Errors", + RPC_SERVER_ERROR_COUNT, + DistributionAggregationDescriptor.create(), + Arrays.asList(RPC_STATUS, RPC_SERVER_METHOD)); + public static final DistributionViewDescriptor RPC_SERVER_SERVER_LATENCY_VIEW = + DistributionViewDescriptor.create( + "grpc.io/server/server_latency/distribution_cumulative", + "Latency in msecs", + RPC_SERVER_SERVER_LATENCY, + DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), + Arrays.asList(RPC_SERVER_METHOD)); + public static final DistributionViewDescriptor RPC_SERVER_SERVER_ELAPSED_TIME_VIEW = + DistributionViewDescriptor.create( + "grpc.io/server/elapsed_time/distribution_cumulative", + "Server elapsed time in msecs", + RPC_SERVER_SERVER_ELAPSED_TIME, + DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), + Arrays.asList(RPC_SERVER_METHOD)); + public static final DistributionViewDescriptor RPC_SERVER_REQUEST_BYTES_VIEW = + DistributionViewDescriptor.create( + "grpc.io/server/request_bytes/distribution_cumulative", + "Request bytes", + RPC_SERVER_REQUEST_BYTES, + DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + Arrays.asList(RPC_SERVER_METHOD)); + public static final DistributionViewDescriptor RPC_SERVER_RESPONSE_BYTES_VIEW = + DistributionViewDescriptor.create( + "grpc.io/server/response_bytes/distribution_cumulative", + "Response bytes", + RPC_SERVER_RESPONSE_BYTES, + DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + Arrays.asList(RPC_SERVER_METHOD)); + public static final DistributionViewDescriptor RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_VIEW = + DistributionViewDescriptor.create( + "grpc.io/server/uncompressed_request_bytes/distribution_cumulative", + "Uncompressed Request bytes", + RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, + DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + Arrays.asList(RPC_SERVER_METHOD)); + public static final DistributionViewDescriptor RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_VIEW = + DistributionViewDescriptor.create( + "grpc.io/server/uncompressed_response_bytes/distribution_cumulative", + "Uncompressed Response bytes", + RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, + DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + Arrays.asList(RPC_SERVER_METHOD)); + public static final DistributionViewDescriptor RPC_SERVER_REQUEST_COUNT_VIEW = + DistributionViewDescriptor.create( + "grpc.io/server/request_count/distribution_cumulative", + "Count of request messages per server RPC", + RPC_SERVER_REQUEST_COUNT, + DistributionAggregationDescriptor.create(), + Arrays.asList(RPC_SERVER_METHOD)); + public static final DistributionViewDescriptor RPC_SERVER_RESPONSE_COUNT_VIEW = + DistributionViewDescriptor.create( + "grpc.io/server/response_count/distribution_cumulative", + "Count of response messages per server RPC", + RPC_SERVER_RESPONSE_COUNT, + DistributionAggregationDescriptor.create(), + Arrays.asList(RPC_SERVER_METHOD)); + + // Interval Stats + static final Duration MINUTE = Duration.create(60, 0); + static final Duration HOUR = Duration.create(60 * 60, 0); + + // RPC client {@link IntervalViewDescriptor}s. + public static final IntervalViewDescriptor RPC_CLIENT_ROUNDTRIP_LATENCY_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/client/roundtrip_latency/interval", + "Minute and Hour stats for latency in msecs", + RPC_CLIENT_ROUNDTRIP_LATENCY, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_CLIENT_METHOD)); + + public static final IntervalViewDescriptor RPC_CLIENT_REQUEST_BYTES_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/client/request_bytes/interval", + "Minute and Hour stats for request size in bytes", + RPC_CLIENT_REQUEST_BYTES, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_CLIENT_METHOD)); + + public static final IntervalViewDescriptor RPC_CLIENT_RESPONSE_BYTES_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/client/response_bytes/interval", + "Minute and Hour stats for response size in bytes", + RPC_CLIENT_RESPONSE_BYTES, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_CLIENT_METHOD)); + + public static final IntervalViewDescriptor RPC_CLIENT_ERROR_COUNT_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/client/error_count/interval", + "Minute and Hour stats for rpc errors", + RPC_CLIENT_ERROR_COUNT, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_CLIENT_METHOD)); + + public static final IntervalViewDescriptor RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/client/uncompressed_request_bytes/interval", + "Minute and Hour stats for uncompressed request size in bytes", + RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_CLIENT_METHOD)); + + public static final IntervalViewDescriptor RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/client/uncompressed_response_bytes/interval", + "Minute and Hour stats for uncompressed response size in bytes", + RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_CLIENT_METHOD)); + + public static final IntervalViewDescriptor RPC_CLIENT_SERVER_ELAPSED_TIME_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/client/server_elapsed_time/interval", + "Minute and Hour stats for server elapsed time in msecs", + RPC_CLIENT_SERVER_ELAPSED_TIME, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_CLIENT_METHOD)); + + public static final IntervalViewDescriptor RPC_CLIENT_STARTED_COUNT_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/client/started_count/interval", + "Minute and Hour stats on the number of client RPCs started", + RPC_CLIENT_STARTED_COUNT, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_CLIENT_METHOD)); + + public static final IntervalViewDescriptor RPC_CLIENT_FINISHED_COUNT_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/client/finished_count/interval", + "Minute and Hour stats on the number of client RPCs finished", + RPC_CLIENT_FINISHED_COUNT, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_CLIENT_METHOD)); + + public static final IntervalViewDescriptor RPC_CLIENT_REQUEST_COUNT_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/client/request_count/interval", + "Minute and Hour stats on the count of request messages per client RPC", + RPC_CLIENT_REQUEST_COUNT, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_CLIENT_METHOD)); + + public static final IntervalViewDescriptor RPC_CLIENT_RESPONSE_COUNT_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/client/response_count/interval", + "Minute and Hour stats on the count of response messages per client RPC", + RPC_CLIENT_RESPONSE_COUNT, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_CLIENT_METHOD)); + + // RPC server {@link IntervalViewDescriptor}s. + public static final IntervalViewDescriptor RPC_SERVER_SERVER_LATENCY_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/server/server_latency/interval", + "Minute and Hour stats for server latency in msecs", + RPC_SERVER_SERVER_LATENCY, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_SERVER_METHOD)); + + public static final IntervalViewDescriptor RPC_SERVER_REQUEST_BYTES_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/server/request_bytes/interval", + "Minute and Hour stats for request size in bytes", + RPC_SERVER_REQUEST_BYTES, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_SERVER_METHOD)); + + public static final IntervalViewDescriptor RPC_SERVER_RESPONSE_BYTES_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/server/response_bytes/interval", + "Minute and Hour stats for response size in bytes", + RPC_SERVER_RESPONSE_BYTES, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_SERVER_METHOD)); + + public static final IntervalViewDescriptor RPC_SERVER_ERROR_COUNT_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/server/error_count/interval", + "Minute and Hour stats for rpc errors", + RPC_SERVER_ERROR_COUNT, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_SERVER_METHOD)); + + public static final IntervalViewDescriptor RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/server/uncompressed_request_bytes/interval", + "Minute and Hour stats for uncompressed request size in bytes", + RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_SERVER_METHOD)); + + public static final IntervalViewDescriptor RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/server/uncompressed_response_bytes/interval", + "Minute and Hour stats for uncompressed response size in bytes", + RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_SERVER_METHOD)); + + public static final IntervalViewDescriptor RPC_SERVER_SERVER_ELAPSED_TIME_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/server/server_elapsed_time/interval", + "Minute and Hour stats for server elapsed time in msecs", + RPC_SERVER_SERVER_ELAPSED_TIME, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_SERVER_METHOD)); + + public static final IntervalViewDescriptor RPC_SERVER_STARTED_COUNT_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/server/started_count/interval", + "Minute and Hour stats on the number of server RPCs started", + RPC_SERVER_STARTED_COUNT, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_SERVER_METHOD)); + + public static final IntervalViewDescriptor RPC_SERVER_FINISHED_COUNT_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/server/finished_count/interval", + "Minute and Hour stats on the number of server RPCs finished", + RPC_SERVER_FINISHED_COUNT, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_SERVER_METHOD)); + + public static final IntervalViewDescriptor RPC_SERVER_REQUEST_COUNT_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/server/request_count/interval", + "Minute and Hour stats on the count of request messages per server RPC", + RPC_SERVER_REQUEST_COUNT, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_SERVER_METHOD)); + + public static final IntervalViewDescriptor RPC_SERVER_RESPONSE_COUNT_INTERVAL_VIEW = + IntervalViewDescriptor.create( + "grpc.io/server/response_count/interval", + "Minute and Hour stats on the count of response messages per server RPC", + RPC_SERVER_RESPONSE_COUNT, + IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + Arrays.asList(RPC_SERVER_METHOD)); + + // Visible for testing. + RpcViewConstants() { + throw new AssertionError(); + } +} diff --git a/core/src/test/java/com/google/instrumentation/stats/RpcConstantsTest.java b/core/src/test/java/com/google/instrumentation/stats/RpcConstantsTest.java index a5c448abdf..1ac1626543 100644 --- a/core/src/test/java/com/google/instrumentation/stats/RpcConstantsTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/RpcConstantsTest.java @@ -22,6 +22,7 @@ /** * Tests for {@link RpcConstants} */ +@Deprecated @RunWith(JUnit4.class) public final class RpcConstantsTest { @Test diff --git a/core/src/test/java/com/google/instrumentation/stats/RpcMeasurementConstantsTest.java b/core/src/test/java/com/google/instrumentation/stats/RpcMeasurementConstantsTest.java new file mode 100644 index 0000000000..3999be531a --- /dev/null +++ b/core/src/test/java/com/google/instrumentation/stats/RpcMeasurementConstantsTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test for {@link RpcMeasurementConstants}. + */ +@RunWith(JUnit4.class) +public class RpcMeasurementConstantsTest { + + @Test + public void testConstants() { + assertThat(RpcMeasurementConstants.RPC_STATUS).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_CLIENT_METHOD).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_SERVER_METHOD).isNotNull(); + + // Test client measurement descriptors. + assertThat(RpcMeasurementConstants.RPC_CLIENT_ERROR_COUNT).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_CLIENT_REQUEST_BYTES).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_CLIENT_RESPONSE_BYTES).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_CLIENT_REQUEST_COUNT).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_CLIENT_RESPONSE_COUNT).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_CLIENT_STARTED_COUNT).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_CLIENT_FINISHED_COUNT).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_CLIENT_SERVER_ELAPSED_TIME).isNotNull(); + + // Test server measurement descriptors. + assertThat(RpcMeasurementConstants.RPC_SERVER_ERROR_COUNT).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_SERVER_REQUEST_BYTES).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_SERVER_RESPONSE_BYTES).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_SERVER_SERVER_LATENCY).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_SERVER_REQUEST_COUNT).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_SERVER_RESPONSE_COUNT).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_SERVER_STARTED_COUNT).isNotNull(); + assertThat(RpcMeasurementConstants.RPC_SERVER_FINISHED_COUNT).isNotNull(); + } + + @Test(expected = AssertionError.class) + public void testConstructor() { + new RpcMeasurementConstants(); + } +} diff --git a/core/src/test/java/com/google/instrumentation/stats/RpcViewConstantsTest.java b/core/src/test/java/com/google/instrumentation/stats/RpcViewConstantsTest.java new file mode 100644 index 0000000000..01c4951f78 --- /dev/null +++ b/core/src/test/java/com/google/instrumentation/stats/RpcViewConstantsTest.java @@ -0,0 +1,78 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; + +/** + * Test for {@link RpcViewConstants}. + */ +public final class RpcViewConstantsTest { + + @Test + public void testConstants() { + // Test client distribution view descriptors. + assertThat(RpcViewConstants.RPC_CLIENT_ERROR_COUNT_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_REQUEST_BYTES_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_RESPONSE_BYTES_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_REQUEST_COUNT_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_RESPONSE_COUNT_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_SERVER_ELAPSED_TIME_VIEW).isNotNull(); + + // Test server distribution view descriptors. + assertThat(RpcViewConstants.RPC_SERVER_ERROR_COUNT_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_SERVER_LATENCY_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_REQUEST_BYTES_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_RESPONSE_BYTES_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_REQUEST_COUNT_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_RESPONSE_COUNT_VIEW).isNotNull(); + + // Test client interval view descriptors. + assertThat(RpcViewConstants.RPC_CLIENT_ERROR_COUNT_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_STARTED_COUNT_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_FINISHED_COUNT_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_SERVER_ELAPSED_TIME_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_REQUEST_COUNT_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_RESPONSE_COUNT_INTERVAL_VIEW).isNotNull(); + + // Test server interval view descriptors. + assertThat(RpcViewConstants.RPC_SERVER_ERROR_COUNT_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_SERVER_LATENCY_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_STARTED_COUNT_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_FINISHED_COUNT_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_REQUEST_COUNT_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_RESPONSE_COUNT_INTERVAL_VIEW).isNotNull(); + } + + @Test(expected = AssertionError.class) + public void testConstructor() { + new RpcViewConstants(); + } +} diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/SupportedViews.java b/core_impl/src/main/java/com/google/instrumentation/stats/SupportedViews.java index 3029514d37..e5e7bae30c 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/SupportedViews.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/SupportedViews.java @@ -17,9 +17,9 @@ * Constants specifying the view that is supported in the initial stats implementation. */ class SupportedViews { - static final ViewDescriptor SUPPORTED_VIEW = RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW; + static final ViewDescriptor SUPPORTED_VIEW = RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW; static final MeasurementDescriptor SUPPORTED_MEASUREMENT_DESCRIPTOR = - RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY; + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY; private SupportedViews() {} } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java index 060561938d..3d98a0d132 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java @@ -32,12 +32,13 @@ public class MeasurementDescriptorToViewMapTest { @Test public void testPutAndGetView() { MutableView expected = MutableDistributionView.create( - RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, + RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, Timestamp.fromMillis(System.currentTimeMillis())); measurementDescriptorToViewMap.putView( - RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY.getMeasurementDescriptorName(), expected); + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY.getMeasurementDescriptorName(), + expected); View actual = measurementDescriptorToViewMap.getView( - RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); assertThat(actual.getViewDescriptor()).isEqualTo(expected.getViewDescriptor()); } } \ No newline at end of file diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java index d8d440ee41..e7412c21fd 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java @@ -38,9 +38,12 @@ public class StatsContextTest { private static final StatsContext DEFAULT = Stats.getStatsContextFactory().getDefault(); private static final MeasurementDescriptor[] StatsMeasurementDescriptors = { - RpcConstants.RPC_CLIENT_REQUEST_BYTES, RpcConstants.RPC_CLIENT_RESPONSE_BYTES, - RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, RpcConstants.RPC_SERVER_REQUEST_BYTES, - RpcConstants.RPC_SERVER_RESPONSE_BYTES, RpcConstants.RPC_SERVER_SERVER_LATENCY + RpcMeasurementConstants.RPC_CLIENT_REQUEST_BYTES, + RpcMeasurementConstants.RPC_CLIENT_RESPONSE_BYTES, + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, + RpcMeasurementConstants.RPC_SERVER_REQUEST_BYTES, + RpcMeasurementConstants.RPC_SERVER_RESPONSE_BYTES, + RpcMeasurementConstants.RPC_SERVER_SERVER_LATENCY }; private static final int VERSION_ID = 0; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 3803792ec2..6cb45e29be 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -38,7 +38,7 @@ public class StatsManagerImplTest { public final ExpectedException thrown = ExpectedException.none(); private static final double TOLERANCE = 1e-5; - private static final TagKey tagKey = RpcConstants.RPC_CLIENT_METHOD; + private static final TagKey tagKey = RpcMeasurementConstants.RPC_CLIENT_METHOD; private static final TagKey wrongTagKey = TagKey.create("Wrong Tag Key"); private static final TagKey wrongTagKey2 = TagKey.create("Another wrong Tag Key"); private static final TagValue tagValue1 = TagValue.create("some client method"); @@ -57,51 +57,51 @@ public class StatsManagerImplTest { @Test public void testRegisterAndGetView() throws Exception { - statsManager.registerView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - View actual = statsManager.getView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + View actual = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); assertThat(actual.getViewDescriptor()).isEqualTo( - RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); } @Test public void testRegisterUnsupportedViewDescriptor() throws Exception { thrown.expect(UnsupportedOperationException.class); - statsManager.registerView(RpcConstants.RPC_CLIENT_REQUEST_COUNT_VIEW); + statsManager.registerView(RpcViewConstants.RPC_CLIENT_REQUEST_COUNT_VIEW); } @Test public void testRegisterViewDescriptorTwice() { - statsManager.registerView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - statsManager.registerView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - View actual = statsManager.getView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + View actual = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); assertThat(actual.getViewDescriptor()).isEqualTo( - RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); } @Test public void testGetNonexistentView() throws Exception { thrown.expect(IllegalArgumentException.class); - statsManager.getView(RpcConstants.RPC_CLIENT_REQUEST_COUNT_VIEW); + statsManager.getView(RpcViewConstants.RPC_CLIENT_REQUEST_COUNT_VIEW); } @Test public void testRecord() { - statsManager.registerView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); for (double val : Arrays.asList(10.0, 20.0, 30.0, 40.0)) { statsManager.record( - oneTag, MeasurementMap.of(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, val)); + oneTag, MeasurementMap.of(RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, val)); } DistributionView view = - (DistributionView) statsManager.getView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - assertThat(view.getViewDescriptor()).isEqualTo(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + assertThat(view.getViewDescriptor()).isEqualTo(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); // TODO(songya): update to make assertions on the exact time based on fake clock. assertThat(view.getEnd().getSeconds()).isAtLeast(view.getStart().getSeconds()); List distributionAggregations = view.getDistributionAggregations(); assertThat(distributionAggregations).hasSize(1); DistributionAggregation distributionAggregation = distributionAggregations.get(0); verifyDistributionAggregation(distributionAggregation, 4, 100.0, 25.0, 10.0, 40.0, 1); - // Refer to RpcConstants.RPC_MILLIS_BUCKET_BOUNDARIES for bucket boundaries. + // Refer to RpcViewConstants.RPC_MILLIS_BUCKET_BOUNDARIES for bucket boundaries. verifyBucketCounts(distributionAggregation.getBucketCounts(), 9, 12, 14, 15); List tags = distributionAggregation.getTags(); @@ -111,15 +111,16 @@ public void testRecord() { @Test public void testRecordMultipleTagValues() { - statsManager.registerView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - statsManager.record(oneTag, MeasurementMap.of(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10.0)); - statsManager.record( - anotherTag, MeasurementMap.of(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 30.0)); - statsManager.record( - anotherTag, MeasurementMap.of(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 50.0)); + statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + statsManager.record(oneTag, MeasurementMap.of( + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10.0)); + statsManager.record(anotherTag, MeasurementMap.of( + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 30.0)); + statsManager.record(anotherTag, MeasurementMap.of( + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 50.0)); DistributionView view = - (DistributionView) statsManager.getView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); List distributionAggregations = view.getDistributionAggregations(); assertThat(distributionAggregations).hasSize(2); // Sort distributionAggregations by count. @@ -171,17 +172,18 @@ private static final void verifyBucketCounts(List bucketCounts, int... non @Test public void testRecordWithoutRegisteringView() { thrown.expect(IllegalArgumentException.class); - statsManager.record(oneTag, MeasurementMap.of(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10)); + statsManager.record(oneTag, MeasurementMap.of( + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10)); } @Test public void testRecordWithEmptyStatsContext() { - statsManager.registerView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - // DEFAULT doesn't have tags. Should have TagKey "method" as defined in RpcConstants. - statsManager.record(StatsContextFactoryImpl.DEFAULT, - MeasurementMap.of(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10.0)); + statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + // DEFAULT doesn't have tags. Should have TagKey "method" as defined in RpcViewConstants. + statsManager.record(StatsContextFactoryImpl.DEFAULT, MeasurementMap.of( + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10.0)); DistributionView view = - (DistributionView) statsManager.getView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); assertThat(view.getDistributionAggregations()).hasSize(1); DistributionAggregation distributionAggregation = view.getDistributionAggregations().get(0); List tags = distributionAggregation.getTags(); @@ -195,23 +197,24 @@ public void testRecordWithEmptyStatsContext() { @Test public void testRecordNonExistentMeasurementDescriptor() { - statsManager.registerView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - statsManager.record(oneTag, MeasurementMap.of(RpcConstants.RPC_SERVER_ERROR_COUNT, 10.0)); + statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + statsManager.record(oneTag, MeasurementMap.of( + RpcMeasurementConstants.RPC_SERVER_ERROR_COUNT, 10.0)); DistributionView view = - (DistributionView) statsManager.getView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); assertThat(view.getDistributionAggregations()).hasSize(0); } @Test public void testRecordTagDoesNotMatchView() { - statsManager.registerView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); statsManager.record(wrongTag, MeasurementMap.of( - RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10.0)); + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10.0)); statsManager.record(wrongTag2, MeasurementMap.of( - RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 50.0)); + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 50.0)); DistributionView view = - (DistributionView) statsManager.getView(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); assertThat(view.getDistributionAggregations()).hasSize(1); DistributionAggregation distributionAggregation = view.getDistributionAggregations().get(0); diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsTest.java index 2bbf5cefcb..58da35c874 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsTest.java @@ -20,7 +20,7 @@ import org.junit.runners.JUnit4; /** - * Tests for {@link RpcConstants} + * Tests for {@link Stats} */ @RunWith(JUnit4.class) public final class StatsTest { From 9ea92f13b50d854b4a645a84564bab8064914ea6 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 27 Apr 2017 13:12:45 -0700 Subject: [PATCH 0007/1581] Split core_impl into directories for Android, Java 7, and Java 8. This directory structure will allow us to support the three Java versions but also take advantage of the features available in each one. Each directory has a readme. I refactored the stats code so that there is one StatsManagerImpl for each of Android, Java 7, and Java 8. StatsManagerImpl is loaded with reflection, and it specifies the stats classes that should be used for the implementation. I also moved DisruptorEventQueue to core_impl_java, since it isn't Android-compatible. This commit doesn't affect tracing. --- core/README.md | 6 ++++ core/build.gradle | 1 - .../instrumentation/stats/StatsTest.java | 29 +++++++++++++++++ core_impl/README.md | 5 +++ core_impl/build.gradle | 1 - .../instrumentation/common/EventQueue.java | 4 +-- ...gerImpl.java => StatsManagerImplBase.java} | 13 +++----- .../stats/StatsContextFactoryTest.java | 6 ++-- .../stats/StatsContextTest.java | 5 +-- .../stats/StatsManagerImplTest.java | 5 +-- core_impl_android/README.md | 6 ++++ core_impl_android/build.gradle | 8 +++++ .../stats/StatsManagerImpl.java | 27 ++++++++++++++++ .../instrumentation/stats/StatsTest.java | 7 +---- core_impl_java/README.md | 5 +++ core_impl_java/build.gradle | 9 ++++++ .../common/DisruptorEventQueue.java | 0 .../stats/StatsManagerImplJava.java | 26 ++++++++++++++++ .../common/DisruptorEventQueueTest.java | 0 core_impl_java_7/README.md | 6 ++++ core_impl_java_7/build.gradle | 9 ++++++ .../stats/StatsManagerImpl.java | 23 ++++++++++++++ .../instrumentation/stats/StatsTest.java | 31 +++++++++++++++++++ core_impl_java_8/README.md | 5 +++ core_impl_java_8/build.gradle | 7 +++++ .../stats/StatsManagerImpl.java | 23 ++++++++++++++ .../instrumentation/stats/StatsTest.java | 31 +++++++++++++++++++ settings.gradle | 10 +++++- 28 files changed, 282 insertions(+), 26 deletions(-) create mode 100644 core/README.md create mode 100644 core/src/test/java/com/google/instrumentation/stats/StatsTest.java create mode 100644 core_impl/README.md rename core_impl/src/main/java/com/google/instrumentation/stats/{StatsManagerImpl.java => StatsManagerImplBase.java} (92%) create mode 100644 core_impl_android/README.md create mode 100644 core_impl_android/build.gradle create mode 100644 core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java rename {core_impl => core_impl_android}/src/test/java/com/google/instrumentation/stats/StatsTest.java (88%) create mode 100644 core_impl_java/README.md create mode 100644 core_impl_java/build.gradle rename {core_impl => core_impl_java}/src/main/java/com/google/instrumentation/common/DisruptorEventQueue.java (100%) create mode 100644 core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImplJava.java rename {core_impl => core_impl_java}/src/test/java/com/google/instrumentation/common/DisruptorEventQueueTest.java (100%) create mode 100644 core_impl_java_7/README.md create mode 100644 core_impl_java_7/build.gradle create mode 100644 core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java create mode 100644 core_impl_java_7/src/test/java/com/google/instrumentation/stats/StatsTest.java create mode 100644 core_impl_java_8/README.md create mode 100644 core_impl_java_8/build.gradle create mode 100644 core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java create mode 100644 core_impl_java_8/src/test/java/com/google/instrumentation/stats/StatsTest.java diff --git a/core/README.md b/core/README.md new file mode 100644 index 0000000000..b4dfea1886 --- /dev/null +++ b/core/README.md @@ -0,0 +1,6 @@ +Instrumentation API +====================================================== + +* Java 6 and Android compatible. +* The abstract classes in this directory can be subclassed to create alternative + implementations of the Instrumentation library. diff --git a/core/build.gradle b/core/build.gradle index bfff603de8..c7516a6771 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -4,7 +4,6 @@ dependencies { compile libraries.grpc_context, libraries.guava compileOnly libraries.auto_value - testCompile libraries.grpc_context signature "org.codehaus.mojo.signature:java16:+@signature" } diff --git a/core/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core/src/test/java/com/google/instrumentation/stats/StatsTest.java new file mode 100644 index 0000000000..598aafa469 --- /dev/null +++ b/core/src/test/java/com/google/instrumentation/stats/StatsTest.java @@ -0,0 +1,29 @@ +/* + * Copyright 2016, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for {@link Stats}. + */ +@RunWith(JUnit4.class) +public final class StatsTest { + @Test(expected = AssertionError.class) + public void testConstructor() { + new Stats(); + } +} diff --git a/core_impl/README.md b/core_impl/README.md new file mode 100644 index 0000000000..baa071320b --- /dev/null +++ b/core_impl/README.md @@ -0,0 +1,5 @@ +Instrumentation implementation +====================================================== + +* The main implementation. +* Java 6 and Android compatible. diff --git a/core_impl/build.gradle b/core_impl/build.gradle index 9409a109c9..e7c7e72103 100644 --- a/core_impl/build.gradle +++ b/core_impl/build.gradle @@ -4,7 +4,6 @@ dependencies { compile project(':instrumentation-java-core'), project(':shared'), libraries.auto_value, - libraries.disruptor, libraries.guava testCompile project(':instrumentation-java-core') diff --git a/core_impl/src/main/java/com/google/instrumentation/common/EventQueue.java b/core_impl/src/main/java/com/google/instrumentation/common/EventQueue.java index 178251e9fe..e0585f1d43 100644 --- a/core_impl/src/main/java/com/google/instrumentation/common/EventQueue.java +++ b/core_impl/src/main/java/com/google/instrumentation/common/EventQueue.java @@ -14,14 +14,14 @@ package com.google.instrumentation.common; /** - * A queue that processes events. See {@link DisruptorEventQueue} for an example. + * A queue that processes events. See {@code DisruptorEventQueue} for an example. */ public interface EventQueue { void enqueue(Entry entry); /** * Base interface to be used for all entries in {@link EventQueue}. For example usage, - * see {@link DisruptorEventQueue}. + * see {@code DisruptorEventQueue}. */ public interface Entry { /** diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java similarity index 92% rename from core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java rename to core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java index 659c6717bb..747379f2fb 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java @@ -13,7 +13,6 @@ package com.google.instrumentation.stats; -import com.google.instrumentation.common.DisruptorEventQueue; import com.google.instrumentation.common.EventQueue; import com.google.instrumentation.common.Function; import com.google.instrumentation.common.Timestamp; @@ -25,14 +24,10 @@ /** * Native Implementation of {@link StatsManager}. */ -public final class StatsManagerImpl extends StatsManager { +public class StatsManagerImplBase extends StatsManager { private final EventQueue queue; - public StatsManagerImpl() { - queue = DisruptorEventQueue.getInstance(); - } - - StatsManagerImpl(EventQueue queue) { + StatsManagerImplBase(EventQueue queue) { this.queue = queue; } @@ -94,10 +89,10 @@ void record(StatsContextImpl tags, MeasurementMap measurementValues) { private static final class StatsEvent implements EventQueue.Entry { private final StatsContextImpl tags; private final MeasurementMap stats; - private final StatsManagerImpl statsManager; + private final StatsManagerImplBase statsManager; StatsEvent( - StatsManagerImpl statsManager, StatsContextImpl tags, MeasurementMap stats) { + StatsManagerImplBase statsManager, StatsContextImpl tags, MeasurementMap stats) { this.statsManager = statsManager; this.tags = tags; this.stats = stats; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java index 9229d35f04..ce1396f696 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java @@ -34,6 +34,8 @@ public class StatsContextFactoryTest { private static final String KEY = "Key"; private static final String VALUE_STRING = "String"; private static final int VALUE_INT = 10; + + private static final StatsContextFactory FACTORY = new StatsContextFactoryImpl(); private final HashMap sampleTags = new HashMap(); public StatsContextFactoryTest() { @@ -53,7 +55,7 @@ public void testVersionAndValueTypeConstants() { @Test public void testDeserializeNoTags() throws Exception { - StatsContext expected = Stats.getStatsContextFactory().getDefault(); + StatsContext expected = FACTORY.getDefault(); StatsContext actual = testDeserialize( new ByteArrayInputStream( new byte[]{StatsSerializer.VERSION_ID})); // One byte that represents Version ID. @@ -127,7 +129,7 @@ public void testDeserializeWrongVersionId() throws Exception { private static StatsContext testDeserialize(InputStream inputStream) throws IOException, IOException { - return Stats.getStatsContextFactory().deserialize(inputStream); + return FACTORY.deserialize(inputStream); } /* diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java index e7412c21fd..8e467ee050 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java @@ -35,7 +35,8 @@ */ @RunWith(JUnit4.class) public class StatsContextTest { - private static final StatsContext DEFAULT = Stats.getStatsContextFactory().getDefault(); + private static final StatsContextFactory FACTORY = new StatsContextFactoryImpl(); + private static final StatsContext DEFAULT = StatsContextFactoryImpl.DEFAULT; private static final MeasurementDescriptor[] StatsMeasurementDescriptors = { RpcMeasurementConstants.RPC_CLIENT_REQUEST_BYTES, @@ -202,7 +203,7 @@ private static void testRoundtripSerialization(StatsContext expected) throws Exc ByteArrayOutputStream output = new ByteArrayOutputStream(); expected.serialize(output); ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); - StatsContext actual = Stats.getStatsContextFactory().deserialize(input); + StatsContext actual = FACTORY.deserialize(input); assertThat(actual).isEqualTo(expected); } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 6cb45e29be..8a8039d61c 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -29,7 +29,7 @@ import org.junit.runners.JUnit4; /** - * Tests for {@link StatsManagerImpl}. + * Tests for {@link StatsManagerImplBase}. */ @RunWith(JUnit4.class) public class StatsManagerImplTest { @@ -53,7 +53,8 @@ public class StatsManagerImplTest { new StatsContextImpl(ImmutableMap.of(wrongTagKey, tagValue1, wrongTagKey2, tagValue2)); - private final StatsManagerImpl statsManager = new StatsManagerImpl(new SimpleEventQueue()); + private final StatsManagerImplBase statsManager = + new StatsManagerImplBase(new SimpleEventQueue()); @Test public void testRegisterAndGetView() throws Exception { diff --git a/core_impl_android/README.md b/core_impl_android/README.md new file mode 100644 index 0000000000..9fadb3aeae --- /dev/null +++ b/core_impl_android/README.md @@ -0,0 +1,6 @@ +Instrumentation Android implementation +====================================================== + +* Java 6 and Android compatible. +* StatsManager specifies the stats implementation classes that should be used + with Android. diff --git a/core_impl_android/build.gradle b/core_impl_android/build.gradle new file mode 100644 index 0000000000..5053d6e462 --- /dev/null +++ b/core_impl_android/build.gradle @@ -0,0 +1,8 @@ +description = 'Instrumentation Core Impl Android' + +dependencies { + compile project(':instrumentation-java-core'), + project(':instrumentation-java-core-impl') + + signature "org.codehaus.mojo.signature:java16:+@signature" +} diff --git a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java new file mode 100644 index 0000000000..6b4fbd66e5 --- /dev/null +++ b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -0,0 +1,27 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import com.google.instrumentation.common.SimpleEventQueue; + +/** + * Android-compatible implementation of {@link StatsManager}. + */ +public final class StatsManagerImpl extends StatsManagerImplBase { + + public StatsManagerImpl() { + // TODO(sebright): Use a more efficient queue implementation. + super(new SimpleEventQueue()); + } +} diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core_impl_android/src/test/java/com/google/instrumentation/stats/StatsTest.java similarity index 88% rename from core_impl/src/test/java/com/google/instrumentation/stats/StatsTest.java rename to core_impl_android/src/test/java/com/google/instrumentation/stats/StatsTest.java index 58da35c874..e5ed1d9ee4 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTest.java +++ b/core_impl_android/src/test/java/com/google/instrumentation/stats/StatsTest.java @@ -20,7 +20,7 @@ import org.junit.runners.JUnit4; /** - * Tests for {@link Stats} + * Test for accessing the {@link StatsManager} through the {@link Stats} class. */ @RunWith(JUnit4.class) public final class StatsTest { @@ -28,9 +28,4 @@ public final class StatsTest { public void getStatsContextFactory() { assertThat(Stats.getStatsContextFactory()).isNotNull(); } - - @Test(expected = AssertionError.class) - public void testConstructor() { - new Stats(); - } } diff --git a/core_impl_java/README.md b/core_impl_java/README.md new file mode 100644 index 0000000000..e578f26f27 --- /dev/null +++ b/core_impl_java/README.md @@ -0,0 +1,5 @@ +Instrumentation Java implementation +====================================================== + +* Java 7 compatible. +* Contains any classes not compatible with Android. diff --git a/core_impl_java/build.gradle b/core_impl_java/build.gradle new file mode 100644 index 0000000000..0eea0a779a --- /dev/null +++ b/core_impl_java/build.gradle @@ -0,0 +1,9 @@ +description = 'Instrumentation Core Impl Java' + +dependencies { + compile project(':instrumentation-java-core'), + project(':instrumentation-java-core-impl'), + libraries.disruptor + + signature "org.codehaus.mojo.signature:java17:+@signature" +} diff --git a/core_impl/src/main/java/com/google/instrumentation/common/DisruptorEventQueue.java b/core_impl_java/src/main/java/com/google/instrumentation/common/DisruptorEventQueue.java similarity index 100% rename from core_impl/src/main/java/com/google/instrumentation/common/DisruptorEventQueue.java rename to core_impl_java/src/main/java/com/google/instrumentation/common/DisruptorEventQueue.java diff --git a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImplJava.java b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImplJava.java new file mode 100644 index 0000000000..d588d12a69 --- /dev/null +++ b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImplJava.java @@ -0,0 +1,26 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import com.google.instrumentation.common.DisruptorEventQueue; + +/** + * Java 7 and 8 implementation of {@link StatsManager}. + */ +public abstract class StatsManagerImplJava extends StatsManagerImplBase { + + public StatsManagerImplJava() { + super(DisruptorEventQueue.getInstance()); + } +} diff --git a/core_impl/src/test/java/com/google/instrumentation/common/DisruptorEventQueueTest.java b/core_impl_java/src/test/java/com/google/instrumentation/common/DisruptorEventQueueTest.java similarity index 100% rename from core_impl/src/test/java/com/google/instrumentation/common/DisruptorEventQueueTest.java rename to core_impl_java/src/test/java/com/google/instrumentation/common/DisruptorEventQueueTest.java diff --git a/core_impl_java_7/README.md b/core_impl_java_7/README.md new file mode 100644 index 0000000000..20d04a7b90 --- /dev/null +++ b/core_impl_java_7/README.md @@ -0,0 +1,6 @@ +Instrumentation Java 7 implementation +====================================================== + +* Java 7 compatible. +* StatsManager specifies the stats implementation classes that should be used + with Java 7. diff --git a/core_impl_java_7/build.gradle b/core_impl_java_7/build.gradle new file mode 100644 index 0000000000..62a9bd543a --- /dev/null +++ b/core_impl_java_7/build.gradle @@ -0,0 +1,9 @@ +description = 'Instrumentation Core Impl Java 7' + +dependencies { + compile project(':instrumentation-java-core'), + project(':instrumentation-java-core-impl'), + project(':instrumentation-java-core-impl-java') + + signature "org.codehaus.mojo.signature:java17:+@signature" +} diff --git a/core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java new file mode 100644 index 0000000000..be178132a4 --- /dev/null +++ b/core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -0,0 +1,23 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +/** + * Java 7 implementation of {@link StatsManager}. + */ +public final class StatsManagerImpl extends StatsManagerImplJava { + + public StatsManagerImpl() { + } +} diff --git a/core_impl_java_7/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core_impl_java_7/src/test/java/com/google/instrumentation/stats/StatsTest.java new file mode 100644 index 0000000000..e5ed1d9ee4 --- /dev/null +++ b/core_impl_java_7/src/test/java/com/google/instrumentation/stats/StatsTest.java @@ -0,0 +1,31 @@ +/* + * Copyright 2016, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test for accessing the {@link StatsManager} through the {@link Stats} class. + */ +@RunWith(JUnit4.class) +public final class StatsTest { + @Test + public void getStatsContextFactory() { + assertThat(Stats.getStatsContextFactory()).isNotNull(); + } +} diff --git a/core_impl_java_8/README.md b/core_impl_java_8/README.md new file mode 100644 index 0000000000..35e61c4f67 --- /dev/null +++ b/core_impl_java_8/README.md @@ -0,0 +1,5 @@ +Instrumentation Java 8 implementation +====================================================== + +* StatsManager specifies the stats implementation classes that should be used + with Java 8. diff --git a/core_impl_java_8/build.gradle b/core_impl_java_8/build.gradle new file mode 100644 index 0000000000..043d7a7980 --- /dev/null +++ b/core_impl_java_8/build.gradle @@ -0,0 +1,7 @@ +description = 'Instrumentation Core Impl Java 8' + +dependencies { + compile project(':instrumentation-java-core'), + project(':instrumentation-java-core-impl'), + project(':instrumentation-java-core-impl-java') +} diff --git a/core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java new file mode 100644 index 0000000000..5f8e8d6524 --- /dev/null +++ b/core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -0,0 +1,23 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +/** + * Java 8 implementation of {@link StatsManager}. + */ +public final class StatsManagerImpl extends StatsManagerImplJava { + + public StatsManagerImpl() { + } +} diff --git a/core_impl_java_8/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core_impl_java_8/src/test/java/com/google/instrumentation/stats/StatsTest.java new file mode 100644 index 0000000000..e5ed1d9ee4 --- /dev/null +++ b/core_impl_java_8/src/test/java/com/google/instrumentation/stats/StatsTest.java @@ -0,0 +1,31 @@ +/* + * Copyright 2016, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test for accessing the {@link StatsManager} through the {@link Stats} class. + */ +@RunWith(JUnit4.class) +public final class StatsTest { + @Test + public void getStatsContextFactory() { + assertThat(Stats.getStatsContextFactory()).isNotNull(); + } +} diff --git a/settings.gradle b/settings.gradle index 180b4bfd6b..f5acf453fc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,12 +3,20 @@ include ":instrumentation-java-all" include ":instrumentation-java-benchmarks" include ":instrumentation-java-core" include ":instrumentation-java-core-impl" +include ":instrumentation-java-core-impl-java" +include ":instrumentation-java-core-impl-java-7" +include ":instrumentation-java-core-impl-java-8" +include ":instrumentation-java-core-impl-android" include ":shared" project(':instrumentation-java-all').projectDir = "$rootDir/all" as File project(':instrumentation-java-benchmarks').projectDir = "$rootDir/benchmarks" as File project(':instrumentation-java-core').projectDir = "$rootDir/core" as File project(':instrumentation-java-core-impl').projectDir = "$rootDir/core_impl" as File +project(':instrumentation-java-core-impl-java').projectDir = "$rootDir/core_impl_java" as File +project(':instrumentation-java-core-impl-java-7').projectDir = "$rootDir/core_impl_java_7" as File +project(':instrumentation-java-core-impl-java-8').projectDir = "$rootDir/core_impl_java_8" as File +project(':instrumentation-java-core-impl-android').projectDir = "$rootDir/core_impl_android" as File project(':shared').projectDir = "$rootDir/shared" as File // Java8 projects only @@ -16,4 +24,4 @@ if (JavaVersion.current().isJava8Compatible()) { include ":instrumentation-examples" project(':instrumentation-examples').projectDir = "$rootDir/examples" as File -} \ No newline at end of file +} From 948af51566c721b39f7378a79dcae049500066d2 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 27 Apr 2017 14:23:16 -0700 Subject: [PATCH 0008/1581] Update other build files for core_impl split. --- all/build.gradle | 4 ++++ benchmarks/build.gradle | 2 ++ examples/build.gradle | 2 ++ 3 files changed, 8 insertions(+) diff --git a/all/build.gradle b/all/build.gradle index 64668ed08a..42cb16cb6e 100644 --- a/all/build.gradle +++ b/all/build.gradle @@ -14,6 +14,10 @@ buildscript { def subprojects = [ project(':instrumentation-java-core'), project(':instrumentation-java-core-impl'), + project(':instrumentation-java-core-impl-android'), + project(':instrumentation-java-core-impl-java'), + project(':instrumentation-java-core-impl-java-7'), + project(':instrumentation-java-core-impl-java-8'), ] for (subproject in rootProject.subprojects) { diff --git a/benchmarks/build.gradle b/benchmarks/build.gradle index ac677ec467..73e52ecbef 100644 --- a/benchmarks/build.gradle +++ b/benchmarks/build.gradle @@ -25,6 +25,8 @@ jmh { dependencies { compile project(':instrumentation-java-core'), project(':instrumentation-java-core-impl') + project(':instrumentation-java-core-impl-java') + project(':instrumentation-java-core-impl-java-8') } compileJmhJava { diff --git a/examples/build.gradle b/examples/build.gradle index e413ef0d6d..c20bcb7ea5 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -8,6 +8,8 @@ tasks.withType(JavaCompile) { dependencies { compile project(':instrumentation-java-core'), project(':instrumentation-java-core-impl'), + project(':instrumentation-java-core-impl-java'), + project(':instrumentation-java-core-impl-java-8'), libraries.grpc_context } From cfb22894acdf0d9c8b763f5daa1c7e12800a8fdf Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 27 Apr 2017 16:48:26 -0700 Subject: [PATCH 0009/1581] Avoid generating Javadocs for duplicate classes. Including instrumentation-java-core-impl-java-7, instrumentation-java-core-impl-java-8, and instrumentation-java-core-impl-android in all/build.gradle caused the Gradle javadoc command to throw a NPE because there were multiple StatsManagerImpls. --- all/build.gradle | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/all/build.gradle b/all/build.gradle index 42cb16cb6e..143e4cb3e3 100644 --- a/all/build.gradle +++ b/all/build.gradle @@ -11,13 +11,15 @@ buildscript { } } +// TODO(sebright): Look into handling instrumentation-java-core-impl-java-7, +// instrumentation-java-core-impl-java-8, and +// instrumentation-java-core-impl-android. 'subprojects' currently doesn't +// include all directories, because Javadoc cannot handle multiple classes with +// the same name, such as StatsManagerImpl. def subprojects = [ project(':instrumentation-java-core'), project(':instrumentation-java-core-impl'), - project(':instrumentation-java-core-impl-android'), project(':instrumentation-java-core-impl-java'), - project(':instrumentation-java-core-impl-java-7'), - project(':instrumentation-java-core-impl-java-8'), ] for (subproject in rootProject.subprojects) { From 19c0ce7c81b83d2880451327e4c21bfce57556c9 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 27 Apr 2017 16:58:43 -0700 Subject: [PATCH 0010/1581] Update readmes after code review. --- core_impl/README.md | 2 +- core_impl_android/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core_impl/README.md b/core_impl/README.md index baa071320b..674b08f84d 100644 --- a/core_impl/README.md +++ b/core_impl/README.md @@ -1,5 +1,5 @@ Instrumentation implementation ====================================================== -* The main implementation. +* The main implementation shared between Java and Android. * Java 6 and Android compatible. diff --git a/core_impl_android/README.md b/core_impl_android/README.md index 9fadb3aeae..97a99ff97d 100644 --- a/core_impl_android/README.md +++ b/core_impl_android/README.md @@ -1,6 +1,6 @@ Instrumentation Android implementation ====================================================== -* Java 6 and Android compatible. +* Android compatible. * StatsManager specifies the stats implementation classes that should be used with Android. From 14d156e63483c8d1d3b736d9f04998210c6d741b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 27 Apr 2017 17:56:57 -0700 Subject: [PATCH 0011/1581] Specify that core_impl is Java 7 compatible in readme. --- core_impl/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core_impl/README.md b/core_impl/README.md index 674b08f84d..95e4027e26 100644 --- a/core_impl/README.md +++ b/core_impl/README.md @@ -2,4 +2,4 @@ Instrumentation implementation ====================================================== * The main implementation shared between Java and Android. -* Java 6 and Android compatible. +* Java 7 and Android compatible. From 001a09a19cbf316990cc6b344fa173469ce170fa Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 28 Apr 2017 09:06:01 -0700 Subject: [PATCH 0012/1581] Convert Annotation and Link to use AutoValue. (#264) --- .../instrumentation/trace/Annotation.java | 62 ++++--------------- .../google/instrumentation/trace/Link.java | 60 +++--------------- 2 files changed, 21 insertions(+), 101 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/trace/Annotation.java b/core/src/main/java/com/google/instrumentation/trace/Annotation.java index 2dc6f7cd40..cfd0e27f89 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Annotation.java +++ b/core/src/main/java/com/google/instrumentation/trace/Annotation.java @@ -15,8 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; +import com.google.auto.value.AutoValue; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -24,11 +23,10 @@ /** A text annotation with a set of attributes. */ @Immutable -public final class Annotation { - private static final Map EMPTY_ATTRIBUTES = Collections.emptyMap(); - - private final String description; - private final Map attributes; +@AutoValue +public abstract class Annotation { + private static final Map EMPTY_ATTRIBUTES = + Collections.unmodifiableMap(Collections.emptyMap()); /** * Returns a new {@code Annotation} with the given description. @@ -38,7 +36,7 @@ public final class Annotation { * @throws NullPointerException if {@code description} is {@code null}. */ public static Annotation fromDescription(String description) { - return new Annotation(description, EMPTY_ATTRIBUTES); + return new AutoValue_Annotation(description, EMPTY_ATTRIBUTES); } /** @@ -51,7 +49,10 @@ public static Annotation fromDescription(String description) { */ public static Annotation fromDescriptionAndAttributes( String description, Map attributes) { - return new Annotation(description, attributes); + return new AutoValue_Annotation( + description, + Collections.unmodifiableMap( + new HashMap(checkNotNull(attributes, "attributes")))); } /** @@ -59,51 +60,14 @@ public static Annotation fromDescriptionAndAttributes( * * @return the description of the {@code Annotation}. */ - public String getDescription() { - return description; - } + public abstract String getDescription(); /** * Return the attributes of the {@code Annotation}. * * @return the attributes of the {@code Annotation}. */ - public Map getAttributes() { - return attributes; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof Annotation)) { - return false; - } - - Annotation that = (Annotation) obj; - return Objects.equal(description, that.description) - && Objects.equal(attributes, that.attributes); - } - - @Override - public int hashCode() { - return Objects.hashCode(description, attributes); - } + public abstract Map getAttributes(); - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("description", description) - .add("attributes", attributes) - .toString(); - } - - private Annotation(String description, Map attributes) { - this.description = checkNotNull(description, "description"); - this.attributes = - Collections.unmodifiableMap( - new HashMap(checkNotNull(attributes, "attributes"))); - } + Annotation() {} } diff --git a/core/src/main/java/com/google/instrumentation/trace/Link.java b/core/src/main/java/com/google/instrumentation/trace/Link.java index 64995ff710..2934a0832f 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Link.java +++ b/core/src/main/java/com/google/instrumentation/trace/Link.java @@ -13,8 +13,7 @@ package com.google.instrumentation.trace; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; +import com.google.auto.value.AutoValue; import javax.annotation.concurrent.Immutable; /** @@ -27,7 +26,8 @@ * requests from different traces. */ @Immutable -public final class Link { +@AutoValue +public abstract class Link { /** The relationship with the linked {@code Span} relative to the current {@code Span}. */ public enum Type { /** When the linked {@code Span} is a child of the current {@code Span}. */ @@ -36,10 +36,6 @@ public enum Type { PARENT } - private final TraceId traceId; - private final SpanId spanId; - private final Type type; - /** * Returns a new {@code Link}. * @@ -48,7 +44,7 @@ public enum Type { * @return a new {@code Link}. */ public static Link fromSpanContext(SpanContext context, Type type) { - return new Link(context.getTraceId(), context.getSpanId(), type); + return new AutoValue_Link(context.getTraceId(), context.getSpanId(), type); } /** @@ -56,61 +52,21 @@ public static Link fromSpanContext(SpanContext context, Type type) { * * @return the {@code TraceId}. */ - public TraceId getTraceId() { - return traceId; - } + public abstract TraceId getTraceId(); /** * Returns the {@code SpanId}. * * @return the {@code SpanId} */ - public SpanId getSpanId() { - return spanId; - } + public abstract SpanId getSpanId(); /** * Returns the {@code Type}. * * @return the {@code Type}. */ - public Type getType() { - return type; - } + public abstract Type getType(); - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof Link)) { - return false; - } - - Link that = (Link) obj; - return Objects.equal(traceId, that.traceId) - && Objects.equal(spanId, that.spanId) - && Objects.equal(type, that.type); - } - - @Override - public int hashCode() { - return Objects.hashCode(traceId, spanId, type); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("traceId", traceId) - .add("spanId", spanId) - .add("type", type) - .toString(); - } - - private Link(TraceId traceId, SpanId spanId, Type type) { - this.traceId = traceId; - this.spanId = spanId; - this.type = type; - } + Link() {} } From e5a7410636cbdb5ed70f92ba4b64274d63a7c980 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Apr 2017 11:55:17 -0700 Subject: [PATCH 0013/1581] Change TestClock's default time to be non-zero. Timestamp.create(0, 0) represents an invalid time, so it is better to use a constant non-zero time. --- .../com/google/instrumentation/internal/TestClock.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/internal/TestClock.java b/core/src/main/java/com/google/instrumentation/internal/TestClock.java index 92332b1bca..a1c251323a 100644 --- a/core/src/main/java/com/google/instrumentation/internal/TestClock.java +++ b/core/src/main/java/com/google/instrumentation/internal/TestClock.java @@ -28,14 +28,15 @@ public final class TestClock extends Clock { private static final int NUM_NANOS_PER_SECOND = 1000 * 1000 * 1000; @GuardedBy("this") - private Timestamp currentTime = Timestamp.create(0, 0); + private Timestamp currentTime = Timestamp.create(123, 456); private TestClock() {} /** - * Creates a clock initialized to time 0. + * Creates a clock initialized to a constant non-zero time. {@code Timestamp.create(0, 0)} is not + * a good default, because it represents an invalid time. * - * @return a clock initialized to time 0. + * @return a clock initialized to a constant non-zero time. */ public static TestClock create() { return new TestClock(); From 546085b97a35a533891862f7c749b13ea1404acc Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 28 Apr 2017 12:12:34 -0700 Subject: [PATCH 0014/1581] Change SpanData to use AutoValue. (#262) * Change SpanData to use AutoValue. Fix the compileOnly build for auto_value library. * Ensure SpanData is immutable and add javadoc for create. --- core_impl/build.gradle | 2 + .../instrumentation/trace/SpanData.java | 116 +++++++----------- .../instrumentation/trace/SpanDataTest.java | 8 +- 3 files changed, 53 insertions(+), 73 deletions(-) diff --git a/core_impl/build.gradle b/core_impl/build.gradle index e7c7e72103..d0f5564b8b 100644 --- a/core_impl/build.gradle +++ b/core_impl/build.gradle @@ -6,6 +6,8 @@ dependencies { libraries.auto_value, libraries.guava + compileOnly libraries.auto_value + testCompile project(':instrumentation-java-core') signature "org.codehaus.mojo.signature:java16:+@signature" diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanData.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanData.java index ccb2de8a0c..62118abc4a 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanData.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanData.java @@ -13,9 +13,11 @@ package com.google.instrumentation.trace; -import com.google.common.base.MoreObjects; +import com.google.auto.value.AutoValue; import com.google.instrumentation.common.Timestamp; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Nullable; @@ -23,20 +25,28 @@ /** Immutable representation of all data collected by the {@link Span} class. */ @Immutable -public final class SpanData { - private final SpanContext context; - private final SpanId parentSpanId; - private final String displayName; - private final Timestamp startTimestamp; - private final Map attributes; - private final List> annotations; - private final List> networkEvents; - private final List links; - private final Status status; - private final Timestamp endTimestamp; +@AutoValue +public abstract class SpanData { - // This constructor must be called only by the implementation of the Span. - SpanData( + /** + * Returns a new immutable {@code SpanData}. + * + * @param context the {@code SpanContext} of the {@code Span}. + * @param parentSpanId the parent {@code SpanId} of the {@code Span}. {@code null} if the {@code + * Span} is a root. + * @param displayName the name of the {@code Span}. + * @param startTimestamp the start {@code Timestamp} of the {@code Span}. + * @param attributes the attributes associated with the {@code Span}. + * @param annotations the annotations associated with the {@code Span}. + * @param networkEvents the network events associated with the {@code Span}. + * @param links the links associated with the {@code Span}. + * @param status the {@code Status} of the {@code Span}. {@code null} if the {@code Span} is still + * active. + * @param endTimestamp the end {@code Timestamp} of the {@code Span}. {@code null} if the {@code + * Span} is still active. + * @return a new immutable {@code SpanData}. + */ + public static SpanData create( SpanContext context, @Nullable SpanId parentSpanId, String displayName, @@ -47,16 +57,17 @@ public final class SpanData { List links, @Nullable Status status, @Nullable Timestamp endTimestamp) { - this.context = context; - this.parentSpanId = parentSpanId; - this.displayName = displayName; - this.startTimestamp = startTimestamp; - this.attributes = Collections.unmodifiableMap(attributes); - this.annotations = Collections.unmodifiableList(annotations); - this.networkEvents = Collections.unmodifiableList(networkEvents); - this.links = Collections.unmodifiableList(links); - this.status = status; - this.endTimestamp = endTimestamp; + return new AutoValue_SpanData( + context, + parentSpanId, + displayName, + startTimestamp, + Collections.unmodifiableMap(new HashMap(attributes)), + Collections.unmodifiableList(new ArrayList>(annotations)), + Collections.unmodifiableList(new ArrayList>(networkEvents)), + Collections.unmodifiableList(new ArrayList(links)), + status, + endTimestamp); } /** @@ -64,9 +75,7 @@ public final class SpanData { * * @return the {@code SpanContext} associated with this {@code Span}. */ - public SpanContext getContext() { - return context; - } + public abstract SpanContext getContext(); /** * Returns the parent {@code SpanId} or {@code null} if the {@code Span} is a root {@code Span}. @@ -74,72 +83,57 @@ public SpanContext getContext() { * @return the parent {@code SpanId} or {@code null} if the {@code Span} is a root {@code Span}. */ @Nullable - public SpanId getParentSpanId() { - return parentSpanId; - } + public abstract SpanId getParentSpanId(); /** * Returns the display name of this {@code Span}. * * @return the display name of this {@code Span}. */ - public String getDisplayName() { - return displayName; - } + public abstract String getDisplayName(); /** * Returns the start {@code Timestamp} of this {@code Span}. * * @return the start {@code Timestamp} of this {@code Span}. */ - public Timestamp getStartTimestamp() { - return startTimestamp; - } + public abstract Timestamp getStartTimestamp(); /** * Returns the set of attributes recorded for this {@code Span}. * * @return the set of attributes recorded for this {@code Span}. */ - public Map getAttributes() { - return attributes; - } + public abstract Map getAttributes(); /** * Returns the list of {@code Annotation}s recorded for this {@code Span}. * * @return the list of {@code Annotation}s recorded for this {@code Span}. */ - public List> getAnnotations() { - return annotations; - } + public abstract List> getAnnotations(); /** * Returns the list of {@code NetworkEvent}s recorded for this {@code Span}. * * @return the list of {@code NetworkEvent}s recorded for this {@code Span}. */ - public List> getNetworkEvents() { - return networkEvents; - } + public abstract List> getNetworkEvents(); /** * Returns the list of {@code Link}s recorded for this {@code Span}. * * @return the list of {@code Link}s recorded for this {@code Span}. */ - public List getLinks() { - return links; - } + public abstract List getLinks(); /** * Returns the {@code Status} or {@code null} if {@code Span} is still active. * * @return the {@code Status} or {@code null} if {@code Span} is still active. */ - public Status getStatus() { - return status; - } + @Nullable + public abstract Status getStatus(); /** * Returns the end {@code Timestamp} or {@code null} if the {@code Span} is still active. @@ -147,23 +141,7 @@ public Status getStatus() { * @return the end {@code Timestamp} or {@code null} if the {@code Span} is still active. */ @Nullable - public Timestamp getEndTimestamp() { - return endTimestamp; - } + public abstract Timestamp getEndTimestamp(); - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("context", context) - .add("parentSpanId", parentSpanId) - .add("displayName", displayName) - .add("startTimestamp", startTimestamp) - .add("attributes", attributes) - .add("annotations", annotations) - .add("networkEvents", networkEvents) - .add("links", links) - .add("status", status) - .add("endTimestamp", endTimestamp) - .toString(); - } + SpanData() {} } diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/SpanDataTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/SpanDataTest.java index 803650b979..166dcfca05 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/SpanDataTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/SpanDataTest.java @@ -68,7 +68,7 @@ public void setUp() { @Test public void spanData_AllValues() { SpanData spanData = - new SpanData( + SpanData.create( spanContext, parentSpanId, DISPLAY_NAME, @@ -94,7 +94,7 @@ public void spanData_AllValues() { @Test public void spanData_RootActiveSpan() { SpanData spanData = - new SpanData( + SpanData.create( spanContext, null, DISPLAY_NAME, @@ -120,7 +120,7 @@ public void spanData_RootActiveSpan() { @Test public void spanData_AllDataEmpty() { SpanData spanData = - new SpanData( + SpanData.create( spanContext, parentSpanId, DISPLAY_NAME, @@ -146,7 +146,7 @@ public void spanData_AllDataEmpty() { @Test public void spanData_ToString() { String spanDataString = - new SpanData( + SpanData.create( spanContext, parentSpanId, DISPLAY_NAME, From d3625be7c0e265ab7a0530ecbd10441e730d141e Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 28 Apr 2017 12:48:07 -0700 Subject: [PATCH 0015/1581] Update animalsniffer signature requires (#265) * Add animalsniffer restrictions for java8 directory. * Update animalsniffer for android directory. --- core_impl_android/build.gradle | 2 +- core_impl_java_8/build.gradle | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core_impl_android/build.gradle b/core_impl_android/build.gradle index 5053d6e462..fc205157bc 100644 --- a/core_impl_android/build.gradle +++ b/core_impl_android/build.gradle @@ -4,5 +4,5 @@ dependencies { compile project(':instrumentation-java-core'), project(':instrumentation-java-core-impl') - signature "org.codehaus.mojo.signature:java16:+@signature" + signature "net.sf.androidscents.signature:android-api-level-14:+@signature" } diff --git a/core_impl_java_8/build.gradle b/core_impl_java_8/build.gradle index 043d7a7980..89655ef2a9 100644 --- a/core_impl_java_8/build.gradle +++ b/core_impl_java_8/build.gradle @@ -4,4 +4,6 @@ dependencies { compile project(':instrumentation-java-core'), project(':instrumentation-java-core-impl'), project(':instrumentation-java-core-impl-java') + + signature "org.codehaus.mojo.signature:java18:+@signature" } From 2ef6ebd45ba595b99f89dbad440a7181186f7b2d Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Apr 2017 12:01:52 -0700 Subject: [PATCH 0016/1581] Use Clock class throughout stats implementation. --- .../stats/MeasurementDescriptorToViewMap.java | 5 +- .../instrumentation/stats/MutableView.java | 9 ++-- .../stats/StatsManagerImplBase.java | 22 +++++--- .../MeasurementDescriptorToViewMapTest.java | 25 +++++----- .../stats/StatsManagerImplTest.java | 4 +- .../stats/StatsManagerImpl.java | 3 +- .../stats/StatsManagerImplJava.java | 5 +- .../stats/StatsManagerImpl.java | 3 ++ .../internal/InstantClock.java | 50 +++++++++++++++++++ .../stats/StatsManagerImpl.java | 3 ++ 10 files changed, 101 insertions(+), 28 deletions(-) create mode 100644 core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java index ea0e69b2c0..0471b3fc38 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java @@ -16,6 +16,7 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; +import com.google.instrumentation.common.Clock; import java.util.Collection; /** @@ -35,13 +36,13 @@ final class MeasurementDescriptorToViewMap { /** * Returns a {@link View} corresponding to the given {@link ViewDescriptor}. */ - final View getView(ViewDescriptor viewDescriptor) { + final View getView(ViewDescriptor viewDescriptor, Clock clock) { Collection views = mutableMap.get( viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); synchronized (mutableMap) { for (MutableView view : views) { if (view.getViewDescriptor().equals(viewDescriptor)) { - return view.toView(); + return view.toView(clock); } } } diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java b/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java index 9b6243b8e7..4a0eac4936 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java @@ -14,6 +14,7 @@ package com.google.instrumentation.stats; import com.google.common.annotations.VisibleForTesting; +import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.Function; import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.stats.View.DistributionView; @@ -53,7 +54,7 @@ abstract T match( /** * Convert this {@link MutableView} to {@link View}. */ - abstract View toView(); + abstract View toView(Clock clock); private MutableView() { } @@ -114,7 +115,7 @@ void record(StatsContextImpl context, double value) { } @Override - final View toView() { + final View toView(Clock clock) { final List distributionAggregations = new ArrayList(); for (Entry, MutableDistribution> entry : tagValueDistributionMap.entrySet()) { @@ -125,7 +126,7 @@ final View toView() { generateTags(entry.getKey()), distribution.getBucketCounts())); } return DistributionView.create(distributionViewDescriptor, distributionAggregations, start, - Timestamp.fromMillis(System.currentTimeMillis())); + clock.now()); } /** @@ -192,7 +193,7 @@ void record(StatsContextImpl tags, double value) { } @Override - final View toView() { + final View toView(Clock clock) { throw new UnsupportedOperationException("Not implemented."); } } diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java index 747379f2fb..b1245c49a6 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java @@ -13,9 +13,9 @@ package com.google.instrumentation.stats; +import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.EventQueue; import com.google.instrumentation.common.Function; -import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.stats.MutableView.MutableDistributionView; import com.google.instrumentation.stats.MutableView.MutableIntervalView; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; @@ -27,8 +27,12 @@ public class StatsManagerImplBase extends StatsManager { private final EventQueue queue; - StatsManagerImplBase(EventQueue queue) { + // clock used throughout the stats implementation + private final Clock clock; + + StatsManagerImplBase(EventQueue queue, Clock clock) { this.queue = queue; + this.clock = clock; } private final MeasurementDescriptorToViewMap measurementDescriptorToViewMap = @@ -47,13 +51,13 @@ public void registerView(ViewDescriptor viewDescriptor) { + SupportedViews.SUPPORTED_VIEW.getName()); } - if (measurementDescriptorToViewMap.getView(viewDescriptor) != null) { + if (measurementDescriptorToViewMap.getView(viewDescriptor, clock) != null) { // Ignore views that are already registered. return; } MutableView mutableView = viewDescriptor.match( - new CreateMutableDistributionViewFunction(), new CreateMutableIntervalViewFunction()); + new CreateMutableDistributionViewFunction(clock), new CreateMutableIntervalViewFunction()); measurementDescriptorToViewMap.putView( viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName(), mutableView); @@ -61,7 +65,7 @@ public void registerView(ViewDescriptor viewDescriptor) { @Override public View getView(ViewDescriptor viewDescriptor) { - View view = measurementDescriptorToViewMap.getView(viewDescriptor); + View view = measurementDescriptorToViewMap.getView(viewDescriptor, clock); if (view == null) { throw new IllegalArgumentException( "View for view descriptor " + viewDescriptor.getName() + " not found."); @@ -108,10 +112,16 @@ public void process() { private static final class CreateMutableDistributionViewFunction implements Function { + private final Clock clock; + + public CreateMutableDistributionViewFunction(Clock clock) { + this.clock = clock; + } + @Override public MutableView apply(DistributionViewDescriptor viewDescriptor) { return MutableDistributionView.create( - viewDescriptor, Timestamp.fromMillis(System.currentTimeMillis())); + viewDescriptor, clock.now()); } } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java index 3d98a0d132..cf71b33b33 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java @@ -15,15 +15,14 @@ import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.Timestamp; +import com.google.instrumentation.common.Clock; +import com.google.instrumentation.internal.TestClock; import com.google.instrumentation.stats.MutableView.MutableDistributionView; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link MeasurementDescriptorToViewMap}. - */ +/** Tests for {@link MeasurementDescriptorToViewMap}. */ @RunWith(JUnit4.class) public class MeasurementDescriptorToViewMapTest { private final MeasurementDescriptorToViewMap measurementDescriptorToViewMap = @@ -31,14 +30,16 @@ public class MeasurementDescriptorToViewMapTest { @Test public void testPutAndGetView() { - MutableView expected = MutableDistributionView.create( - RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, - Timestamp.fromMillis(System.currentTimeMillis())); + Clock clock = TestClock.create(); + MutableView expected = + MutableDistributionView.create( + RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock.now()); measurementDescriptorToViewMap.putView( - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY.getMeasurementDescriptorName(), - expected); - View actual = measurementDescriptorToViewMap.getView( - RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY.getMeasurementDescriptorName(), + expected); + View actual = + measurementDescriptorToViewMap.getView( + RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock); assertThat(actual.getViewDescriptor()).isEqualTo(expected.getViewDescriptor()); } -} \ No newline at end of file +} diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 8a8039d61c..e57145b7a7 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -17,6 +17,8 @@ import com.google.common.collect.ImmutableMap; import com.google.instrumentation.common.SimpleEventQueue; +import com.google.instrumentation.common.Timestamp; +import com.google.instrumentation.internal.TestClock; import com.google.instrumentation.stats.View.DistributionView; import java.util.Arrays; import java.util.Collections; @@ -54,7 +56,7 @@ public class StatsManagerImplTest { private final StatsManagerImplBase statsManager = - new StatsManagerImplBase(new SimpleEventQueue()); + new StatsManagerImplBase(new SimpleEventQueue(), TestClock.create(Timestamp.create(1, 2))); @Test public void testRegisterAndGetView() throws Exception { diff --git a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java index 6b4fbd66e5..fe3fb91f49 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -14,6 +14,7 @@ package com.google.instrumentation.stats; import com.google.instrumentation.common.SimpleEventQueue; +import com.google.instrumentation.internal.MillisClock; /** * Android-compatible implementation of {@link StatsManager}. @@ -22,6 +23,6 @@ public final class StatsManagerImpl extends StatsManagerImplBase { public StatsManagerImpl() { // TODO(sebright): Use a more efficient queue implementation. - super(new SimpleEventQueue()); + super(new SimpleEventQueue(), MillisClock.getInstance()); } } diff --git a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImplJava.java b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImplJava.java index d588d12a69..5c43eff6a0 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImplJava.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImplJava.java @@ -13,6 +13,7 @@ package com.google.instrumentation.stats; +import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.DisruptorEventQueue; /** @@ -20,7 +21,7 @@ */ public abstract class StatsManagerImplJava extends StatsManagerImplBase { - public StatsManagerImplJava() { - super(DisruptorEventQueue.getInstance()); + public StatsManagerImplJava(Clock clock) { + super(DisruptorEventQueue.getInstance(), clock); } } diff --git a/core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java index be178132a4..1d8bea1cef 100644 --- a/core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -13,11 +13,14 @@ package com.google.instrumentation.stats; +import com.google.instrumentation.internal.MillisClock; + /** * Java 7 implementation of {@link StatsManager}. */ public final class StatsManagerImpl extends StatsManagerImplJava { public StatsManagerImpl() { + super(MillisClock.getInstance()); } } diff --git a/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java b/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java new file mode 100644 index 0000000000..d54c521ace --- /dev/null +++ b/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java @@ -0,0 +1,50 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.internal; + +import com.google.instrumentation.common.Clock; +import com.google.instrumentation.common.Timestamp; +import java.time.Instant; +import javax.annotation.concurrent.ThreadSafe; + +/** + * A {@link Clock} that uses {@link Instant#now()}. + */ +@ThreadSafe +public final class InstantClock extends Clock { + private static final InstantClock INSTANCE = new InstantClock(); + + private InstantClock() {} + + /** + * Returns an {@code InstantClock}. + * + * @return an {@code InstantClock}. + */ + public static InstantClock getInstance() { + return INSTANCE; + } + + @Override + public Timestamp now() { + Instant instant = Instant.now(); + return Timestamp.create(instant.getEpochSecond(), instant.getNano()); + } + + @Override + public long nowNanos() { + // TODO(sebright): Is this correct? + return System.nanoTime(); + } +} diff --git a/core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java index 5f8e8d6524..9c1aaed428 100644 --- a/core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -13,11 +13,14 @@ package com.google.instrumentation.stats; +import com.google.instrumentation.internal.InstantClock; + /** * Java 8 implementation of {@link StatsManager}. */ public final class StatsManagerImpl extends StatsManagerImplJava { public StatsManagerImpl() { + super(InstantClock.getInstance()); } } From 7b1bebbf0530c93537c58eb65efb9fefc18c3c9d Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Apr 2017 13:31:28 -0700 Subject: [PATCH 0017/1581] Temporarily remove reference to Instant class. We can use Instant once we skip building core_impl_java_8 with Java 7. --- .../google/instrumentation/internal/InstantClock.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java b/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java index d54c521ace..f7019f8728 100644 --- a/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java +++ b/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java @@ -15,11 +15,10 @@ import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.Timestamp; -import java.time.Instant; import javax.annotation.concurrent.ThreadSafe; /** - * A {@link Clock} that uses {@link Instant#now()}. + * A {@link Clock} that uses {@code Instant#now()}. */ @ThreadSafe public final class InstantClock extends Clock { @@ -38,8 +37,11 @@ public static InstantClock getInstance() { @Override public Timestamp now() { - Instant instant = Instant.now(); - return Timestamp.create(instant.getEpochSecond(), instant.getNano()); + // // TODO(sebright): Use Instant once we skip building this class with Java 7. + // Instant instant = Instant.now(); + // return Timestamp.create(instant.getEpochSecond(), instant.getNano()); + + return Timestamp.fromMillis(System.currentTimeMillis()); } @Override From 5d4e4f478847cc9259dd483afee96f2b0e1c89f2 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Apr 2017 16:02:56 -0700 Subject: [PATCH 0018/1581] Use a time from 2017 as TestClock's default time. --- .../java/com/google/instrumentation/internal/TestClock.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/instrumentation/internal/TestClock.java b/core/src/main/java/com/google/instrumentation/internal/TestClock.java index a1c251323a..7cf922d155 100644 --- a/core/src/main/java/com/google/instrumentation/internal/TestClock.java +++ b/core/src/main/java/com/google/instrumentation/internal/TestClock.java @@ -28,7 +28,7 @@ public final class TestClock extends Clock { private static final int NUM_NANOS_PER_SECOND = 1000 * 1000 * 1000; @GuardedBy("this") - private Timestamp currentTime = Timestamp.create(123, 456); + private Timestamp currentTime = validateNanos(Timestamp.create(1493419949, 223123456)); private TestClock() {} From db20d40d5f9e210cbdc93418e32bdf9af21133e3 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Apr 2017 16:09:11 -0700 Subject: [PATCH 0019/1581] Check exact time in StatsManagerImplTest.testRecord(). --- .../stats/StatsManagerImplTest.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index e57145b7a7..857c909ab3 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -53,10 +53,9 @@ public class StatsManagerImplTest { new StatsContextImpl(ImmutableMap.of(wrongTagKey, tagValue1)); private static final StatsContextImpl wrongTag2 = new StatsContextImpl(ImmutableMap.of(wrongTagKey, tagValue1, wrongTagKey2, tagValue2)); - - + private final TestClock clock = TestClock.create(); private final StatsManagerImplBase statsManager = - new StatsManagerImplBase(new SimpleEventQueue(), TestClock.create(Timestamp.create(1, 2))); + new StatsManagerImplBase(new SimpleEventQueue(), clock); @Test public void testRegisterAndGetView() throws Exception { @@ -89,17 +88,20 @@ public void testGetNonexistentView() throws Exception { @Test public void testRecord() { + clock.setTime(Timestamp.create(1, 2)); statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); for (double val : Arrays.asList(10.0, 20.0, 30.0, 40.0)) { statsManager.record( oneTag, MeasurementMap.of(RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, val)); } + clock.setTime(Timestamp.create(3, 4)); DistributionView view = (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - assertThat(view.getViewDescriptor()).isEqualTo(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - // TODO(songya): update to make assertions on the exact time based on fake clock. - assertThat(view.getEnd().getSeconds()).isAtLeast(view.getStart().getSeconds()); + assertThat(view.getViewDescriptor()) + .isEqualTo(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + assertThat(view.getStart()).isEqualTo(Timestamp.create(1, 2)); + assertThat(view.getEnd()).isEqualTo(Timestamp.create(3, 4)); List distributionAggregations = view.getDistributionAggregations(); assertThat(distributionAggregations).hasSize(1); DistributionAggregation distributionAggregation = distributionAggregations.get(0); From c6e5603618d488f3fd5b472bfddcc867f22adab5 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Apr 2017 16:23:56 -0700 Subject: [PATCH 0020/1581] Check view start and end times in MeasurementDescriptorToViewMapTest. --- .../MeasurementDescriptorToViewMapTest.java | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java index cf71b33b33..4cef662f58 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java @@ -14,10 +14,15 @@ package com.google.instrumentation.stats; import static com.google.common.truth.Truth.assertThat; +import static com.google.instrumentation.stats.RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW; +import static org.junit.Assert.fail; -import com.google.instrumentation.common.Clock; +import com.google.instrumentation.common.Function; +import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.internal.TestClock; import com.google.instrumentation.stats.MutableView.MutableDistributionView; +import com.google.instrumentation.stats.View.DistributionView; +import com.google.instrumentation.stats.View.IntervalView; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -30,16 +35,29 @@ public class MeasurementDescriptorToViewMapTest { @Test public void testPutAndGetView() { - Clock clock = TestClock.create(); - MutableView expected = - MutableDistributionView.create( - RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock.now()); + TestClock clock = TestClock.create(Timestamp.create(10, 20)); measurementDescriptorToViewMap.putView( RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY.getMeasurementDescriptorName(), - expected); - View actual = - measurementDescriptorToViewMap.getView( - RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock); - assertThat(actual.getViewDescriptor()).isEqualTo(expected.getViewDescriptor()); + MutableDistributionView.create(RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock.now())); + clock.setTime(Timestamp.create(30, 40)); + View actual = measurementDescriptorToViewMap.getView(RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock); + actual.match( + new Function() { + @Override + public Void apply(DistributionView view) { + assertThat(view.getViewDescriptor()).isEqualTo(RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + assertThat(view.getStart()).isEqualTo(Timestamp.create(10, 20)); + assertThat(view.getEnd()).isEqualTo(Timestamp.create(30, 40)); + assertThat(view.getDistributionAggregations()).isEmpty(); + return null; + } + }, + new Function() { + @Override + public Void apply(IntervalView view) { + fail("Wrong view type."); + return null; + } + }); } } From e5c0f73774a2e8ce8a365b9cb7e26b67e90845ea Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Sun, 30 Apr 2017 11:35:06 -0700 Subject: [PATCH 0021/1581] Remove TODO. --- .../java/com/google/instrumentation/internal/InstantClock.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java b/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java index f7019f8728..bc2a57436d 100644 --- a/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java +++ b/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java @@ -46,7 +46,6 @@ public Timestamp now() { @Override public long nowNanos() { - // TODO(sebright): Is this correct? return System.nanoTime(); } } From fcee5dff099d093703877237b5704096887f395a Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 1 May 2017 10:41:47 -0700 Subject: [PATCH 0022/1581] Change AttributeValue, EndSpanOptions and NetworkEvent to use autovalue. (#267) * Change AttributeValue, EndSpanOptions and NetworkEvent to use autovalue. --- .../instrumentation/trace/AttributeValue.java | 78 ++-------------- .../instrumentation/trace/EndSpanOptions.java | 66 ++++--------- .../instrumentation/trace/NetworkEvent.java | 93 ++++++------------- .../trace/AttributeValueTest.java | 3 - .../trace/EndSpanOptionsTest.java | 2 +- 5 files changed, 58 insertions(+), 184 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/trace/AttributeValue.java b/core/src/main/java/com/google/instrumentation/trace/AttributeValue.java index a6cde61224..09b749cd87 100644 --- a/core/src/main/java/com/google/instrumentation/trace/AttributeValue.java +++ b/core/src/main/java/com/google/instrumentation/trace/AttributeValue.java @@ -15,8 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; +import com.google.auto.value.AutoValue; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -25,11 +24,8 @@ * of values: {@code String}, {@code Boolean} or {@code Long}. */ @Immutable -public final class AttributeValue { - private final String stringValue; - private final Boolean booleanValue; - private final Long longValue; - +@AutoValue +public abstract class AttributeValue { /** * Returns an {@code AttributeValue} with a string value. * @@ -38,7 +34,7 @@ public final class AttributeValue { * @throws NullPointerException if {@code stringValue} is {@code null}. */ public static AttributeValue stringAttributeValue(String stringValue) { - return new AttributeValue(checkNotNull(stringValue, "stringValue"), null, null); + return new AutoValue_AttributeValue(checkNotNull(stringValue, "stringValue"), null, null); } /** @@ -48,7 +44,7 @@ public static AttributeValue stringAttributeValue(String stringValue) { * @return an {@code AttributeValue} with a boolean value. */ public static AttributeValue booleanAttributeValue(boolean booleanValue) { - return new AttributeValue(null, booleanValue, null); + return new AutoValue_AttributeValue(null, booleanValue, null); } /** @@ -58,15 +54,10 @@ public static AttributeValue booleanAttributeValue(boolean booleanValue) { * @return an {@code AttributeValue} with a long value. */ public static AttributeValue longAttributeValue(long longValue) { - return new AttributeValue(null, null, longValue); + return new AutoValue_AttributeValue(null, null, longValue); } - private AttributeValue( - @Nullable String stringValue, @Nullable Boolean booleanValue, @Nullable Long longValue) { - this.stringValue = stringValue; - this.booleanValue = booleanValue; - this.longValue = longValue; - } + AttributeValue() {} /** * Returns the {@code String} value if this is a string {@code AttributeValue}, otherwise {@code @@ -76,9 +67,7 @@ private AttributeValue( * null}. */ @Nullable - public String getStringValue() { - return stringValue; - } + public abstract String getStringValue(); /** * Returns the {@code Boolean} value if this is a boolean {@code AttributeValue}, otherwise {@code @@ -88,9 +77,7 @@ public String getStringValue() { * null}. */ @Nullable - public Boolean getBooleanValue() { - return booleanValue; - } + public abstract Boolean getBooleanValue(); /** * Returns the {@code Long} value if this is a long {@code AttributeValue}, otherwise {@code @@ -100,50 +87,5 @@ public Boolean getBooleanValue() { * null}. */ @Nullable - public Long getLongValue() { - return longValue; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof AttributeValue)) { - return false; - } - - AttributeValue that = (AttributeValue) obj; - return Objects.equal(stringValue, that.stringValue) - && Objects.equal(booleanValue, that.booleanValue) - && Objects.equal(longValue, that.longValue); - } - - @Override - public int hashCode() { - return Objects.hashCode(stringValue, booleanValue, longValue); - } - - @Override - public String toString() { - if (getStringValue() != null) { - return MoreObjects.toStringHelper(this) - .add("type", "string") - .add("value", getStringValue()) - .toString(); - } else if (getBooleanValue() != null) { - return MoreObjects.toStringHelper(this) - .add("type", "boolean") - .add("value", getBooleanValue()) - .toString(); - } else if (getLongValue() != null) { - return MoreObjects.toStringHelper(this) - .add("type", "long") - .add("value", getLongValue()) - .toString(); - } - // This should never happen - throw new RuntimeException("Not a supported attribute value"); - } + public abstract Long getLongValue(); } diff --git a/core/src/main/java/com/google/instrumentation/trace/EndSpanOptions.java b/core/src/main/java/com/google/instrumentation/trace/EndSpanOptions.java index 31ad67743b..25f6e7c6d3 100644 --- a/core/src/main/java/com/google/instrumentation/trace/EndSpanOptions.java +++ b/core/src/main/java/com/google/instrumentation/trace/EndSpanOptions.java @@ -15,8 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; +import com.google.auto.value.AutoValue; import javax.annotation.concurrent.Immutable; /** @@ -24,23 +23,18 @@ * overriding the {@link Status status}. */ @Immutable -public final class EndSpanOptions { - private final Status status; - +@AutoValue +public abstract class EndSpanOptions { /** The default {@code EndSpanOptions}. */ public static final EndSpanOptions DEFAULT = builder().build(); - private EndSpanOptions(Status status) { - this.status = status; - } - /** * Returns a new {@link Builder} with default options. * * @return a new {@code Builder} with default options. */ public static Builder builder() { - return new Builder(); + return new AutoValue_EndSpanOptions.Builder().setStatus(Status.OK); } /** @@ -48,40 +42,11 @@ public static Builder builder() { * * @return the status. */ - public Status getStatus() { - return status; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof EndSpanOptions)) { - return false; - } - - EndSpanOptions that = (EndSpanOptions) obj; - return Objects.equal(status, that.status); - } - - @Override - public int hashCode() { - return Objects.hashCode(status); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this).add("status", status).toString(); - } + public abstract Status getStatus(); /** Builder class for {@link EndSpanOptions}. */ - public static final class Builder { - private Status status = Status.OK; - - private Builder() {} - + @AutoValue.Builder + public abstract static class Builder { /** * Sets the status for the {@link Span}. * @@ -89,20 +54,25 @@ private Builder() {} * * @param status the status. * @return this. - * @throws NullPointerException if {@code status} is {@code null}. */ - public Builder setStatus(Status status) { - this.status = checkNotNull(status, "status"); - return this; - } + public abstract Builder setStatus(Status status); + + abstract EndSpanOptions autoBuild(); // not public /** * Builds and returns a {@code EndSpanOptions} with the desired settings. * * @return a {@code EndSpanOptions} with the desired settings. + * @throws NullPointerException if {@code status} is {@code null}. */ public EndSpanOptions build() { - return new EndSpanOptions(status); + EndSpanOptions endSpanOptions = autoBuild(); + checkNotNull(endSpanOptions.getStatus(), "status"); + return endSpanOptions; } + + Builder() {} } + + EndSpanOptions() {} } diff --git a/core/src/main/java/com/google/instrumentation/trace/NetworkEvent.java b/core/src/main/java/com/google/instrumentation/trace/NetworkEvent.java index 4e15d2bbcd..19730a184b 100644 --- a/core/src/main/java/com/google/instrumentation/trace/NetworkEvent.java +++ b/core/src/main/java/com/google/instrumentation/trace/NetworkEvent.java @@ -15,7 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.MoreObjects; +import com.google.auto.value.AutoValue; import com.google.instrumentation.common.Timestamp; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -26,7 +26,8 @@ * the kernel time and message size. */ @Immutable -public final class NetworkEvent { +@AutoValue +public abstract class NetworkEvent { /** Available types for a {@code NetworkEvent}. */ public enum Type { /** When the message was sent. */ @@ -35,30 +36,22 @@ public enum Type { RECV, } - // Can be null if not available. - private final Timestamp kernelTimestamp; - private final Type type; - private final long messageId; - private final long messageSize; - - private NetworkEvent( - @Nullable Timestamp kernelTimestamp, Type type, long messageId, long messageSize) { - this.kernelTimestamp = kernelTimestamp; - this.type = type; - this.messageId = messageId; - this.messageSize = messageSize; - } - /** * Returns a new {@link Builder} with default values. * * @param type designates whether this is a network send or receive message. * @param messageId serves to uniquely identify each network message. * @return a new {@code Builder} with default values. - * @throws NullPointerException if type is null. + * @throws NullPointerException if {@code type} is {@code null}. */ public static Builder builder(Type type, long messageId) { - return new Builder(type, messageId); + return new AutoValue_NetworkEvent.Builder() + .setType(checkNotNull(type, "type")) + .setMessageId(messageId) + // We need to set a value for the message size because the autovalue requires all + // primitives to be initialized. + // TODO(bdrutu): Consider to change the API to require message size. + .setMessageSize(0); } /** @@ -69,61 +62,37 @@ public static Builder builder(Type type, long messageId) { * set. */ @Nullable - public Timestamp getKernelTimestamp() { - return kernelTimestamp; - } + public abstract Timestamp getKernelTimestamp(); /** * Returns the type of the {@code NetworkEvent}. * * @return the type of the {@code NetworkEvent}. */ - public Type getType() { - return type; - } + public abstract Type getType(); /** * Returns the message id argument that serves to uniquely identify each network message. * * @return The message id of the {@code NetworkEvent}. */ - public long getMessageId() { - return messageId; - } + public abstract long getMessageId(); /** * Returns The message size in bytes of the {@code NetworkEvent}. * * @return The message size in bytes of the {@code NetworkEvent}. */ - public long getMessageSize() { - return messageSize; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("kernelTimestamp", kernelTimestamp) - .add("type", type) - .add("messageId", messageId) - .add("messageSize", messageSize) - .toString(); - } + public abstract long getMessageSize(); /** Builder class for {@link NetworkEvent}. */ - public static final class Builder { - // Required fields. - private final Type type; - private final long messageId; - // Optional fields. - private Timestamp kernelTimestamp; - private long messageSize; - - // Constructs a new {@link Builder} with default values. - private Builder(Type type, long messageId) { - this.type = checkNotNull(type, "type"); - this.messageId = messageId; - } + @AutoValue.Builder + public abstract static class Builder { + // Package protected methods because these values are mandatory and set only in the + // NetworkEvent#builder() function. + abstract Builder setType(Type type); + + abstract Builder setMessageId(long messageId); /** * Sets the kernel timestamp. @@ -131,10 +100,7 @@ private Builder(Type type, long messageId) { * @param kernelTimestamp The kernel timestamp of the event. * @return this. */ - public Builder setKernelTimestamp(@Nullable Timestamp kernelTimestamp) { - this.kernelTimestamp = kernelTimestamp; - return this; - } + public abstract Builder setKernelTimestamp(@Nullable Timestamp kernelTimestamp); /** * Sets the message size. @@ -142,18 +108,17 @@ public Builder setKernelTimestamp(@Nullable Timestamp kernelTimestamp) { * @param messageSize represents the size in bytes of this network message. * @return this. */ - public Builder setMessageSize(long messageSize) { - this.messageSize = messageSize; - return this; - } + public abstract Builder setMessageSize(long messageSize); /** * Builds and returns a {@code NetworkEvent} with the desired values. * * @return a {@code NetworkEvent} with the desired values. */ - public NetworkEvent build() { - return new NetworkEvent(kernelTimestamp, type, messageId, messageSize); - } + public abstract NetworkEvent build(); + + Builder() {} } + + NetworkEvent() {} } diff --git a/core/src/test/java/com/google/instrumentation/trace/AttributeValueTest.java b/core/src/test/java/com/google/instrumentation/trace/AttributeValueTest.java index 82165f41c4..b609a5ce3f 100644 --- a/core/src/test/java/com/google/instrumentation/trace/AttributeValueTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/AttributeValueTest.java @@ -66,13 +66,10 @@ public void attributeValue_EqualsAndHashCode() { @Test public void attributeValue_ToString() { AttributeValue attribute = AttributeValue.stringAttributeValue("MyStringAttributeValue"); - assertThat(attribute.toString()).contains("string"); assertThat(attribute.toString()).contains("MyStringAttributeValue"); attribute = AttributeValue.booleanAttributeValue(true); - assertThat(attribute.toString()).contains("boolean"); assertThat(attribute.toString()).contains("true"); attribute = AttributeValue.longAttributeValue(123456L); - assertThat(attribute.toString()).contains("long"); assertThat(attribute.toString()).contains("123456"); } } diff --git a/core/src/test/java/com/google/instrumentation/trace/EndSpanOptionsTest.java b/core/src/test/java/com/google/instrumentation/trace/EndSpanOptionsTest.java index e718ca0405..dc59808d95 100644 --- a/core/src/test/java/com/google/instrumentation/trace/EndSpanOptionsTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/EndSpanOptionsTest.java @@ -25,7 +25,7 @@ public class EndSpanOptionsTest { @Test(expected = NullPointerException.class) public void setNullStatus() { - EndSpanOptions.builder().setStatus(null); + EndSpanOptions.builder().setStatus(null).build(); } @Test From 0c9fcffe501ecf6e583d917159f41c72c81d8841 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 1 May 2017 12:29:46 -0700 Subject: [PATCH 0023/1581] Add initial span implementation. (#261) * Add initial span implementation. * Use Clock for TimestampConverter and mocking for tests. --- .../instrumentation/trace/SpanImpl.java | 195 ++++++++++++++++++ .../trace/TimestampConverter.java | 10 +- .../instrumentation/trace/SpanImplTest.java | 111 ++++++++++ .../trace/TimestampConverterTest.java | 26 ++- 4 files changed, 332 insertions(+), 10 deletions(-) create mode 100644 core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java create mode 100644 core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java new file mode 100644 index 0000000000..b43714bd5f --- /dev/null +++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java @@ -0,0 +1,195 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import static com.google.common.base.Preconditions.checkState; + +import com.google.instrumentation.common.Clock; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.Nullable; +import javax.annotation.concurrent.GuardedBy; +import javax.annotation.concurrent.ThreadSafe; + +/** Implementation for the {@link Span} class. */ +@ThreadSafe +final class SpanImpl extends Span { + private static final Logger logger = Logger.getLogger(Tracer.class.getName()); + + // The parent SpanId of this span. Null if this is a root. + private final SpanId parentSpanId; + // Handler called when the span starts and ends. + private final StartEndHandler startEndHandler; + // The displayed name of the span. + private final String name; + // The clock used to get the time. + private final Clock clock; + // The time converter used to convert nano time to Timestamp. This is needed because java has + // milliseconds granularity for Timestamp and tracing events are recorded more often. + private final TimestampConverter timestampConverter; + // The start time of the span. Set when the span is created iff the RECORD_EVENTS options is + // set, otherwise 0. + private final long startNanoTime; + // The status of the span. Set when the span is ended iff the RECORD_EVENTS options is set. + @GuardedBy("this") + private Status status; + // The end time of the span. Set when the span is ended iff the RECORD_EVENTS options is set, + // otherwise 0. + @GuardedBy("this") + private long endNanoTime; + // True if the span is ended. + @GuardedBy("this") + private boolean hasBeenEnded; + + // Creates and starts a span with the given configuration. TimestampConverter is null if the + // Span is a root span or the parent is not sampled. If the parent is sampled we should use the + // same converter to ensure ordering between tracing events. + static SpanImpl startSpan(SpanContext context, + @Nullable EnumSet options, + String name, + @Nullable SpanId parentSpanId, + StartEndHandler startEndHandler, + @Nullable TimestampConverter timestampConverter, + Clock clock) { + SpanImpl span = new SpanImpl(context, options, name, parentSpanId, startEndHandler, + timestampConverter, clock); + // Call onStart here instead of calling in the constructor to make sure the span is completely + // initialized. + if (span.getOptions().contains(Options.RECORD_EVENTS)) { + startEndHandler.onStart(span); + } + return span; + } + + /** + * Returns the name of the {@code Span}. + * + * @return the name of the {@code Span}. + */ + String getName() { + return name; + } + + /** + * Returns an immutable representation of all the data from this {@code Span}. + * + * @return an immutable representation of all the data from this {@code Span}. + * @throws IllegalStateException if the Span doesn't have RECORD_EVENTS option. + */ + SpanData toSpanData() { + checkState( + getOptions().contains(Options.RECORD_EVENTS), + "Getting SpanData for a Span without RECORD_EVENTS option."); + synchronized (this) { + // TODO(bdrutu): Set the attributes, annotations, network events and links in the SpanData + // when add the support for them. + return SpanData.create( + getContext(), + parentSpanId, + name, + timestampConverter.convertNanoTime(startNanoTime), + Collections.emptyMap(), + Collections.>emptyList(), + Collections.>emptyList(), + Collections.emptyList(), + hasBeenEnded ? status : null, + hasBeenEnded ? timestampConverter.convertNanoTime(endNanoTime) : null); + } + } + + @Override + public void addAttributes(Map attributes) { + // TODO(bdrutu): Implement this. + } + + @Override + public void addAnnotation(String description, Map attributes) { + // TODO(bdrutu): Implement this. + } + + @Override + public void addAnnotation(Annotation annotation) { + // TODO(bdrutu): Implement this. + } + + @Override + public void addNetworkEvent(NetworkEvent networkEvent) { + // TODO(bdrutu): Implement this. + } + + @Override + public void addLink(Link link) { + // TODO(bdrutu): Implement this. + } + + @Override + public void end(EndSpanOptions options) { + if (!getOptions().contains(Options.RECORD_EVENTS)) { + return; + } + synchronized (this) { + if (hasBeenEnded) { + logger.log(Level.FINE, "Calling end() on an ended Span."); + return; + } + status = options.getStatus(); + endNanoTime = clock.nowNanos(); + startEndHandler.onEnd(this); + hasBeenEnded = true; + } + } + + /** + * Abstract class to handle the start and end operations for a {@link Span} only when the {@code + * Span} has {@link Span.Options#RECORD_EVENTS} option. + * + *

Implementation must avoid high overhead work in any of the methods because the code is + * executed on the critical path. + * + *

One instance can be called by multiple threads in the same time, so the implementation + * must be thread-safe. + */ + abstract static class StartEndHandler { + abstract void onStart(SpanImpl span); + + abstract void onEnd(SpanImpl span); + } + + private SpanImpl( + SpanContext context, + @Nullable EnumSet options, + String name, + @Nullable SpanId parentSpanId, + StartEndHandler startEndHandler, + @Nullable TimestampConverter timestampConverter, + Clock clock) { + super(context, options); + this.parentSpanId = parentSpanId; + this.name = name; + this.startEndHandler = startEndHandler; + this.clock = clock; + this.hasBeenEnded = false; + if (getOptions().contains(Options.RECORD_EVENTS)) { + this.timestampConverter = + timestampConverter != null ? timestampConverter : TimestampConverter.now(clock); + startNanoTime = clock.nowNanos(); + } else { + this.startNanoTime = 0; + this.timestampConverter = null; + } + } +} diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TimestampConverter.java b/core_impl/src/main/java/com/google/instrumentation/trace/TimestampConverter.java index 92a76b8d09..5a01588748 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TimestampConverter.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TimestampConverter.java @@ -13,9 +13,8 @@ package com.google.instrumentation.trace; -import com.google.common.annotations.VisibleForTesting; +import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.Timestamp; -import com.google.instrumentation.common.TimestampFactory; import javax.annotation.concurrent.Immutable; /** @@ -28,8 +27,8 @@ final class TimestampConverter { private final long nanoTime; // Returns a WallTimeConverter initialized to now. - static TimestampConverter now() { - return new TimestampConverter(TimestampFactory.now(), System.nanoTime()); + static TimestampConverter now(Clock clock) { + return new TimestampConverter(clock.now(), clock.nowNanos()); } /** @@ -42,8 +41,7 @@ Timestamp convertNanoTime(long nanoTime) { return timestamp.addNanos(nanoTime - this.nanoTime); } - @VisibleForTesting - TimestampConverter(Timestamp timestamp, long nanoTime) { + private TimestampConverter(Timestamp timestamp, long nanoTime) { this.timestamp = timestamp; this.nanoTime = nanoTime; } diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java new file mode 100644 index 0000000000..2f205546a5 --- /dev/null +++ b/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java @@ -0,0 +1,111 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.instrumentation.common.Duration; +import com.google.instrumentation.common.Timestamp; +import com.google.instrumentation.internal.TestClock; +import com.google.instrumentation.trace.Span.Options; +import com.google.instrumentation.trace.SpanImpl.StartEndHandler; +import java.util.EnumSet; +import java.util.Random; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link SpanImpl}. */ +@RunWith(JUnit4.class) +public class SpanImplTest { + private static final String SPAN_NAME = "MySpanName"; + private final Random random = new Random(1234); + private final SpanContext spanContext = + SpanContext.create( + TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); + private final SpanId parentSpanId = SpanId.generateRandomId(random); + private final Timestamp timestamp = Timestamp.create(1234, 5678); + private final TestClock testClock = TestClock.create(timestamp); + private final TimestampConverter timestampConverter = TimestampConverter.now(testClock); + private EnumSet noRecordSpanOptions = EnumSet.noneOf(Options.class); + private EnumSet recordSpanOptions = EnumSet.of(Options.RECORD_EVENTS); + @Mock private StartEndHandler startEndHandler; + @Rule public final ExpectedException exception = ExpectedException.none(); + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void toSpanData_NoRecordEvents() { + SpanImpl span = + SpanImpl.startSpan( + spanContext, + noRecordSpanOptions, + SPAN_NAME, + parentSpanId, + startEndHandler, + timestampConverter, + testClock); + span.end(); + exception.expect(IllegalStateException.class); + span.toSpanData(); + } + + @Test + public void toSpanData_ActiveSpan() { + SpanImpl span = + SpanImpl.startSpan( + spanContext, + recordSpanOptions, + SPAN_NAME, + parentSpanId, + startEndHandler, + timestampConverter, + testClock); + Mockito.verify(startEndHandler, Mockito.times(1)).onStart(span); + SpanData spanData = span.toSpanData(); + assertThat(spanData.getStartTimestamp()).isEqualTo(timestamp); + assertThat(spanData.getStatus()).isNull(); + assertThat(spanData.getEndTimestamp()).isNull(); + } + + @Test + public void toSpanData_EndedSpan() { + SpanImpl span = + SpanImpl.startSpan( + spanContext, + recordSpanOptions, + SPAN_NAME, + parentSpanId, + startEndHandler, + timestampConverter, + testClock); + Mockito.verify(startEndHandler, Mockito.times(1)).onStart(span); + testClock.advanceTime(Duration.create(0, 7777)); + span.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build()); + Mockito.verify(startEndHandler, Mockito.times(1)).onEnd(span); + SpanData spanData = span.toSpanData(); + assertThat(spanData.getStartTimestamp()).isEqualTo(timestamp); + assertThat(spanData.getStatus()).isEqualTo(Status.CANCELLED); + assertThat(spanData.getEndTimestamp()).isEqualTo(timestamp.addNanos(7777)); + } +} diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TimestampConverterTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TimestampConverterTest.java index fbbb43ade3..8f506fdfe3 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TimestampConverterTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TimestampConverterTest.java @@ -14,20 +14,38 @@ package com.google.instrumentation.trace; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; +import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.Timestamp; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; /** Unit tests for {@link TimestampConverter}. */ @RunWith(JUnit4.class) public class TimestampConverterTest { + private final Timestamp timestamp = Timestamp.create(1234, 5678); + @Mock private Clock mockClock; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + @Test public void convertNanoTime() { - Timestamp timestamp = Timestamp.create(1234, 5678); - TimestampConverter timeConverter = new TimestampConverter(timestamp, 2345); - assertThat(timeConverter.convertNanoTime(1234)).isEqualTo(timestamp.addNanos(-1111)); - assertThat(timeConverter.convertNanoTime(3456)).isEqualTo(timestamp.addNanos(1111)); + when(mockClock.now()).thenReturn(timestamp); + when(mockClock.nowNanos()).thenReturn(1234L); + TimestampConverter timeConverter = TimestampConverter.now(mockClock); + assertThat(timeConverter.convertNanoTime(6234)) + .isEqualTo(Timestamp.create(1234, 10678)); + assertThat(timeConverter.convertNanoTime(1000)) + .isEqualTo(Timestamp.create(1234, 5444)); + assertThat(timeConverter.convertNanoTime(999995556)) + .isEqualTo(Timestamp.create(1235, 0)); } } From 2be3b28a36de4ab87c1b6bccf3b8f66bee29c42e Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Apr 2017 18:12:38 -0700 Subject: [PATCH 0024/1581] Add license information. --- .../instrumentation/trace/TraceComponentTest.java | 13 +++++++++++++ .../instrumentation/trace/TraceComponentImpl.java | 13 +++++++++++++ .../trace/TraceComponentImplTest.java | 13 +++++++++++++ 3 files changed, 39 insertions(+) diff --git a/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java b/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java index f3f631ec21..4f090031ed 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java @@ -1,3 +1,16 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.google.instrumentation.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java index a26b073d18..4379ce9967 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -1,3 +1,16 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.google.instrumentation.trace; /** Implementation of the {@link TraceComponent}. */ diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index cce26bcecf..2597cd22db 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -1,3 +1,16 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.google.instrumentation.trace; import static com.google.common.truth.Truth.assertThat; From 29b10b910b47d542cd0827780b74c7e0844ab87a Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Apr 2017 17:31:37 -0700 Subject: [PATCH 0025/1581] Copy TraceComponentImpl into Android, Java 7, and Java 8 directories. This change will allow TraceComponentImpl to have different implementations for the different Java versions. --- ...tImpl.java => TraceComponentImplBase.java} | 7 ++-- .../trace/TraceComponentImpl.java | 21 +++++++++++ .../trace/TraceComponentImplTest.java | 0 .../trace/TraceComponentImplJava.java | 21 +++++++++++ .../trace/TraceComponentImpl.java | 21 +++++++++++ .../trace/TraceComponentImplTest.java | 36 +++++++++++++++++++ .../trace/TraceComponentImpl.java | 21 +++++++++++ .../trace/TraceComponentImplTest.java | 36 +++++++++++++++++++ 8 files changed, 160 insertions(+), 3 deletions(-) rename core_impl/src/main/java/com/google/instrumentation/trace/{TraceComponentImpl.java => TraceComponentImplBase.java} (91%) create mode 100644 core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java rename {core_impl => core_impl_android}/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java (100%) create mode 100644 core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java create mode 100644 core_impl_java_7/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java create mode 100644 core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java create mode 100644 core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java create mode 100644 core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java similarity index 91% rename from core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java rename to core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java index 4379ce9967..b15e2b410b 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java @@ -14,11 +14,14 @@ package com.google.instrumentation.trace; /** Implementation of the {@link TraceComponent}. */ -public final class TraceComponentImpl extends TraceComponent { +public class TraceComponentImplBase extends TraceComponent { private static final Tracer tracer = Tracer.getNoopTracer(); private static final BinaryPropagationHandler binaryPropagationHandler = BinaryPropagationHandlerImpl.INSTANCE; + TraceComponentImplBase() { + } + @Override public Tracer getTracer() { return tracer; @@ -28,6 +31,4 @@ public Tracer getTracer() { public BinaryPropagationHandler getBinaryPropagationHandler() { return binaryPropagationHandler; } - - public TraceComponentImpl() {} } diff --git a/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java new file mode 100644 index 0000000000..3b966a5385 --- /dev/null +++ b/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -0,0 +1,21 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +/** Android-compatible implementation of the {@link TraceComponent}. */ +public final class TraceComponentImpl extends TraceComponentImplBase { + + public TraceComponentImpl() { + } +} diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java similarity index 100% rename from core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java rename to core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java diff --git a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java new file mode 100644 index 0000000000..4c23477518 --- /dev/null +++ b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java @@ -0,0 +1,21 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +/** Java 7 and 8 implementation of the {@link TraceComponent}. */ +public abstract class TraceComponentImplJava extends TraceComponentImplBase { + + public TraceComponentImplJava() { + } +} diff --git a/core_impl_java_7/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_java_7/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java new file mode 100644 index 0000000000..a17cb71654 --- /dev/null +++ b/core_impl_java_7/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -0,0 +1,21 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +/** Java 7 implementation of the {@link TraceComponent}. */ +public final class TraceComponentImpl extends TraceComponentImplJava { + + public TraceComponentImpl() { + } +} diff --git a/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java new file mode 100644 index 0000000000..2597cd22db --- /dev/null +++ b/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TraceComponentImpl}. */ +@RunWith(JUnit4.class) +public class TraceComponentImplTest { + @Test + public void implementationOfTracer() { + // TODO(bdrutu): Change this when TracerImpl is available. + assertThat(Tracing.getTracer()).isSameAs(Tracer.getNoopTracer()); + } + + @Test + public void implementationOfBinaryPropagationHandler() { + assertThat(Tracing.getBinaryPropagationHandler()) + .isSameAs(BinaryPropagationHandlerImpl.INSTANCE); + } +} diff --git a/core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java new file mode 100644 index 0000000000..7a939c1e62 --- /dev/null +++ b/core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -0,0 +1,21 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +/** Java 8 implementation of the {@link TraceComponent}. */ +public final class TraceComponentImpl extends TraceComponentImplJava { + + public TraceComponentImpl() { + } +} diff --git a/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java new file mode 100644 index 0000000000..2597cd22db --- /dev/null +++ b/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TraceComponentImpl}. */ +@RunWith(JUnit4.class) +public class TraceComponentImplTest { + @Test + public void implementationOfTracer() { + // TODO(bdrutu): Change this when TracerImpl is available. + assertThat(Tracing.getTracer()).isSameAs(Tracer.getNoopTracer()); + } + + @Test + public void implementationOfBinaryPropagationHandler() { + assertThat(Tracing.getBinaryPropagationHandler()) + .isSameAs(BinaryPropagationHandlerImpl.INSTANCE); + } +} From 9996bafdc119f8038801746bfcb57ae3d28ca699 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Apr 2017 18:21:46 -0700 Subject: [PATCH 0026/1581] Add a Clock field to TraceComponent. This is the clock that will be used throughout the tracing implementation. It is exposed so that users can record times, too. --- .../instrumentation/trace/TraceComponent.java | 16 ++++++++++++++++ .../google/instrumentation/trace/Tracing.java | 10 ++++++++++ .../trace/TraceComponentImplBase.java | 11 ++++++++++- .../trace/TraceComponentImpl.java | 3 +++ .../trace/TraceComponentImplJava.java | 5 ++++- .../trace/TraceComponentImpl.java | 3 +++ .../trace/TraceComponentImpl.java | 3 +++ 7 files changed, 49 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java b/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java index e55d1ec0b3..0aac9c54b3 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java @@ -13,6 +13,9 @@ package com.google.instrumentation.trace; +import com.google.instrumentation.common.Clock; +import com.google.instrumentation.internal.MillisClock; + /** * Class that holds the implementation instances for {@link Tracer} and {@link * BinaryPropagationHandler}. @@ -38,6 +41,13 @@ public abstract class TraceComponent { */ public abstract BinaryPropagationHandler getBinaryPropagationHandler(); + /** + * Returns the {@link Clock} with the provided implementation. + * + * @return the {@code Clock} implementation. + */ + public abstract Clock getClock(); + // Disallow external overrides until we define the final API. TraceComponent() {} @@ -61,6 +71,12 @@ public BinaryPropagationHandler getBinaryPropagationHandler() { return BinaryPropagationHandler.getNoopBinaryPropagationHandler(); } + @Override + public Clock getClock() { + // TODO(sebright): Is this the right implementation, or should it return a constant? + return MillisClock.getInstance(); + } + private NoopTraceComponent() {} } } diff --git a/core/src/main/java/com/google/instrumentation/trace/Tracing.java b/core/src/main/java/com/google/instrumentation/trace/Tracing.java index 3a7bae5ce8..f5b0d7fcb4 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Tracing.java +++ b/core/src/main/java/com/google/instrumentation/trace/Tracing.java @@ -14,6 +14,7 @@ package com.google.instrumentation.trace; import com.google.common.annotations.VisibleForTesting; +import com.google.instrumentation.common.Clock; import com.google.instrumentation.internal.Provider; import java.util.logging.Level; import java.util.logging.Logger; @@ -42,6 +43,15 @@ public static BinaryPropagationHandler getBinaryPropagationHandler() { return traceComponent.getBinaryPropagationHandler(); } + /** + * Returns the global {@link Clock}. + * + * @return the global {@code Clock}. + */ + public static Clock getClock() { + return traceComponent.getClock(); + } + // Any provider that may be used for TraceComponent can be added here. @VisibleForTesting static TraceComponent loadTraceComponent(ClassLoader classLoader) { diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java index b15e2b410b..04655c962f 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java @@ -13,13 +13,17 @@ package com.google.instrumentation.trace; +import com.google.instrumentation.common.Clock; + /** Implementation of the {@link TraceComponent}. */ public class TraceComponentImplBase extends TraceComponent { private static final Tracer tracer = Tracer.getNoopTracer(); private static final BinaryPropagationHandler binaryPropagationHandler = BinaryPropagationHandlerImpl.INSTANCE; + private final Clock clock; - TraceComponentImplBase() { + TraceComponentImplBase(Clock clock) { + this.clock = clock; } @Override @@ -31,4 +35,9 @@ public Tracer getTracer() { public BinaryPropagationHandler getBinaryPropagationHandler() { return binaryPropagationHandler; } + + @Override + public final Clock getClock() { + return clock; + } } diff --git a/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java index 3b966a5385..276b19dcbb 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -13,9 +13,12 @@ package com.google.instrumentation.trace; +import com.google.instrumentation.internal.MillisClock; + /** Android-compatible implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplBase { public TraceComponentImpl() { + super(MillisClock.getInstance()); } } diff --git a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java index 4c23477518..da87f05f86 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java @@ -13,9 +13,12 @@ package com.google.instrumentation.trace; +import com.google.instrumentation.common.Clock; + /** Java 7 and 8 implementation of the {@link TraceComponent}. */ public abstract class TraceComponentImplJava extends TraceComponentImplBase { - public TraceComponentImplJava() { + public TraceComponentImplJava(Clock clock) { + super(clock); } } diff --git a/core_impl_java_7/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_java_7/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java index a17cb71654..881ad6f840 100644 --- a/core_impl_java_7/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl_java_7/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -13,9 +13,12 @@ package com.google.instrumentation.trace; +import com.google.instrumentation.internal.MillisClock; + /** Java 7 implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplJava { public TraceComponentImpl() { + super(MillisClock.getInstance()); } } diff --git a/core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java index 7a939c1e62..0f6df78737 100644 --- a/core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -13,9 +13,12 @@ package com.google.instrumentation.trace; +import com.google.instrumentation.internal.InstantClock; + /** Java 8 implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplJava { public TraceComponentImpl() { + super(InstantClock.getInstance()); } } From 55d6b10159ed5fb77f23c3a3f7c08667c3a0ecc3 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Apr 2017 18:58:00 -0700 Subject: [PATCH 0027/1581] Deprecate TimestampFactory in favor of Clock. --- .../instrumentation/common/Timestamp.java | 2 +- .../common/TimestampFactory.java | 43 +++---------------- .../common/TimestampFactoryTest.java | 30 +------------ 3 files changed, 9 insertions(+), 66 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/common/Timestamp.java b/core/src/main/java/com/google/instrumentation/common/Timestamp.java index 070510251d..143f97663b 100644 --- a/core/src/main/java/com/google/instrumentation/common/Timestamp.java +++ b/core/src/main/java/com/google/instrumentation/common/Timestamp.java @@ -19,7 +19,7 @@ * A representation of an instant in time. The instant is the number of nanoseconds after the number * of seconds since the Unix Epoch. * - *

Use {@link TimestampFactory#now} to get the current timestamp since epoch + *

Use {@code Tracing.getClock().now()} to get the current timestamp since epoch * (1970-01-01T00:00:00Z). */ @Immutable diff --git a/core/src/main/java/com/google/instrumentation/common/TimestampFactory.java b/core/src/main/java/com/google/instrumentation/common/TimestampFactory.java index b0a8548677..78d354d79d 100644 --- a/core/src/main/java/com/google/instrumentation/common/TimestampFactory.java +++ b/core/src/main/java/com/google/instrumentation/common/TimestampFactory.java @@ -13,19 +13,16 @@ package com.google.instrumentation.common; -import com.google.common.annotations.VisibleForTesting; -import com.google.instrumentation.internal.Provider; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.annotation.concurrent.Immutable; +import com.google.instrumentation.internal.MillisClock; /** * Factory for {@link Timestamp}. See {@link #now} for how to use this class. + * + * @deprecated Use {@link Clock} instead. */ +@Deprecated public final class TimestampFactory { - private static final Logger logger = Logger.getLogger(TimestampFactory.class.getName()); - private static final Handler HANDLER = - loadTimestampFactoryHandler(Provider.getCorrectClassLoader(Handler.class)); + private static final Clock CLOCK = MillisClock.getInstance(); private TimestampFactory() {} @@ -35,34 +32,6 @@ private TimestampFactory() {} * @return the current instant using the system clock, not null. */ public static Timestamp now() { - return HANDLER.timeNow(); - } - - /** - * Interface to get the current {@link Timestamp}. - */ - interface Handler { - Timestamp timeNow(); - } - - @Immutable - static final class DefaultHandler implements Handler { - @Override - public Timestamp timeNow() { - return Timestamp.fromMillis(System.currentTimeMillis()); - } - } - - @VisibleForTesting - static Handler loadTimestampFactoryHandler(ClassLoader classLoader) { - try { - return Provider.createInstance( - Class.forName( - "com.google.instrumentation.common.TimestampFactoryHandlerImpl", true, classLoader), - Handler.class); - } catch (ClassNotFoundException e) { - logger.log(Level.FINE, "Using default implementation for TimestampFactory$Handler.", e); - } - return new DefaultHandler(); + return CLOCK.now(); } } diff --git a/core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java b/core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java index 66f25199cb..de227d2d0d 100644 --- a/core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java +++ b/core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java @@ -8,7 +8,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@link TimestampFactory}. */ +/** Unit tests for {@code TimestampFactory}. */ @RunWith(JUnit4.class) public class TimestampFactoryTest { private static final int NUM_NANOS_PER_MILLI = 1000 * 1000; @@ -17,6 +17,7 @@ public class TimestampFactoryTest { public ExpectedException thrown = ExpectedException.none(); @Test + @SuppressWarnings("deprecation") public void millisGranularity() { for (int i = 0; i < 1000000; i++) { Timestamp now = TimestampFactory.now(); @@ -24,31 +25,4 @@ public void millisGranularity() { assertThat(now.getNanos() % NUM_NANOS_PER_MILLI).isEqualTo(0); } } - - @Test - public void loadProtoPropagationHandler_UsesProvidedClassLoader() { - final RuntimeException toThrow = new RuntimeException("UseClassLoader"); - thrown.expect(RuntimeException.class); - thrown.expectMessage("UseClassLoader"); - TimestampFactory.loadTimestampFactoryHandler(new ClassLoader() { - @Override - public Class loadClass(String name) { - throw toThrow; - } - }); - } - - @Test - public void loadProtoPropagationHandler_IgnoresMissingClasses() { - assertThat(TimestampFactory - .loadTimestampFactoryHandler(new ClassLoader() { - @Override - public Class loadClass(String name) throws ClassNotFoundException { - throw new ClassNotFoundException(); - } - }) - .getClass() - .getName()) - .isEqualTo("com.google.instrumentation.common.TimestampFactory$DefaultHandler"); - } } From 0728715c392379867c5d4398bd3b01da8c28a6fe Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 1 May 2017 13:07:23 -0700 Subject: [PATCH 0028/1581] Delete StatsCurrentContext.java, which was unused. The class will need to be rewritten to use io.grpc.Context. --- .../stats/StatsCurrentContext.java | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 core_impl/src/main/java/com/google/instrumentation/stats/StatsCurrentContext.java diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsCurrentContext.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsCurrentContext.java deleted file mode 100644 index 53b138b219..0000000000 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsCurrentContext.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.stats; - -/** - * Native implementation of thread-local {@link StatsContext}. - */ -class StatsCurrentContext { - static final ThreadLocal contexts = new ThreadLocal() { - @Override - protected StatsContextImpl initialValue() { - return StatsContextFactoryImpl.DEFAULT; - } - }; - - public static void set(StatsContextImpl context) { - contexts.set(context); - } - - public static StatsContextImpl get() { - return contexts.get(); - } -} From f7094f3441c9739a6d2843240646264d795c63fe Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 1 May 2017 13:11:27 -0700 Subject: [PATCH 0029/1581] Implement StatsContext.record(...) using StatsManagerImplBase.record(...). This change requires StatsContextImpl to store a reference to the StatsManagerImplBase that is used to record the stats. It is a temporary change that is only needed until we add the new tagging API. This commit also updates the StatsContext tests so that they only record stats for the one supported view. --- .../stats/StatsContextFactoryImpl.java | 17 +- .../stats/StatsContextImpl.java | 14 +- .../stats/StatsManagerImplBase.java | 19 ++- .../stats/StatsSerializer.java | 5 +- .../stats/StatsContextFactoryTest.java | 16 +- .../stats/StatsContextTest.java | 156 ++++++++++++------ .../stats/StatsManagerImplTest.java | 19 ++- 7 files changed, 163 insertions(+), 83 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java index e4a39be0b8..0c23714d3f 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java @@ -15,13 +15,20 @@ import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; +import java.util.Collections; /** * Native Implementation of {@link StatsContextFactory}. */ final class StatsContextFactoryImpl extends StatsContextFactory { - static final StatsContextImpl DEFAULT = new StatsContextImpl(new HashMap(0)); + private final StatsManagerImplBase statsManager; + private final StatsContextImpl defaultStatsContext; + + StatsContextFactoryImpl(StatsManagerImplBase statsManager) { + this.statsManager = statsManager; + this.defaultStatsContext = + new StatsContextImpl(statsManager, Collections.emptyMap()); + } /** * Deserializes a {@link StatsContextImpl} from a serialized {@code CensusContextProto}. @@ -30,11 +37,11 @@ final class StatsContextFactoryImpl extends StatsContextFactory { */ @Override public StatsContextImpl deserialize(InputStream input) throws IOException { - return StatsSerializer.deserialize(input); + return StatsSerializer.deserialize(statsManager, input); } @Override - public StatsContext getDefault() { - return DEFAULT; + public StatsContextImpl getDefault() { + return defaultStatsContext; } } diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java index 338d56f4f9..3b87ec3fd9 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java @@ -23,19 +23,22 @@ * Native Implementation of {@link StatsContext}. */ final class StatsContextImpl extends StatsContext { + private final StatsManagerImplBase statsManager; final Map tags; - StatsContextImpl(Map tags) { + StatsContextImpl(StatsManagerImplBase statsManager, Map tags) { + this.statsManager = statsManager; this.tags = tags; } @Override public Builder builder() { - return new Builder(tags); + return new Builder(statsManager, tags); } @Override public StatsContextImpl record(MeasurementMap stats) { + statsManager.record(this, stats); return this; } @@ -65,9 +68,11 @@ public String toString() { } private static final class Builder extends StatsContext.Builder { + private final StatsManagerImplBase statsManager; private final HashMap tags; - private Builder(Map tags) { + private Builder(StatsManagerImplBase statsManager, Map tags) { + this.statsManager = statsManager; this.tags = new HashMap(tags); } @@ -79,7 +84,8 @@ public Builder set(TagKey key, TagValue value) { @Override public StatsContext build() { - return new StatsContextImpl(Collections.unmodifiableMap(new HashMap(tags))); + return new StatsContextImpl( + statsManager, Collections.unmodifiableMap(new HashMap(tags))); } } } diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java index b1245c49a6..8c1eee7cec 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java @@ -24,21 +24,24 @@ /** * Native Implementation of {@link StatsManager}. */ -public class StatsManagerImplBase extends StatsManager { +class StatsManagerImplBase extends StatsManager { private final EventQueue queue; // clock used throughout the stats implementation private final Clock clock; + private final MeasurementDescriptorToViewMap measurementDescriptorToViewMap = + new MeasurementDescriptorToViewMap(); + + // The StatsContextFactoryImpl is lazily initialized because it references "this" and cannot be + // created in the constructor. Multiple initializations are okay. + private volatile StatsContextFactoryImpl statsContextFactory; + StatsManagerImplBase(EventQueue queue, Clock clock) { this.queue = queue; this.clock = clock; } - private final MeasurementDescriptorToViewMap measurementDescriptorToViewMap = - new MeasurementDescriptorToViewMap(); - private final StatsContextFactoryImpl statsContextFactory = new StatsContextFactoryImpl(); - @Override public void registerView(ViewDescriptor viewDescriptor) { // We are using a preset measurement RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY @@ -76,7 +79,11 @@ public View getView(ViewDescriptor viewDescriptor) { @Override StatsContextFactoryImpl getStatsContextFactory() { - return statsContextFactory; + StatsContextFactoryImpl factory = statsContextFactory; + if (factory == null) { + statsContextFactory = factory = new StatsContextFactoryImpl(this); + } + return factory; } /** diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java index 59798210ac..ffd7ea741c 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java @@ -89,7 +89,8 @@ static void serialize(StatsContextImpl context, OutputStream output) throws IOEx // Deserializes input to StatsContext based on the binary format standard. // The encoded tags are of the form: - static StatsContextImpl deserialize(InputStream input) throws IOException { + static StatsContextImpl deserialize(StatsManagerImplBase statsManager, InputStream input) + throws IOException { try { byte[] bytes = ByteStreams.toByteArray(input); HashMap tags = new HashMap(); @@ -122,7 +123,7 @@ static StatsContextImpl deserialize(InputStream input) throws IOException { throw new IOException("Unsupported tag value type."); } } - return new StatsContextImpl(tags); + return new StatsContextImpl(statsManager, tags); } catch (BufferUnderflowException exn) { throw new IOException(exn.toString()); // byte array format error. } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java index ce1396f696..884bcddf83 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java @@ -15,6 +15,8 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.instrumentation.common.SimpleEventQueue; +import com.google.instrumentation.internal.TestClock; import com.google.io.base.VarInt; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -35,7 +37,9 @@ public class StatsContextFactoryTest { private static final String VALUE_STRING = "String"; private static final int VALUE_INT = 10; - private static final StatsContextFactory FACTORY = new StatsContextFactoryImpl(); + private final StatsManagerImplBase statsManager = + new StatsManagerImplBase(new SimpleEventQueue(), TestClock.create()); + private final StatsContextFactory factory = new StatsContextFactoryImpl(statsManager); private final HashMap sampleTags = new HashMap(); public StatsContextFactoryTest() { @@ -55,7 +59,7 @@ public void testVersionAndValueTypeConstants() { @Test public void testDeserializeNoTags() throws Exception { - StatsContext expected = FACTORY.getDefault(); + StatsContext expected = factory.getDefault(); StatsContext actual = testDeserialize( new ByteArrayInputStream( new byte[]{StatsSerializer.VERSION_ID})); // One byte that represents Version ID. @@ -69,7 +73,7 @@ public void testDeserializeEmptyByteArrayThrowException() throws Exception { @Test public void testDeserializeValueTypeString() throws Exception { - StatsContext expected = new StatsContextImpl(sampleTags); + StatsContext expected = new StatsContextImpl(statsManager, sampleTags); StatsContext actual = testDeserialize( constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_STRING)); assertThat(actual).isEqualTo(expected); @@ -78,7 +82,7 @@ public void testDeserializeValueTypeString() throws Exception { @Test public void testDeserializeMultipleString() throws Exception { sampleTags.put(TagKey.create("Key2"), TagValue.create("String2")); - StatsContext expected = new StatsContextImpl(sampleTags); + StatsContext expected = new StatsContextImpl(statsManager, sampleTags); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byteArrayOutputStream.write(StatsSerializer.VERSION_ID); @@ -127,9 +131,9 @@ public void testDeserializeWrongVersionId() throws Exception { testDeserialize(new ByteArrayInputStream(new byte[]{(byte) (StatsSerializer.VERSION_ID + 1)})); } - private static StatsContext testDeserialize(InputStream inputStream) + private StatsContext testDeserialize(InputStream inputStream) throws IOException, IOException { - return FACTORY.deserialize(inputStream); + return factory.deserialize(inputStream); } /* diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java index 8e467ee050..2a013a7a7b 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java @@ -14,15 +14,22 @@ package com.google.instrumentation.stats; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; import com.google.common.collect.Collections2; import com.google.common.testing.EqualsTester; +import com.google.instrumentation.common.Function; +import com.google.instrumentation.common.SimpleEventQueue; +import com.google.instrumentation.internal.TestClock; +import com.google.instrumentation.stats.View.DistributionView; +import com.google.instrumentation.stats.View.IntervalView; import com.google.io.base.VarInt; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -30,22 +37,25 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link StatsContext}. - */ +/** Tests for {@link StatsContext}. */ @RunWith(JUnit4.class) public class StatsContextTest { - private static final StatsContextFactory FACTORY = new StatsContextFactoryImpl(); - private static final StatsContext DEFAULT = StatsContextFactoryImpl.DEFAULT; - - private static final MeasurementDescriptor[] StatsMeasurementDescriptors = { - RpcMeasurementConstants.RPC_CLIENT_REQUEST_BYTES, - RpcMeasurementConstants.RPC_CLIENT_RESPONSE_BYTES, - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, - RpcMeasurementConstants.RPC_SERVER_REQUEST_BYTES, - RpcMeasurementConstants.RPC_SERVER_RESPONSE_BYTES, - RpcMeasurementConstants.RPC_SERVER_SERVER_LATENCY - }; + private final StatsManagerImplBase statsManager = + new StatsManagerImplBase(new SimpleEventQueue(), TestClock.create()); + private final StatsContextFactory factory = statsManager.getStatsContextFactory(); + private final StatsContext defaultStatsContext = factory.getDefault(); + + // TODO(sebright): Test more views once they are supported. + private static final List STATS_MEASUREMENT_DESCRIPTORS = + Collections.unmodifiableList( + Arrays.asList( +// RpcMeasurementConstants.RPC_CLIENT_REQUEST_BYTES, +// RpcMeasurementConstants.RPC_CLIENT_RESPONSE_BYTES, + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY +// RpcMeasurementConstants.RPC_SERVER_REQUEST_BYTES, +// RpcMeasurementConstants.RPC_SERVER_RESPONSE_BYTES, +// RpcMeasurementConstants.RPC_SERVER_SERVER_LATENCY + )); private static final int VERSION_ID = 0; private static final int VALUE_TYPE_STRING = 0; @@ -74,53 +84,94 @@ public class StatsContextTest { @Test public void testWith() { - assertThat(DEFAULT.builder().set(K1, V1).build()).isEqualTo(DEFAULT.with(K1, V1)); + assertThat(defaultStatsContext.builder().set(K1, V1).build()) + .isEqualTo(defaultStatsContext.with(K1, V1)); - assertThat(DEFAULT.builder().set(K1, V1).set(K2, V2).build()) - .isEqualTo(DEFAULT.with(K1, V1, K2, V2)); + assertThat(defaultStatsContext.builder().set(K1, V1).set(K2, V2).build()) + .isEqualTo(defaultStatsContext.with(K1, V1, K2, V2)); - assertThat(DEFAULT.builder().set(K1, V1).set(K2, V2).set(K3, V3).build()) - .isEqualTo(DEFAULT.with(K1, V1, K2, V2, K3, V3)); + assertThat(defaultStatsContext.builder().set(K1, V1).set(K2, V2).set(K3, V3).build()) + .isEqualTo(defaultStatsContext.with(K1, V1, K2, V2, K3, V3)); } @Test public void testWithComposed() { - StatsContext context1 = DEFAULT.with(K1, V1); - assertThat(DEFAULT.builder().set(K1, V1).build()).isEqualTo(context1); + StatsContext context1 = defaultStatsContext.with(K1, V1); + assertThat(defaultStatsContext.builder().set(K1, V1).build()).isEqualTo(context1); StatsContext context2 = context1.with(K1, V10, K2, V2); - assertThat(DEFAULT.with(K1, V10, K2, V2)).isEqualTo(context2); + assertThat(defaultStatsContext.with(K1, V10, K2, V2)).isEqualTo(context2); StatsContext context3 = context2.with(K1, V100, K2, V20, K3, V3); - assertThat(DEFAULT.with(K1, V100, K2, V20, K3, V3)).isEqualTo(context3); + assertThat(defaultStatsContext.with(K1, V100, K2, V20, K3, V3)).isEqualTo(context3); StatsContext context4 = context3.with(K3, V30, K4, V4); - assertThat(DEFAULT.builder().set(K1, V100).set(K2, V20).set(K3, V30).set(K4, V4).build()) + assertThat( + defaultStatsContext + .builder() + .set(K1, V100) + .set(K2, V20) + .set(K3, V30) + .set(K4, V4) + .build()) .isEqualTo(context4); } - @Test public void testRecordEachMeasurement() { - StatsContext context = DEFAULT.with(K1, V1); + statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + StatsContext context = defaultStatsContext.with(K1, V1); double value = 44.0; - for (MeasurementDescriptor descriptor : StatsMeasurementDescriptors) { + for (MeasurementDescriptor descriptor : STATS_MEASUREMENT_DESCRIPTORS) { MeasurementMap measurements = MeasurementMap.of(descriptor, value); context.record(measurements); - //verify(context.context).record(measurements); + // TODO(sebright): Check the values in the view. + View view = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + view.match( + new Function() { + @Override + public Void apply(DistributionView view) { + assertThat(view.getDistributionAggregations()).hasSize(1); + return null; + } + }, + new Function() { + @Override + public Void apply(IntervalView view) { + fail("Expected a DistributionView"); + return null; + } + }); value++; } } @Test public void testRecordAllMeasurements() { - StatsContext context = DEFAULT.with(K1, V1); + statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + StatsContext context = defaultStatsContext.with(K1, V1); double value = 44.0; MeasurementMap.Builder builder = MeasurementMap.builder(); - for (MeasurementDescriptor descriptor : StatsMeasurementDescriptors) { + for (MeasurementDescriptor descriptor : STATS_MEASUREMENT_DESCRIPTORS) { MeasurementMap measurements = builder.put(descriptor, value).build(); context.record(measurements); - //verify(context.context).record(measurements); + // TODO(sebright): Check the values in the view. + View view = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + view.match( + new Function() { + @Override + public Void apply(DistributionView view) { + assertThat(view.getDistributionAggregations()).hasSize(1); + return null; + } + }, + new Function() { + @Override + public Void apply(IntervalView view) { + fail("Expected a DistributionView"); + return null; + } + }); value++; } } @@ -142,12 +193,12 @@ public void testSerializeWithMultiStringTags() throws Exception { @Test public void testRoundtripSerialization() throws Exception { - testRoundtripSerialization(DEFAULT.builder().build()); - testRoundtripSerialization(DEFAULT.with(K1, V1)); - testRoundtripSerialization(DEFAULT.with(K1, V1, K2, V2, K3, V3)); - testRoundtripSerialization(DEFAULT.with(K1, V_EMPTY)); - testRoundtripSerialization(DEFAULT.with(K_EMPTY, V1)); - testRoundtripSerialization(DEFAULT.with(K_EMPTY, V_EMPTY)); + testRoundtripSerialization(defaultStatsContext.builder().build()); + testRoundtripSerialization(defaultStatsContext.with(K1, V1)); + testRoundtripSerialization(defaultStatsContext.with(K1, V1, K2, V2, K3, V3)); + testRoundtripSerialization(defaultStatsContext.with(K1, V_EMPTY)); + testRoundtripSerialization(defaultStatsContext.with(K_EMPTY, V1)); + testRoundtripSerialization(defaultStatsContext.with(K_EMPTY, V_EMPTY)); } // Tests for Object overrides. @@ -155,27 +206,30 @@ public void testRoundtripSerialization() throws Exception { @Test public void testEquals() { new EqualsTester() - .addEqualityGroup(DEFAULT, DEFAULT) - .addEqualityGroup(DEFAULT.with(K1, V1), DEFAULT.with(K1, V1)) + .addEqualityGroup(defaultStatsContext, defaultStatsContext) + .addEqualityGroup(defaultStatsContext.with(K1, V1), defaultStatsContext.with(K1, V1)) .addEqualityGroup( - DEFAULT.with(K1, V1, K2, V2), - DEFAULT.with(K1, V1, K2, V2), - DEFAULT.with(K2, V2, K1, V1)) - .addEqualityGroup(DEFAULT.with(K10, V1)) - .addEqualityGroup(DEFAULT.with(K1, V10)) + defaultStatsContext.with(K1, V1, K2, V2), + defaultStatsContext.with(K1, V1, K2, V2), + defaultStatsContext.with(K2, V2, K1, V1)) + .addEqualityGroup(defaultStatsContext.with(K10, V1)) + .addEqualityGroup(defaultStatsContext.with(K1, V10)) .addEqualityGroup("foo") .testEquals(); } @Test public void testToString() { - assertThat(DEFAULT.with(K1, V1).toString()).isEqualTo(DEFAULT.with(K1, V1).toString()); - assertThat(DEFAULT.with(K10, V1).toString()).isNotEqualTo(DEFAULT.with(K1, V1).toString()); - assertThat(DEFAULT.with(K1, V10).toString()).isNotEqualTo(DEFAULT.with(K1, V1).toString()); + assertThat(defaultStatsContext.with(K1, V1).toString()) + .isEqualTo(defaultStatsContext.with(K1, V1).toString()); + assertThat(defaultStatsContext.with(K10, V1).toString()) + .isNotEqualTo(defaultStatsContext.with(K1, V1).toString()); + assertThat(defaultStatsContext.with(K1, V10).toString()) + .isNotEqualTo(defaultStatsContext.with(K1, V1).toString()); } - private static void testSerialize(Tag... tags) throws IOException { - StatsContext.Builder builder = DEFAULT.builder(); + private void testSerialize(Tag... tags) throws IOException { + StatsContext.Builder builder = defaultStatsContext.builder(); for (Tag tag : tags) { builder.set(tag.getKey(), tag.getValue()); } @@ -199,11 +253,11 @@ private static void testSerialize(Tag... tags) throws IOException { assertThat(possibleOutputs).contains(actual.toString()); } - private static void testRoundtripSerialization(StatsContext expected) throws Exception { + private void testRoundtripSerialization(StatsContext expected) throws Exception { ByteArrayOutputStream output = new ByteArrayOutputStream(); expected.serialize(output); ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); - StatsContext actual = FACTORY.deserialize(input); + StatsContext actual = factory.deserialize(input); assertThat(actual).isEqualTo(expected); } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 857c909ab3..396f43ced3 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -45,17 +45,18 @@ public class StatsManagerImplTest { private static final TagKey wrongTagKey2 = TagKey.create("Another wrong Tag Key"); private static final TagValue tagValue1 = TagValue.create("some client method"); private static final TagValue tagValue2 = TagValue.create("some other client method"); - private static final StatsContextImpl oneTag = - new StatsContextImpl(ImmutableMap.of(tagKey, tagValue1)); - private static final StatsContextImpl anotherTag = - new StatsContextImpl(ImmutableMap.of(tagKey, tagValue2)); - private static final StatsContextImpl wrongTag = - new StatsContextImpl(ImmutableMap.of(wrongTagKey, tagValue1)); - private static final StatsContextImpl wrongTag2 = - new StatsContextImpl(ImmutableMap.of(wrongTagKey, tagValue1, wrongTagKey2, tagValue2)); private final TestClock clock = TestClock.create(); private final StatsManagerImplBase statsManager = new StatsManagerImplBase(new SimpleEventQueue(), clock); + private final StatsContextImpl oneTag = + new StatsContextImpl(statsManager, ImmutableMap.of(tagKey, tagValue1)); + private final StatsContextImpl anotherTag = + new StatsContextImpl(statsManager, ImmutableMap.of(tagKey, tagValue2)); + private final StatsContextImpl wrongTag = + new StatsContextImpl(statsManager, ImmutableMap.of(wrongTagKey, tagValue1)); + private final StatsContextImpl wrongTag2 = + new StatsContextImpl( + statsManager, ImmutableMap.of(wrongTagKey, tagValue1, wrongTagKey2, tagValue2)); @Test public void testRegisterAndGetView() throws Exception { @@ -185,7 +186,7 @@ public void testRecordWithoutRegisteringView() { public void testRecordWithEmptyStatsContext() { statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); // DEFAULT doesn't have tags. Should have TagKey "method" as defined in RpcViewConstants. - statsManager.record(StatsContextFactoryImpl.DEFAULT, MeasurementMap.of( + statsManager.record(statsManager.getStatsContextFactory().getDefault(), MeasurementMap.of( RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10.0)); DistributionView view = (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); From 93935982176b1d311af02b16238d82405668f5bb Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 1 May 2017 14:03:22 -0700 Subject: [PATCH 0030/1581] Use @link in TimestampFactoryTest.java Javadoc. --- .../google/instrumentation/common/TimestampFactoryTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java b/core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java index de227d2d0d..1b4cc9e64e 100644 --- a/core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java +++ b/core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java @@ -8,7 +8,8 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@code TimestampFactory}. */ +/** Unit tests for {@link TimestampFactory}. */ +@SuppressWarnings("javadoc") @RunWith(JUnit4.class) public class TimestampFactoryTest { private static final int NUM_NANOS_PER_MILLI = 1000 * 1000; From 16fc887170a3a0e890bc68d42e7aeac55a59b92a Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 1 May 2017 14:08:10 -0700 Subject: [PATCH 0031/1581] Add ZeroTimeClock for no-op TraceComponent. --- .../internal/ZeroTimeClock.java | 48 +++++++++++++++++++ .../instrumentation/trace/TraceComponent.java | 5 +- .../trace/TraceComponentTest.java | 6 +++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/com/google/instrumentation/internal/ZeroTimeClock.java diff --git a/core/src/main/java/com/google/instrumentation/internal/ZeroTimeClock.java b/core/src/main/java/com/google/instrumentation/internal/ZeroTimeClock.java new file mode 100644 index 0000000000..1d53a1e72c --- /dev/null +++ b/core/src/main/java/com/google/instrumentation/internal/ZeroTimeClock.java @@ -0,0 +1,48 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.internal; + +import com.google.instrumentation.common.Clock; +import com.google.instrumentation.common.Timestamp; +import javax.annotation.concurrent.Immutable; + +/** + * A {@link Clock} that always returns 0. + */ +@Immutable +public final class ZeroTimeClock extends Clock { + private static final ZeroTimeClock INSTANCE = new ZeroTimeClock(); + private static final Timestamp ZERO_TIMESTAMP = Timestamp.create(0, 0); + + private ZeroTimeClock() {} + + /** + * Returns a {@code ZeroTimeClock}. + * + * @return a {@code ZeroTimeClock}. + */ + public static ZeroTimeClock getInstance() { + return INSTANCE; + } + + @Override + public Timestamp now() { + return ZERO_TIMESTAMP; + } + + @Override + public long nowNanos() { + return 0; + } +} diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java b/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java index 0aac9c54b3..b00b6cf6e4 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java @@ -14,7 +14,7 @@ package com.google.instrumentation.trace; import com.google.instrumentation.common.Clock; -import com.google.instrumentation.internal.MillisClock; +import com.google.instrumentation.internal.ZeroTimeClock; /** * Class that holds the implementation instances for {@link Tracer} and {@link @@ -73,8 +73,7 @@ public BinaryPropagationHandler getBinaryPropagationHandler() { @Override public Clock getClock() { - // TODO(sebright): Is this the right implementation, or should it return a constant? - return MillisClock.getInstance(); + return ZeroTimeClock.getInstance(); } private NoopTraceComponent() {} diff --git a/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java b/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java index 4f090031ed..d7510d4bc1 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.instrumentation.internal.ZeroTimeClock; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -32,4 +33,9 @@ public void defaultBinaryPropagationHandler() { assertThat(TraceComponent.getNoopTraceComponent().getBinaryPropagationHandler()) .isSameAs(BinaryPropagationHandler.getNoopBinaryPropagationHandler()); } + + @Test + public void defaultClock() { + assertThat(TraceComponent.getNoopTraceComponent().getClock()).isInstanceOf(ZeroTimeClock.class); + } } From efbada5056659a78cc32cc964fcd3743518be399 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 1 May 2017 14:11:38 -0700 Subject: [PATCH 0032/1581] Add tests for TraceComponentImpl Clock implementations. --- .../instrumentation/trace/TraceComponentImplTest.java | 6 ++++++ .../instrumentation/trace/TraceComponentImplTest.java | 6 ++++++ .../instrumentation/trace/TraceComponentImplTest.java | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index 2597cd22db..814d10a0cb 100644 --- a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.instrumentation.internal.MillisClock; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -33,4 +34,9 @@ public void implementationOfBinaryPropagationHandler() { assertThat(Tracing.getBinaryPropagationHandler()) .isSameAs(BinaryPropagationHandlerImpl.INSTANCE); } + + @Test + public void implementationOfClock() { + assertThat(Tracing.getClock()).isInstanceOf(MillisClock.class); + } } diff --git a/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index 2597cd22db..814d10a0cb 100644 --- a/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.instrumentation.internal.MillisClock; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -33,4 +34,9 @@ public void implementationOfBinaryPropagationHandler() { assertThat(Tracing.getBinaryPropagationHandler()) .isSameAs(BinaryPropagationHandlerImpl.INSTANCE); } + + @Test + public void implementationOfClock() { + assertThat(Tracing.getClock()).isInstanceOf(MillisClock.class); + } } diff --git a/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index 2597cd22db..0e426e1a65 100644 --- a/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.instrumentation.internal.InstantClock; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -33,4 +34,9 @@ public void implementationOfBinaryPropagationHandler() { assertThat(Tracing.getBinaryPropagationHandler()) .isSameAs(BinaryPropagationHandlerImpl.INSTANCE); } + + @Test + public void implementationOfClock() { + assertThat(Tracing.getClock()).isInstanceOf(InstantClock.class); + } } From a49204e3e0f8ced1209628326f117f5c42dcb36d Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 1 May 2017 15:14:05 -0700 Subject: [PATCH 0033/1581] Check for nulls. --- .../instrumentation/stats/StatsContextFactoryImpl.java | 3 ++- .../com/google/instrumentation/stats/StatsContextImpl.java | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java index 0c23714d3f..fe528875b8 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java @@ -13,6 +13,7 @@ package com.google.instrumentation.stats; +import com.google.common.base.Preconditions; import java.io.IOException; import java.io.InputStream; import java.util.Collections; @@ -25,7 +26,7 @@ final class StatsContextFactoryImpl extends StatsContextFactory { private final StatsContextImpl defaultStatsContext; StatsContextFactoryImpl(StatsManagerImplBase statsManager) { - this.statsManager = statsManager; + this.statsManager = Preconditions.checkNotNull(statsManager); this.defaultStatsContext = new StatsContextImpl(statsManager, Collections.emptyMap()); } diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java index 3b87ec3fd9..d13cd97cd3 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java @@ -13,6 +13,7 @@ package com.google.instrumentation.stats; +import com.google.common.base.Preconditions; import java.io.IOException; import java.io.OutputStream; import java.util.Collections; @@ -27,8 +28,8 @@ final class StatsContextImpl extends StatsContext { final Map tags; StatsContextImpl(StatsManagerImplBase statsManager, Map tags) { - this.statsManager = statsManager; - this.tags = tags; + this.statsManager = Preconditions.checkNotNull(statsManager); + this.tags = Preconditions.checkNotNull(tags); } @Override From 85b702f52b220bc095a251f2f4162b324b72ba28 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 1 May 2017 15:14:05 -0700 Subject: [PATCH 0034/1581] Simplify "record" tests in StatsContextTest. Stats recording is already tested in StatsManagerImplTest, so StatsContextTest only needs to check that StatsContext.record(...) is calling StatsManagerImplBase.record(...) correctly. --- .../stats/StatsContextTest.java | 117 ++++++++---------- 1 file changed, 49 insertions(+), 68 deletions(-) diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java index 2a013a7a7b..a54f786ab0 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -40,23 +39,13 @@ /** Tests for {@link StatsContext}. */ @RunWith(JUnit4.class) public class StatsContextTest { + private static final double TOLERANCE = 1e-6; + private final StatsManagerImplBase statsManager = new StatsManagerImplBase(new SimpleEventQueue(), TestClock.create()); private final StatsContextFactory factory = statsManager.getStatsContextFactory(); private final StatsContext defaultStatsContext = factory.getDefault(); - // TODO(sebright): Test more views once they are supported. - private static final List STATS_MEASUREMENT_DESCRIPTORS = - Collections.unmodifiableList( - Arrays.asList( -// RpcMeasurementConstants.RPC_CLIENT_REQUEST_BYTES, -// RpcMeasurementConstants.RPC_CLIENT_RESPONSE_BYTES, - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY -// RpcMeasurementConstants.RPC_SERVER_REQUEST_BYTES, -// RpcMeasurementConstants.RPC_SERVER_RESPONSE_BYTES, -// RpcMeasurementConstants.RPC_SERVER_SERVER_LATENCY - )); - private static final int VERSION_ID = 0; private static final int VALUE_TYPE_STRING = 0; @@ -117,63 +106,55 @@ public void testWithComposed() { .isEqualTo(context4); } + // The main tests for stats recording are in StatsManagerImplTest. @Test - public void testRecordEachMeasurement() { - statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - StatsContext context = defaultStatsContext.with(K1, V1); - double value = 44.0; - for (MeasurementDescriptor descriptor : STATS_MEASUREMENT_DESCRIPTORS) { - MeasurementMap measurements = MeasurementMap.of(descriptor, value); - context.record(measurements); - // TODO(sebright): Check the values in the view. - View view = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - view.match( - new Function() { - @Override - public Void apply(DistributionView view) { - assertThat(view.getDistributionAggregations()).hasSize(1); - return null; - } - }, - new Function() { - @Override - public Void apply(IntervalView view) { - fail("Expected a DistributionView"); - return null; - } - }); - value++; - } - } - - @Test - public void testRecordAllMeasurements() { + public void testRecord() { statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - StatsContext context = defaultStatsContext.with(K1, V1); - double value = 44.0; - MeasurementMap.Builder builder = MeasurementMap.builder(); - for (MeasurementDescriptor descriptor : STATS_MEASUREMENT_DESCRIPTORS) { - MeasurementMap measurements = builder.put(descriptor, value).build(); - context.record(measurements); - // TODO(sebright): Check the values in the view. - View view = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - view.match( - new Function() { - @Override - public Void apply(DistributionView view) { - assertThat(view.getDistributionAggregations()).hasSize(1); - return null; - } - }, - new Function() { - @Override - public Void apply(IntervalView view) { - fail("Expected a DistributionView"); - return null; - } - }); - value++; - } + View beforeView = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + beforeView.match( + new Function() { + @Override + public Void apply(DistributionView view) { + assertThat(view.getDistributionAggregations()).isEmpty(); + return null; + } + }, + new Function() { + @Override + public Void apply(IntervalView view) { + fail("Expected a DistributionView"); + return null; + } + }); + StatsContext context = + defaultStatsContext.with( + RpcMeasurementConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); + MeasurementMap measurements = + MeasurementMap.of(RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1); + context.record(measurements); + View afterView = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + afterView.match( + new Function() { + @Override + public Void apply(DistributionView view) { + assertThat(view.getDistributionAggregations()).hasSize(1); + DistributionAggregation agg = view.getDistributionAggregations().get(0); + assertThat(agg.getTags()) + .containsExactly( + Tag.create( + RpcMeasurementConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod"))); + assertThat(agg.getCount()).isEqualTo(1); + assertThat(agg.getMean()).isWithin(TOLERANCE).of(5.1); + return null; + } + }, + new Function() { + @Override + public Void apply(IntervalView view) { + fail("Expected a DistributionView"); + return null; + } + }); } @Test From c8e525b5b00d553a357092817beeb241813a8073 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 1 May 2017 17:38:21 -0700 Subject: [PATCH 0035/1581] Improve a comment. --- .../google/instrumentation/trace/TraceComponentImplBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java index 04655c962f..6f72d4175e 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java @@ -15,7 +15,7 @@ import com.google.instrumentation.common.Clock; -/** Implementation of the {@link TraceComponent}. */ +/** Base implementation of the {@link TraceComponent}. */ public class TraceComponentImplBase extends TraceComponent { private static final Tracer tracer = Tracer.getNoopTracer(); private static final BinaryPropagationHandler binaryPropagationHandler = From 9aa5314d51dfbdff5977e3e090d3a3d3a8f321c5 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 1 May 2017 19:41:34 -0700 Subject: [PATCH 0036/1581] Add all the informations that we have in the Span to the SpanData. (#270) * Add all the informations that we have in the Span to the SpanData. --- .../instrumentation/trace/SpanData.java | 180 ++++++++++++++++-- .../instrumentation/trace/SpanImpl.java | 21 +- .../instrumentation/trace/TimedEvent.java | 76 -------- .../instrumentation/trace/SpanDataTest.java | 111 ++++++++--- .../instrumentation/trace/TimedEventTest.java | 62 ------ 5 files changed, 258 insertions(+), 192 deletions(-) delete mode 100644 core_impl/src/main/java/com/google/instrumentation/trace/TimedEvent.java delete mode 100644 core_impl/src/test/java/com/google/instrumentation/trace/TimedEventTest.java diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanData.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanData.java index 62118abc4a..ce1a7a8485 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanData.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanData.java @@ -13,6 +13,8 @@ package com.google.instrumentation.trace; +import static com.google.common.base.Preconditions.checkNotNull; + import com.google.auto.value.AutoValue; import com.google.instrumentation.common.Timestamp; import java.util.ArrayList; @@ -51,10 +53,10 @@ public static SpanData create( @Nullable SpanId parentSpanId, String displayName, Timestamp startTimestamp, - Map attributes, - List> annotations, - List> networkEvents, - List links, + Attributes attributes, + TimedEvents annotations, + TimedEvents networkEvents, + Links links, @Nullable Status status, @Nullable Timestamp endTimestamp) { return new AutoValue_SpanData( @@ -62,10 +64,10 @@ public static SpanData create( parentSpanId, displayName, startTimestamp, - Collections.unmodifiableMap(new HashMap(attributes)), - Collections.unmodifiableList(new ArrayList>(annotations)), - Collections.unmodifiableList(new ArrayList>(networkEvents)), - Collections.unmodifiableList(new ArrayList(links)), + attributes, + annotations, + networkEvents, + links, status, endTimestamp); } @@ -100,32 +102,32 @@ public static SpanData create( public abstract Timestamp getStartTimestamp(); /** - * Returns the set of attributes recorded for this {@code Span}. + * Returns the attributes recorded for this {@code Span}. * - * @return the set of attributes recorded for this {@code Span}. + * @return the attributes recorded for this {@code Span}. */ - public abstract Map getAttributes(); + public abstract Attributes getAttributes(); /** - * Returns the list of {@code Annotation}s recorded for this {@code Span}. + * Returns the annotations recorded for this {@code Span}. * - * @return the list of {@code Annotation}s recorded for this {@code Span}. + * @return the annotations recorded for this {@code Span}. */ - public abstract List> getAnnotations(); + public abstract TimedEvents getAnnotations(); /** - * Returns the list of {@code NetworkEvent}s recorded for this {@code Span}. + * Returns network events recorded for this {@code Span}. * - * @return the list of {@code NetworkEvent}s recorded for this {@code Span}. + * @return network events recorded for this {@code Span}. */ - public abstract List> getNetworkEvents(); + public abstract TimedEvents getNetworkEvents(); /** - * Returns the list of {@code Link}s recorded for this {@code Span}. + * Returns links recorded for this {@code Span}. * - * @return the list of {@code Link}s recorded for this {@code Span}. + * @return links recorded for this {@code Span}. */ - public abstract List getLinks(); + public abstract Links getLinks(); /** * Returns the {@code Status} or {@code null} if {@code Span} is still active. @@ -144,4 +146,142 @@ public static SpanData create( public abstract Timestamp getEndTimestamp(); SpanData() {} + + /** A timed event representation. It can be a timed {@link Annotation} or {@link NetworkEvent}. */ + @Immutable + @AutoValue + public abstract static class TimedEvent { + /** + * Returns a new immutable {@code TimedEvent}. + * + * @param timestamp the {@code Timestamp} of this event. + * @param event the event. + * @param the type of value that is timed. + * @return a new immutable {@code TimedEvent} + */ + public static TimedEvent create(Timestamp timestamp, T event) { + return new AutoValue_SpanData_TimedEvent(timestamp, event); + } + + /** + * Returns the {@code Timestamp} of this event. + * + * @return the {@code Timestamp} of this event. + */ + public abstract Timestamp getTimestamp(); + + /** + * Returns the event. + * + * @return the event. + */ + public abstract T getEvent(); + + TimedEvent() {} + } + + @Immutable + @AutoValue + public abstract static class TimedEvents { + /** + * Returns a new immutable {@code TimedEvents}. + * + * @param events the list of events. + * @param droppedEventsCount the number of dropped events. + * @param the type of value that is timed. + * @return a new immutable {@code TimedEvents} + */ + public static TimedEvents create(List> events, int droppedEventsCount) { + return new AutoValue_SpanData_TimedEvents( + Collections.unmodifiableList( + new ArrayList>(checkNotNull(events, "events"))), + droppedEventsCount); + } + + /** + * Returns the list of events. + * + * @return the list of events. + */ + public abstract List> getEvents(); + + /** + * Returns the number of dropped events. + * + * @return the number of dropped events. + */ + public abstract int getDroppedEventsCount(); + + TimedEvents() {} + } + + @Immutable + @AutoValue + public abstract static class Attributes { + /** + * Returns a new immutable {@code Attributes}. + * + * @param attributeMap the set of attributes. + * @param droppedAttributesCount the number of dropped attributes. + * @return a new immutable {@code Attributes}. + */ + public static Attributes create( + Map attributeMap, int droppedAttributesCount) { + // TODO(bdrutu): Consider to use LinkedHashMap here and everywhere else, less test flakes + // for others on account of determinism. + return new AutoValue_SpanData_Attributes( + Collections.unmodifiableMap( + new HashMap(checkNotNull(attributeMap, "attributeMap"))), + droppedAttributesCount); + } + + /** + * Returns the set of attributes. + * + * @return the set of attributes. + */ + public abstract Map getAttributeMap(); + + /** + * Returns the number of dropped attributes. + * + * @return the number of dropped attributes. + */ + public abstract int getDroppedAttributesCount(); + + Attributes() {} + } + + @Immutable + @AutoValue + public abstract static class Links { + /** + * Returns a new immutable {@code Links}. + * + * @param links the list of links. + * @param droppedLinksCount the number of dropped links. + * @return a new immutable {@code Links}. + */ + public static Links create(List links, int droppedLinksCount) { + return new AutoValue_SpanData_Links( + Collections.unmodifiableList(new ArrayList(checkNotNull(links, "links"))), + droppedLinksCount); + } + + /** + * Returns the list of links. + * + * @return the list of links. + */ + public abstract List getLinks(); + + /** + * Returns the number of dropped links. + * + * @return the number of dropped links. + */ + public abstract int getDroppedLinksCount(); + + Links() {} + } } diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java index b43714bd5f..e1917e9330 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java @@ -58,15 +58,17 @@ final class SpanImpl extends Span { // Creates and starts a span with the given configuration. TimestampConverter is null if the // Span is a root span or the parent is not sampled. If the parent is sampled we should use the // same converter to ensure ordering between tracing events. - static SpanImpl startSpan(SpanContext context, + static SpanImpl startSpan( + SpanContext context, @Nullable EnumSet options, String name, @Nullable SpanId parentSpanId, StartEndHandler startEndHandler, @Nullable TimestampConverter timestampConverter, Clock clock) { - SpanImpl span = new SpanImpl(context, options, name, parentSpanId, startEndHandler, - timestampConverter, clock); + SpanImpl span = + new SpanImpl( + context, options, name, parentSpanId, startEndHandler, timestampConverter, clock); // Call onStart here instead of calling in the constructor to make sure the span is completely // initialized. if (span.getOptions().contains(Options.RECORD_EVENTS)) { @@ -102,10 +104,11 @@ SpanData toSpanData() { parentSpanId, name, timestampConverter.convertNanoTime(startNanoTime), - Collections.emptyMap(), - Collections.>emptyList(), - Collections.>emptyList(), - Collections.emptyList(), + SpanData.Attributes.create(Collections.emptyMap(), 0), + SpanData.TimedEvents.create(Collections.>emptyList(), 0), + SpanData.TimedEvents.create( + Collections.>emptyList(), 0), + SpanData.Links.create(Collections.emptyList(), 0), hasBeenEnded ? status : null, hasBeenEnded ? timestampConverter.convertNanoTime(endNanoTime) : null); } @@ -160,8 +163,8 @@ public void end(EndSpanOptions options) { *

Implementation must avoid high overhead work in any of the methods because the code is * executed on the critical path. * - *

One instance can be called by multiple threads in the same time, so the implementation - * must be thread-safe. + *

One instance can be called by multiple threads in the same time, so the implementation must + * be thread-safe. */ abstract static class StartEndHandler { abstract void onStart(SpanImpl span); diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TimedEvent.java b/core_impl/src/main/java/com/google/instrumentation/trace/TimedEvent.java deleted file mode 100644 index d4bc1739e5..0000000000 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TimedEvent.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.trace; - -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; -import com.google.instrumentation.common.Timestamp; -import javax.annotation.concurrent.Immutable; - -/** A timed event representation. It can be a timed {@link Annotation} or {@link NetworkEvent}. */ -@Immutable -public final class TimedEvent { - private final Timestamp timestamp; - private final T event; - - TimedEvent(Timestamp timestamp, T event) { - this.timestamp = timestamp; - this.event = event; - } - - /** - * Returns the {@code Timestamp} of this event. - * - * @return the {@code Timestamp} of this event. - */ - public Timestamp getTimestamp() { - return timestamp; - } - - /** - * Returns the event. - * - * @return the event. - */ - public T getEvent() { - return event; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof TimedEvent)) { - return false; - } - - TimedEvent that = (TimedEvent) obj; - return Objects.equal(timestamp, that.timestamp) && Objects.equal(event, that.event); - } - - @Override - public int hashCode() { - return Objects.hashCode(timestamp, event); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("timestamp", timestamp) - .add("event", event) - .toString(); - } -} diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/SpanDataTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/SpanDataTest.java index 166dcfca05..9b2e6d7abd 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/SpanDataTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/SpanDataTest.java @@ -15,7 +15,13 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.common.testing.EqualsTester; import com.google.instrumentation.common.Timestamp; +import com.google.instrumentation.trace.Link.Type; +import com.google.instrumentation.trace.SpanData.Attributes; +import com.google.instrumentation.trace.SpanData.Links; +import com.google.instrumentation.trace.SpanData.TimedEvent; +import com.google.instrumentation.trace.SpanData.TimedEvents; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; @@ -37,32 +43,41 @@ public class SpanDataTest { private static final Timestamp endTimestamp = Timestamp.create(123, 460); private static final String DISPLAY_NAME = "MySpanDisplayName"; private static final String ANNOTATION_TEXT = "MyAnnotationText"; + private static final Annotation annotation = Annotation.fromDescription(ANNOTATION_TEXT); + private static final NetworkEvent recvNetworkEvent = + NetworkEvent.builder(NetworkEvent.Type.RECV, 1).build(); + private static final NetworkEvent sentNetworkEvent = + NetworkEvent.builder(NetworkEvent.Type.SENT, 1).build(); private static final Status status = Status.DEADLINE_EXCEEDED.withDescription("TooSlow"); private final Random random = new Random(1234); private final SpanContext spanContext = SpanContext.create( TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); private final SpanId parentSpanId = SpanId.generateRandomId(random); - private final Map attributes = new HashMap(); - private final List> annotations = new LinkedList>(); - private final List> networkEvents = - new LinkedList>(); - private final List links = new LinkedList(); + private final Map attributesMap = new HashMap(); + private final List> annotationsList = + new LinkedList>(); + private final List> networkEventsList = + new LinkedList>(); + private final List linksList = new LinkedList(); + private Attributes attributes; + private TimedEvents annotations; + private TimedEvents networkEvents; + private Links links; @Before public void setUp() { - annotations.add( - new TimedEvent(eventTimestamp1, Annotation.fromDescription(ANNOTATION_TEXT))); - annotations.add( - new TimedEvent(eventTimestamp3, Annotation.fromDescription(ANNOTATION_TEXT))); - networkEvents.add( - new TimedEvent( - eventTimestamp1, NetworkEvent.builder(NetworkEvent.Type.RECV, 1).build())); - networkEvents.add( - new TimedEvent( - eventTimestamp2, NetworkEvent.builder(NetworkEvent.Type.SENT, 1).build())); - attributes.put("MyAttributeKey1", AttributeValue.longAttributeValue(10)); - attributes.put("MyAttributeKey2", AttributeValue.booleanAttributeValue(true)); + attributesMap.put("MyAttributeKey1", AttributeValue.longAttributeValue(10)); + attributesMap.put("MyAttributeKey2", AttributeValue.booleanAttributeValue(true)); + attributes = Attributes.create(attributesMap, 1); + annotationsList.add(SpanData.TimedEvent.create(eventTimestamp1, annotation)); + annotationsList.add(SpanData.TimedEvent.create(eventTimestamp3, annotation)); + annotations = TimedEvents.create(annotationsList, 2); + networkEventsList.add(SpanData.TimedEvent.create(eventTimestamp1, recvNetworkEvent)); + networkEventsList.add(SpanData.TimedEvent.create(eventTimestamp2, sentNetworkEvent)); + networkEvents = TimedEvents.create(networkEventsList, 3); + linksList.add(Link.fromSpanContext(spanContext, Type.CHILD)); + links = Links.create(linksList, 0); } @Test @@ -125,24 +140,70 @@ public void spanData_AllDataEmpty() { parentSpanId, DISPLAY_NAME, startTimestamp, - Collections.emptyMap(), - Collections.>emptyList(), - Collections.>emptyList(), - Collections.emptyList(), + Attributes.create(Collections.emptyMap(), 0), + TimedEvents.create(Collections.>emptyList(), 0), + TimedEvents.create(Collections.>emptyList(), 0), + Links.create(Collections.emptyList(), 0), status, endTimestamp); assertThat(spanData.getContext()).isEqualTo(spanContext); assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); assertThat(spanData.getDisplayName()).isEqualTo(DISPLAY_NAME); assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); - assertThat(spanData.getAttributes().isEmpty()).isTrue(); - assertThat(spanData.getAnnotations().isEmpty()).isTrue(); - assertThat(spanData.getNetworkEvents().isEmpty()).isTrue(); - assertThat(spanData.getLinks().isEmpty()).isTrue(); + assertThat(spanData.getAttributes().getAttributeMap().isEmpty()).isTrue(); + assertThat(spanData.getAnnotations().getEvents().isEmpty()).isTrue(); + assertThat(spanData.getNetworkEvents().getEvents().isEmpty()).isTrue(); + assertThat(spanData.getLinks().getLinks().isEmpty()).isTrue(); assertThat(spanData.getStatus()).isEqualTo(status); assertThat(spanData.getEndTimestamp()).isEqualTo(endTimestamp); } + @Test + public void spanDataEquals() { + String allSpanData1 = + SpanData.create( + spanContext, + parentSpanId, + DISPLAY_NAME, + startTimestamp, + attributes, + annotations, + networkEvents, + links, + status, + endTimestamp) + .toString(); + String allSpanData2 = + SpanData.create( + spanContext, + parentSpanId, + DISPLAY_NAME, + startTimestamp, + attributes, + annotations, + networkEvents, + links, + status, + endTimestamp) + .toString(); + SpanData emptySpanData = + SpanData.create( + spanContext, + parentSpanId, + DISPLAY_NAME, + startTimestamp, + Attributes.create(Collections.emptyMap(), 0), + TimedEvents.create(Collections.>emptyList(), 0), + TimedEvents.create(Collections.>emptyList(), 0), + Links.create(Collections.emptyList(), 0), + status, + endTimestamp); + new EqualsTester() + .addEqualityGroup(allSpanData1, allSpanData2) + .addEqualityGroup(emptySpanData) + .testEquals(); + } + @Test public void spanData_ToString() { String spanDataString = diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TimedEventTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TimedEventTest.java deleted file mode 100644 index be8d1502ca..0000000000 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TimedEventTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.trace; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.testing.EqualsTester; -import com.google.instrumentation.common.Timestamp; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link TimedEvent}. */ -@RunWith(JUnit4.class) -public class TimedEventTest { - private static final Timestamp timestamp = Timestamp.create(123, 456); - private static final Annotation annotation = Annotation.fromDescription("MyTextAnnotation"); - private static final NetworkEvent networkEvent = - NetworkEvent.builder(NetworkEvent.Type.RECV, 1).build(); - - @Test - public void timedEvent_WithAnnotation() { - TimedEvent timedEvent = new TimedEvent(timestamp, annotation); - assertThat(timedEvent.getTimestamp()).isEqualTo(timestamp); - assertThat(timedEvent.getEvent()).isEqualTo(annotation); - assertThat(timedEvent.toString()).contains(timestamp.toString()); - assertThat(timedEvent.toString()).contains(annotation.toString()); - } - - @Test - public void timedEvent_WithNetworkEvent() { - TimedEvent timedEvent = new TimedEvent(timestamp, networkEvent); - assertThat(timedEvent.getTimestamp()).isEqualTo(timestamp); - assertThat(timedEvent.getEvent()).isEqualTo(networkEvent); - assertThat(timedEvent.toString()).contains(timestamp.toString()); - assertThat(timedEvent.toString()).contains(networkEvent.toString()); - } - - @Test - public void link_EqualsAndHashCode() { - EqualsTester tester = new EqualsTester(); - tester - .addEqualityGroup( - new TimedEvent(timestamp, annotation), - new TimedEvent(timestamp, annotation)) - .addEqualityGroup( - new TimedEvent(timestamp, networkEvent), - new TimedEvent(timestamp, networkEvent)); - tester.testEquals(); - } -} From 62ccd0bce9c88957461eb0a44a6c14bea45f0bf9 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 2 May 2017 15:04:25 -0700 Subject: [PATCH 0037/1581] Set correct source and target in gradle for java7 and java8 artifacts. (#272) * Set correct source and target in gradle for java7 and java8 artifacts. * Build instrumentation-java8 and instrumentation-benchmark artifacts only if java8 is available. --- core_impl_java/build.gradle | 7 +++++++ core_impl_java_7/build.gradle | 7 +++++++ core_impl_java_8/build.gradle | 7 +++++++ settings.gradle | 8 ++++---- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/core_impl_java/build.gradle b/core_impl_java/build.gradle index 0eea0a779a..149fae40ee 100644 --- a/core_impl_java/build.gradle +++ b/core_impl_java/build.gradle @@ -1,5 +1,12 @@ description = 'Instrumentation Core Impl Java' +apply plugin: 'java' + +[compileJava, compileTestJava].each() { + it.sourceCompatibility = 1.7 + it.targetCompatibility = 1.7 +} + dependencies { compile project(':instrumentation-java-core'), project(':instrumentation-java-core-impl'), diff --git a/core_impl_java_7/build.gradle b/core_impl_java_7/build.gradle index 62a9bd543a..e504da837f 100644 --- a/core_impl_java_7/build.gradle +++ b/core_impl_java_7/build.gradle @@ -1,5 +1,12 @@ description = 'Instrumentation Core Impl Java 7' +apply plugin: 'java' + +[compileJava, compileTestJava].each() { + it.sourceCompatibility = 1.7 + it.targetCompatibility = 1.7 +} + dependencies { compile project(':instrumentation-java-core'), project(':instrumentation-java-core-impl'), diff --git a/core_impl_java_8/build.gradle b/core_impl_java_8/build.gradle index 89655ef2a9..12393dbeea 100644 --- a/core_impl_java_8/build.gradle +++ b/core_impl_java_8/build.gradle @@ -1,5 +1,12 @@ description = 'Instrumentation Core Impl Java 8' +apply plugin: 'java' + +[compileJava, compileTestJava].each() { + it.sourceCompatibility = 1.8 + it.targetCompatibility = 1.8 +} + dependencies { compile project(':instrumentation-java-core'), project(':instrumentation-java-core-impl'), diff --git a/settings.gradle b/settings.gradle index f5acf453fc..bd454c36c0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,27 +1,27 @@ rootProject.name = "instrumentation-java" include ":instrumentation-java-all" -include ":instrumentation-java-benchmarks" include ":instrumentation-java-core" include ":instrumentation-java-core-impl" include ":instrumentation-java-core-impl-java" include ":instrumentation-java-core-impl-java-7" -include ":instrumentation-java-core-impl-java-8" include ":instrumentation-java-core-impl-android" include ":shared" project(':instrumentation-java-all').projectDir = "$rootDir/all" as File -project(':instrumentation-java-benchmarks').projectDir = "$rootDir/benchmarks" as File project(':instrumentation-java-core').projectDir = "$rootDir/core" as File project(':instrumentation-java-core-impl').projectDir = "$rootDir/core_impl" as File project(':instrumentation-java-core-impl-java').projectDir = "$rootDir/core_impl_java" as File project(':instrumentation-java-core-impl-java-7').projectDir = "$rootDir/core_impl_java_7" as File -project(':instrumentation-java-core-impl-java-8').projectDir = "$rootDir/core_impl_java_8" as File project(':instrumentation-java-core-impl-android').projectDir = "$rootDir/core_impl_android" as File project(':shared').projectDir = "$rootDir/shared" as File // Java8 projects only if (JavaVersion.current().isJava8Compatible()) { include ":instrumentation-examples" + include ":instrumentation-java-benchmarks" + include ":instrumentation-java-core-impl-java-8" project(':instrumentation-examples').projectDir = "$rootDir/examples" as File + project(':instrumentation-java-benchmarks').projectDir = "$rootDir/benchmarks" as File + project(':instrumentation-java-core-impl-java-8').projectDir = "$rootDir/core_impl_java_8" as File } From 2d179335d4500d97b6b80f59d37d7769ec884b53 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 1 May 2017 16:31:10 -0700 Subject: [PATCH 0038/1581] Add a TraceExporter class that allows exporting Span data to different services. --- .../instrumentation/trace/SpanData.java | 0 .../instrumentation/trace/TraceComponent.java | 13 +++ .../instrumentation/trace/TraceExporter.java | 84 +++++++++++++++++++ .../google/instrumentation/trace/Tracing.java | 9 ++ .../instrumentation/trace/SpanDataTest.java | 0 .../trace/TraceComponentTest.java | 6 ++ .../instrumentation/trace/TracingTest.java | 5 ++ .../trace/TraceComponentImplBase.java | 6 ++ .../trace/TraceComponentImplTest.java | 8 +- .../trace/TraceComponentImplTest.java | 8 +- .../trace/TraceComponentImplTest.java | 8 +- 11 files changed, 144 insertions(+), 3 deletions(-) rename {core_impl => core}/src/main/java/com/google/instrumentation/trace/SpanData.java (100%) create mode 100644 core/src/main/java/com/google/instrumentation/trace/TraceExporter.java rename {core_impl => core}/src/test/java/com/google/instrumentation/trace/SpanDataTest.java (100%) diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanData.java b/core/src/main/java/com/google/instrumentation/trace/SpanData.java similarity index 100% rename from core_impl/src/main/java/com/google/instrumentation/trace/SpanData.java rename to core/src/main/java/com/google/instrumentation/trace/SpanData.java diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java b/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java index b00b6cf6e4..2d7de903bc 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java @@ -48,6 +48,14 @@ public abstract class TraceComponent { */ public abstract Clock getClock(); + /** + * Returns the {@link TraceExporter} with the provided implementation. If no implementation is + * provided then no-op implementations will be used. + * + * @return the {@link TraceExporter} implementation. + */ + public abstract TraceExporter getTraceExporter(); + // Disallow external overrides until we define the final API. TraceComponent() {} @@ -76,6 +84,11 @@ public Clock getClock() { return ZeroTimeClock.getInstance(); } + @Override + public TraceExporter getTraceExporter() { + return TraceExporter.getNoopTraceExporter(); + } + private NoopTraceComponent() {} } } diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java new file mode 100644 index 0000000000..2cbf8c2647 --- /dev/null +++ b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java @@ -0,0 +1,84 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.ThreadSafe; + +/** + * The main exporting API for the trace library. + * + *

Implementation MUST ensure that all functions are thread safe. + */ +@ThreadSafe +public abstract class TraceExporter { + private static final NoopTraceExporter noopTraceExporter = new NoopTraceExporter(); + + /** + * Register a new service handler that allows the library to + * + *

Example of usage: + * + *

{@code
+   * public static void main(String[] args) {
+   *   Tracing.getTraceExporter().registerServiceHandler(
+   *       "com.google.stackdriver", new StackdriverServiceHandler());
+   *   // ...
+   * }
+   * }
+ * + * @param name the name of the exporter. Must be unique for each service. + * @param serviceHandler the service handler that is called for each ended sampled span. If {@code + * null} the previous exporter with the same name will be removed. + */ + public abstract void registerServiceHandler(String name, @Nullable ServiceHandler serviceHandler); + + /** + * An abstract class that allows different tracing services to export recorded data for sampled + * spans in their own format. + * + *

To export data this MUST be register to to the TraceExporter using {@link + * #registerServiceHandler(String, ServiceHandler)}. + */ + public abstract static class ServiceHandler { + + /** + * It is called every time after a sampled (see {@link TraceOptions#isSampled()}) {@link Span} + * is ended. + * + *

This may be called from a different thread than the one that called {@link Span#end()}. + * + *

Implementation SHOULD not block the calling thread and execute the export on a different + * thread if possible. + * + * @param spanData the immutable representation of all data collected by the {@code Span}. + */ + public abstract void export(SpanData spanData); + } + + /** + * Returns the no-op implementation of the {@code TraceExporter}. + * + * @return the no-op implementation of the {@code TraceExporter}. + */ + static TraceExporter getNoopTraceExporter() { + return noopTraceExporter; + } + + private static final class NoopTraceExporter extends TraceExporter { + + @Override + public void registerServiceHandler(String name, @Nullable ServiceHandler serviceHandler) {} + } +} diff --git a/core/src/main/java/com/google/instrumentation/trace/Tracing.java b/core/src/main/java/com/google/instrumentation/trace/Tracing.java index f5b0d7fcb4..aa11824f66 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Tracing.java +++ b/core/src/main/java/com/google/instrumentation/trace/Tracing.java @@ -52,6 +52,15 @@ public static Clock getClock() { return traceComponent.getClock(); } + /** + * Returns the global {@link TraceExporter}. + * + * @return the global {@code TraceExporter}. + */ + public static TraceExporter getTraceExporter() { + return traceComponent.getTraceExporter(); + } + // Any provider that may be used for TraceComponent can be added here. @VisibleForTesting static TraceComponent loadTraceComponent(ClassLoader classLoader) { diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/SpanDataTest.java b/core/src/test/java/com/google/instrumentation/trace/SpanDataTest.java similarity index 100% rename from core_impl/src/test/java/com/google/instrumentation/trace/SpanDataTest.java rename to core/src/test/java/com/google/instrumentation/trace/SpanDataTest.java diff --git a/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java b/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java index d7510d4bc1..9cae921191 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java @@ -38,4 +38,10 @@ public void defaultBinaryPropagationHandler() { public void defaultClock() { assertThat(TraceComponent.getNoopTraceComponent().getClock()).isInstanceOf(ZeroTimeClock.class); } + + @Test + public void defaultTraceExporter() { + assertThat(TraceComponent.getNoopTraceComponent().getTraceExporter()) + .isSameAs(TraceExporter.getNoopTraceExporter()); + } } diff --git a/core/src/test/java/com/google/instrumentation/trace/TracingTest.java b/core/src/test/java/com/google/instrumentation/trace/TracingTest.java index 83f881d430..24006ecf1e 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TracingTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/TracingTest.java @@ -65,4 +65,9 @@ public void defaultBinaryPropagationHandler() { assertThat(Tracing.getBinaryPropagationHandler()) .isSameAs(BinaryPropagationHandler.getNoopBinaryPropagationHandler()); } + + @Test + public void defaultTraceExporter() { + assertThat(Tracing.getTraceExporter()).isSameAs(TraceExporter.getNoopTraceExporter()); + } } diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java index 6f72d4175e..ae32665273 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java @@ -21,6 +21,7 @@ public class TraceComponentImplBase extends TraceComponent { private static final BinaryPropagationHandler binaryPropagationHandler = BinaryPropagationHandlerImpl.INSTANCE; private final Clock clock; + private final TraceExporter traceExporter = TraceExporter.getNoopTraceExporter(); TraceComponentImplBase(Clock clock) { this.clock = clock; @@ -40,4 +41,9 @@ public BinaryPropagationHandler getBinaryPropagationHandler() { public final Clock getClock() { return clock; } + + @Override + public TraceExporter getTraceExporter() { + return traceExporter; + } } diff --git a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index 814d10a0cb..26f7c8b123 100644 --- a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -32,11 +32,17 @@ public void implementationOfTracer() { @Test public void implementationOfBinaryPropagationHandler() { assertThat(Tracing.getBinaryPropagationHandler()) - .isSameAs(BinaryPropagationHandlerImpl.INSTANCE); + .isInstanceOf(BinaryPropagationHandlerImpl.class); } @Test public void implementationOfClock() { assertThat(Tracing.getClock()).isInstanceOf(MillisClock.class); } + + @Test + public void implementationOfTraceExporter() { + // TODO(bdrutu): Change this when TraceExporterImpl is available. + assertThat(Tracing.getTraceExporter()).isSameAs(TraceExporter.getNoopTraceExporter()); + } } diff --git a/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index 814d10a0cb..26f7c8b123 100644 --- a/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -32,11 +32,17 @@ public void implementationOfTracer() { @Test public void implementationOfBinaryPropagationHandler() { assertThat(Tracing.getBinaryPropagationHandler()) - .isSameAs(BinaryPropagationHandlerImpl.INSTANCE); + .isInstanceOf(BinaryPropagationHandlerImpl.class); } @Test public void implementationOfClock() { assertThat(Tracing.getClock()).isInstanceOf(MillisClock.class); } + + @Test + public void implementationOfTraceExporter() { + // TODO(bdrutu): Change this when TraceExporterImpl is available. + assertThat(Tracing.getTraceExporter()).isSameAs(TraceExporter.getNoopTraceExporter()); + } } diff --git a/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index 0e426e1a65..7a20e31acf 100644 --- a/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -32,11 +32,17 @@ public void implementationOfTracer() { @Test public void implementationOfBinaryPropagationHandler() { assertThat(Tracing.getBinaryPropagationHandler()) - .isSameAs(BinaryPropagationHandlerImpl.INSTANCE); + .isInstanceOf(BinaryPropagationHandlerImpl.class); } @Test public void implementationOfClock() { assertThat(Tracing.getClock()).isInstanceOf(InstantClock.class); } + + @Test + public void implementationOfTraceExporter() { + // TODO(bdrutu): Change this when TraceExporterImpl is available. + assertThat(Tracing.getTraceExporter()).isSameAs(TraceExporter.getNoopTraceExporter()); + } } From 0c94ad5295e140477c2f6a82ebb96ee19ec637c4 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 2 May 2017 15:13:31 -0700 Subject: [PATCH 0039/1581] Added comments to all SpanData nested classes and updated the comments in the TraceExporter. --- .../instrumentation/trace/SpanData.java | 17 ++++++++++++- .../instrumentation/trace/TraceExporter.java | 24 ++++++++++++------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/trace/SpanData.java b/core/src/main/java/com/google/instrumentation/trace/SpanData.java index ce1a7a8485..579b03733e 100644 --- a/core/src/main/java/com/google/instrumentation/trace/SpanData.java +++ b/core/src/main/java/com/google/instrumentation/trace/SpanData.java @@ -147,7 +147,11 @@ public static SpanData create( SpanData() {} - /** A timed event representation. It can be a timed {@link Annotation} or {@link NetworkEvent}. */ + /** + * A timed event representation. + * + * @param the type of value that is timed. + */ @Immutable @AutoValue public abstract static class TimedEvent { @@ -180,6 +184,11 @@ public static TimedEvent create(Timestamp timestamp, T event) { TimedEvent() {} } + /** + * A list of timed events and the number of dropped events representation. + * + * @param the type of value that is timed. + */ @Immutable @AutoValue public abstract static class TimedEvents { @@ -215,6 +224,9 @@ public static TimedEvents create(List> events, int droppedE TimedEvents() {} } + /** + * A set of attributes and the number of dropped attributes representation. + */ @Immutable @AutoValue public abstract static class Attributes { @@ -252,6 +264,9 @@ public static Attributes create( Attributes() {} } + /** + * A list of links and the number of dropped links representation. + */ @Immutable @AutoValue public abstract static class Links { diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java index 2cbf8c2647..d9aa074f05 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java @@ -26,7 +26,7 @@ public abstract class TraceExporter { private static final NoopTraceExporter noopTraceExporter = new NoopTraceExporter(); /** - * Register a new service handler that allows the library to + * Registers a new service handler that is used by the library to export trace data. * *

Example of usage: * @@ -38,11 +38,17 @@ public abstract class TraceExporter { * } * } * - * @param name the name of the exporter. Must be unique for each service. - * @param serviceHandler the service handler that is called for each ended sampled span. If {@code - * null} the previous exporter with the same name will be removed. + * @param name the name of the service handler. Must be unique for each service. + * @param serviceHandler the service handler that is called for each ended sampled span. */ - public abstract void registerServiceHandler(String name, @Nullable ServiceHandler serviceHandler); + public abstract void registerServiceHandler(String name, ServiceHandler serviceHandler); + + /** + * Unregisters the service handler with the provided name. + * + * @param name the name of the service handler that will be unregistered. + */ + public abstract void unregisterServiceHandler(String name); /** * An abstract class that allows different tracing services to export recorded data for sampled @@ -59,8 +65,8 @@ public abstract static class ServiceHandler { * *

This may be called from a different thread than the one that called {@link Span#end()}. * - *

Implementation SHOULD not block the calling thread and execute the export on a different - * thread if possible. + *

Implementation SHOULD not block the calling thread. It should execute the export on a + * different thread if possible. * * @param spanData the immutable representation of all data collected by the {@code Span}. */ @@ -77,8 +83,10 @@ static TraceExporter getNoopTraceExporter() { } private static final class NoopTraceExporter extends TraceExporter { - @Override public void registerServiceHandler(String name, @Nullable ServiceHandler serviceHandler) {} + + @Override + public void unregisterServiceHandler(String name) {} } } From 6717f5b90dad7476f049214f79f39cfbad5d9b93 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 2 May 2017 17:25:16 -0700 Subject: [PATCH 0040/1581] Add a random handler that can be implement differently based on the java support. (#273) --- .../instrumentation/trace/RandomHandler.java | 32 ++++++++++++++++++ .../trace/RandomHandlerAndroid.java | 33 +++++++++++++++++++ .../trace/RandomHandlerJava.java | 31 +++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 core_impl/src/main/java/com/google/instrumentation/trace/RandomHandler.java create mode 100644 core_impl_android/src/main/java/com/google/instrumentation/trace/RandomHandlerAndroid.java create mode 100644 core_impl_java/src/main/java/com/google/instrumentation/trace/RandomHandlerJava.java diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/RandomHandler.java b/core_impl/src/main/java/com/google/instrumentation/trace/RandomHandler.java new file mode 100644 index 0000000000..0d58543a46 --- /dev/null +++ b/core_impl/src/main/java/com/google/instrumentation/trace/RandomHandler.java @@ -0,0 +1,32 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import java.util.Random; +import javax.annotation.concurrent.ThreadSafe; + +/** + * Abstract class to access the current {@link Random}. + * + *

Implementation can have a per thread instance or a single global instance. + */ +@ThreadSafe +abstract class RandomHandler { + /** + * Returns the current {@link Random}. + * + * @return the current {@code Random}. + */ + abstract Random current(); +} diff --git a/core_impl_android/src/main/java/com/google/instrumentation/trace/RandomHandlerAndroid.java b/core_impl_android/src/main/java/com/google/instrumentation/trace/RandomHandlerAndroid.java new file mode 100644 index 0000000000..61a8697348 --- /dev/null +++ b/core_impl_android/src/main/java/com/google/instrumentation/trace/RandomHandlerAndroid.java @@ -0,0 +1,33 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import java.security.SecureRandom; +import java.util.Random; +import javax.annotation.concurrent.ThreadSafe; + +/** + * Implementation of the {@link RandomHandler} using {@link SecureRandom}. + */ +@ThreadSafe +final class RandomHandlerAndroid extends RandomHandler { + private final Random random = new SecureRandom(); + + RandomHandlerAndroid() {} + + @Override + Random current() { + return random; + } +} diff --git a/core_impl_java/src/main/java/com/google/instrumentation/trace/RandomHandlerJava.java b/core_impl_java/src/main/java/com/google/instrumentation/trace/RandomHandlerJava.java new file mode 100644 index 0000000000..d04000fbcf --- /dev/null +++ b/core_impl_java/src/main/java/com/google/instrumentation/trace/RandomHandlerJava.java @@ -0,0 +1,31 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import javax.annotation.concurrent.ThreadSafe; + +/** + * Implementation of the {@link RandomHandler} using {@link ThreadLocalRandom}. + */ +@ThreadSafe +final class RandomHandlerJava extends RandomHandler { + RandomHandlerJava() {} + + @Override + Random current() { + return ThreadLocalRandom.current(); + } +} From 9097630ca0e1a487aad6ab50cf6190f2063692d5 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 3 May 2017 20:11:17 -0700 Subject: [PATCH 0041/1581] Add a TraceConfig for active TraceParams and allow changing the active TraceParams. (#275) * Add a TraceConfig for active TraceParams and allow changing the active TraceParams. --- .../instrumentation/trace/TraceComponent.java | 17 +- .../instrumentation/trace/TraceConfig.java | 212 ++++++++++++++++++ .../google/instrumentation/trace/Tracing.java | 9 + .../trace/TraceComponentTest.java | 6 + .../trace/TraceParamsTest.java | 9 +- .../instrumentation/trace/TracingTest.java | 5 + .../trace/TraceComponentImplBase.java | 6 + .../trace/TraceConfigImpl.java | 37 +++ .../instrumentation/trace/TraceParams.java | 153 ------------- .../trace/TraceConfigImplTest.java | 50 +++++ 10 files changed, 345 insertions(+), 159 deletions(-) create mode 100644 core/src/main/java/com/google/instrumentation/trace/TraceConfig.java rename {core_impl => core}/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java (91%) create mode 100644 core_impl/src/main/java/com/google/instrumentation/trace/TraceConfigImpl.java delete mode 100644 core_impl/src/main/java/com/google/instrumentation/trace/TraceParams.java create mode 100644 core_impl/src/test/java/com/google/instrumentation/trace/TraceConfigImplTest.java diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java b/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java index 2d7de903bc..885f0dea92 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java @@ -17,8 +17,8 @@ import com.google.instrumentation.internal.ZeroTimeClock; /** - * Class that holds the implementation instances for {@link Tracer} and {@link - * BinaryPropagationHandler}. + * Class that holds the implementation instances for {@link Tracer}, {@link + * BinaryPropagationHandler}, {@link Clock}, {@link TraceExporter} and {@link TraceConfig}. * *

Unless otherwise noted all methods (on component) results are cacheable. */ @@ -56,6 +56,14 @@ public abstract class TraceComponent { */ public abstract TraceExporter getTraceExporter(); + /** + * Returns the {@link TraceConfig} with the provided implementation. If no implementation is + * provided then no-op implementations will be used. + * + * @return the {@link TraceConfig} implementation. + */ + public abstract TraceConfig getTraceConfig(); + // Disallow external overrides until we define the final API. TraceComponent() {} @@ -89,6 +97,11 @@ public TraceExporter getTraceExporter() { return TraceExporter.getNoopTraceExporter(); } + @Override + public TraceConfig getTraceConfig() { + return TraceConfig.getNoopTraceConfig(); + } + private NoopTraceComponent() {} } } diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java b/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java new file mode 100644 index 0000000000..d7b97dbf09 --- /dev/null +++ b/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java @@ -0,0 +1,212 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.auto.value.AutoValue; +import javax.annotation.concurrent.Immutable; + +/** + * Global configuration of the trace service. This allows users to change configs for the default + * sampler, maximum events to be kept, etc. (see {@link TraceParams} for details). + */ +public abstract class TraceConfig { + private static final NoopTraceConfig noopTraceConfig = new NoopTraceConfig(); + + /** + * Returns the active {@code TraceParams}. + * + * @return the active {@code TraceParams}. + */ + public abstract TraceParams getActiveTraceParams(); + + /** + * Updates the active {@link TraceParams}. + * + * @param traceParams the new active {@code TraceParams}. + */ + public abstract void updateActiveTraceParams(TraceParams traceParams); + + /** + * Temporary updates the active {@link TraceParams} for {@code durationNs} nanoseconds. + * + * @param traceParams the new active {@code TraceParams}. + * @param durationNs the duration for how long the new params will be active. + */ + public abstract void temporaryUpdateActiveTraceParams(TraceParams traceParams, long durationNs); + + /** + * Returns the no-op implementation of the {@code TraceConfig}. + * + * @return the no-op implementation of the {@code TraceConfig}. + */ + static TraceConfig getNoopTraceConfig() { + return noopTraceConfig; + } + + /** Class that holds global trace parameters. */ + @AutoValue + @Immutable + public abstract static class TraceParams { + // These values are the default values for all the global parameters. + // TODO(aveitch): Change this when a rate/probability sampler is available. + private static final Sampler DEFAULT_SAMPLER = Samplers.neverSample(); + private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES = 32; + private static final int DEFAULT_SPAN_MAX_NUM_ANNOTATIONS = 32; + private static final int DEFAULT_SPAN_MAX_NUM_NETWORK_EVENTS = 128; + private static final int DEFAULT_SPAN_MAX_NUM_LINKS = 128; + + public static final TraceParams DEFAULT = + TraceParams.builder() + .setSampler(DEFAULT_SAMPLER) + .setMaxNumberOfAttributes(DEFAULT_SPAN_MAX_NUM_ATTRIBUTES) + .setMaxNumberOfAnnotations(DEFAULT_SPAN_MAX_NUM_ANNOTATIONS) + .setMaxNumberOfNetworkEvents(DEFAULT_SPAN_MAX_NUM_NETWORK_EVENTS) + .setMaxNumberOfLinks(DEFAULT_SPAN_MAX_NUM_LINKS) + .build(); + + /** + * Returns the global default {@code Sampler}. Used if no {@code Sampler} is provided in {@link + * StartSpanOptions}. + * + * @return the global default {@code Sampler}. + */ + public abstract Sampler getSampler(); + + /** + * Returns the global default max number of attributes per {@link Span}. + * + * @return the global default max number of attributes per {@link Span}. + */ + public abstract int getMaxNumberOfAttributes(); + + /** + * Returns the global default max number of {@link Annotation} events per {@link Span}. + * + * @return the global default max number of {@code Annotation} events per {@code Span}. + */ + public abstract int getMaxNumberOfAnnotations(); + + /** + * Returns the global default max number of {@link NetworkEvent} events per {@link Span}. + * + * @return the global default max number of {@code NetworkEvent} events per {@code Span}. + */ + public abstract int getMaxNumberOfNetworkEvents(); + + /** + * Returns the global default max number of {@link Link} entries per {@link Span}. + * + * @return the global default max number of {@code Link} entries per {@code Span}. + */ + public abstract int getMaxNumberOfLinks(); + + private static Builder builder() { + return new AutoValue_TraceConfig_TraceParams.Builder(); + } + + /** + * Returns a {@link Builder} initialized to the same property values as the current instance. + * + * @return a {@link Builder} initialized to the same property values as the current instance. + */ + public abstract Builder toBuilder(); + + @AutoValue.Builder + public abstract static class Builder { + + /** + * Sets the global default {@code Sampler}. It must be not {@code null} otherwise {@link + * #build()} will throw an exception. + * + * @param sampler the global default {@code Sampler}. + * @return this. + */ + public abstract Builder setSampler(Sampler sampler); + + /** + * Sets the global default max number of attributes per {@link Span}. + * + * @param maxNumberOfAttributes the global default max number of attributes per {@link Span}. + * It must be positive otherwise {@link #build()} will throw an exception. + * @return this. + */ + public abstract Builder setMaxNumberOfAttributes(int maxNumberOfAttributes); + + /** + * Sets the global default max number of {@link Annotation} events per {@link Span}. + * + * @param maxNumberOfAnnotations the global default max number of {@link Annotation} events + * per {@link Span}. It must be positive otherwise {@link #build()} will throw an + * exception. + * @return this. + */ + public abstract Builder setMaxNumberOfAnnotations(int maxNumberOfAnnotations); + + /** + * Sets the global default max number of {@link NetworkEvent} events per {@link Span}. + * + * @param maxNumberOfNetworkEvents the global default max number of {@link NetworkEvent} + * events per {@link Span}. It must be positive otherwise {@link #build()} will throw an + * exception. + * @return this. + */ + public abstract Builder setMaxNumberOfNetworkEvents(int maxNumberOfNetworkEvents); + + /** + * Sets the global default max number of {@link Link} entries per {@link Span}. + * + * @param maxNumberOfLinks the global default max number of {@link Link} entries per {@link + * Span}. It must be positive otherwise {@link #build()} will throw an exception. + * @return this. + */ + public abstract Builder setMaxNumberOfLinks(int maxNumberOfLinks); + + abstract TraceParams autoBuild(); + + /** + * Builds and returns a {@code TraceParams} with the desired values. + * + * @return a {@code TraceParams} with the desired values. + * @throws NullPointerException if the sampler is {@code null}. + * @throws IllegalArgumentException if any of the max numbers are not positive. + */ + public TraceParams build() { + TraceParams traceParams = autoBuild(); + checkNotNull(traceParams.getSampler(), "sampler"); + checkArgument(traceParams.getMaxNumberOfAttributes() > 0, "maxNumberOfAttributes"); + checkArgument(traceParams.getMaxNumberOfAnnotations() > 0, "maxNumberOfAnnotations"); + checkArgument(traceParams.getMaxNumberOfNetworkEvents() > 0, "maxNumberOfNetworkEvents"); + checkArgument(traceParams.getMaxNumberOfLinks() > 0, "maxNumberOfLinks"); + return traceParams; + } + } + } + + private static final class NoopTraceConfig extends TraceConfig { + + @Override + public TraceParams getActiveTraceParams() { + return TraceParams.DEFAULT; + } + + @Override + public void updateActiveTraceParams(TraceParams traceParams) {} + + @Override + public void temporaryUpdateActiveTraceParams(TraceParams traceParams, long durationNs) {} + } +} diff --git a/core/src/main/java/com/google/instrumentation/trace/Tracing.java b/core/src/main/java/com/google/instrumentation/trace/Tracing.java index aa11824f66..8759d38b7c 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Tracing.java +++ b/core/src/main/java/com/google/instrumentation/trace/Tracing.java @@ -61,6 +61,15 @@ public static TraceExporter getTraceExporter() { return traceComponent.getTraceExporter(); } + /** + * Returns the global {@link TraceConfig}. + * + * @return the global {@code TraceConfig}. + */ + public static TraceConfig getTraceConfig() { + return traceComponent.getTraceConfig(); + } + // Any provider that may be used for TraceComponent can be added here. @VisibleForTesting static TraceComponent loadTraceComponent(ClassLoader classLoader) { diff --git a/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java b/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java index 9cae921191..9a0db1bf41 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java @@ -44,4 +44,10 @@ public void defaultTraceExporter() { assertThat(TraceComponent.getNoopTraceComponent().getTraceExporter()) .isSameAs(TraceExporter.getNoopTraceExporter()); } + + @Test + public void defaultTraceConfig() { + assertThat(TraceComponent.getNoopTraceComponent().getTraceConfig()) + .isSameAs(TraceConfig.getNoopTraceConfig()); + } } diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java b/core/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java similarity index 91% rename from core_impl/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java rename to core/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java index b98b2c86c2..c939fc7338 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.instrumentation.trace.TraceConfig.TraceParams; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -36,22 +37,22 @@ public void updateTraceParams_NullSampler() { TraceParams.DEFAULT.toBuilder().setSampler(null).build(); } - @Test(expected = IllegalStateException.class) + @Test(expected = IllegalArgumentException.class) public void updateTraceParams_NonPositiveMaxNumberOfAttributes() { TraceParams.DEFAULT.toBuilder().setMaxNumberOfAttributes(0).build(); } - @Test(expected = IllegalStateException.class) + @Test(expected = IllegalArgumentException.class) public void updateTraceParams_NonPositiveMaxNumberOfAnnotations() { TraceParams.DEFAULT.toBuilder().setMaxNumberOfAnnotations(0).build(); } - @Test(expected = IllegalStateException.class) + @Test(expected = IllegalArgumentException.class) public void updateTraceParams_NonPositiveMaxNumberOfNetworkEvents() { TraceParams.DEFAULT.toBuilder().setMaxNumberOfNetworkEvents(0).build(); } - @Test(expected = IllegalStateException.class) + @Test(expected = IllegalArgumentException.class) public void updateTraceParams_NonPositiveMaxNumberOfLinks() { TraceParams.DEFAULT.toBuilder().setMaxNumberOfLinks(0).build(); } diff --git a/core/src/test/java/com/google/instrumentation/trace/TracingTest.java b/core/src/test/java/com/google/instrumentation/trace/TracingTest.java index 24006ecf1e..ab2669549c 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TracingTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/TracingTest.java @@ -70,4 +70,9 @@ public void defaultBinaryPropagationHandler() { public void defaultTraceExporter() { assertThat(Tracing.getTraceExporter()).isSameAs(TraceExporter.getNoopTraceExporter()); } + + @Test + public void defaultTraceConfig() { + assertThat(Tracing.getTraceConfig()).isSameAs(TraceConfig.getNoopTraceConfig()); + } } diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java index ae32665273..6d7e389e63 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java @@ -22,6 +22,7 @@ public class TraceComponentImplBase extends TraceComponent { BinaryPropagationHandlerImpl.INSTANCE; private final Clock clock; private final TraceExporter traceExporter = TraceExporter.getNoopTraceExporter(); + private final TraceConfig traceConfig = new TraceConfigImpl(); TraceComponentImplBase(Clock clock) { this.clock = clock; @@ -46,4 +47,9 @@ public final Clock getClock() { public TraceExporter getTraceExporter() { return traceExporter; } + + @Override + public TraceConfig getTraceConfig() { + return traceConfig; + } } diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceConfigImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceConfigImpl.java new file mode 100644 index 0000000000..c7b40d272d --- /dev/null +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceConfigImpl.java @@ -0,0 +1,37 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +/** + * Global configuration of the trace service. This allows users to change configs for the default + * sampler, maximum events to be kept, etc. + */ +final class TraceConfigImpl extends TraceConfig { + private volatile TraceParams activeTraceParams = TraceParams.DEFAULT; + + @Override + public TraceParams getActiveTraceParams() { + return activeTraceParams; + } + + @Override + public void updateActiveTraceParams(TraceParams traceParams) { + activeTraceParams = traceParams; + } + + @Override + public void temporaryUpdateActiveTraceParams(TraceParams traceParams, long durationNs) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceParams.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceParams.java deleted file mode 100644 index ec0f950741..0000000000 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceParams.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.trace; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.auto.value.AutoValue; -import javax.annotation.concurrent.Immutable; - -/** Class that holds global trace parameters. */ -@AutoValue -@Immutable -abstract class TraceParams { - - // These values are the default values for all the global parameters. - // TODO(aveitch): Change this when a rate/probability sampler will be available. - private static final Sampler DEFAULT_SAMPLER = Samplers.neverSample(); - private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES = 32; - private static final int DEFAULT_SPAN_MAX_NUM_ANNOTATIONS = 32; - private static final int DEFAULT_SPAN_MAX_NUM_NETWORK_EVENTS = 128; - private static final int DEFAULT_SPAN_MAX_NUM_LINKS = 128; - - static final TraceParams DEFAULT = - TraceParams.builder() - .setSampler(DEFAULT_SAMPLER) - .setMaxNumberOfAttributes(DEFAULT_SPAN_MAX_NUM_ATTRIBUTES) - .setMaxNumberOfAnnotations(DEFAULT_SPAN_MAX_NUM_ANNOTATIONS) - .setMaxNumberOfNetworkEvents(DEFAULT_SPAN_MAX_NUM_NETWORK_EVENTS) - .setMaxNumberOfLinks(DEFAULT_SPAN_MAX_NUM_LINKS) - .build(); - - /** - * Returns the global default {@code Sampler}. Used if no {@code Sampler} provided in {@link - * StartSpanOptions}. - * - * @return the global default {@code Sampler}. - */ - abstract Sampler getSampler(); - - /** - * Returns the global default max number of attributes per {@link Span}. - * - * @return the global default max number of attributes per {@link Span}. - */ - abstract int getMaxNumberOfAttributes(); - - /** - * Returns the global default max number of {@link Annotation} events per {@link Span}. - * - * @return the global default max number of {@code Annotation} events per {@code Span}. - */ - abstract int getMaxNumberOfAnnotations(); - - /** - * Returns the global default max number of {@link NetworkEvent} events per {@link Span}. - * - * @return the global default max number of {@code NetworkEvent} events per {@code Span}. - */ - abstract int getMaxNumberOfNetworkEvents(); - - /** - * Returns the global default max number of {@link Link} entries per {@link Span}. - * - * @return the global default max number of {@code Link} entries per {@code Span}. - */ - abstract int getMaxNumberOfLinks(); - - private static Builder builder() { - return new AutoValue_TraceParams.Builder(); - } - - abstract Builder toBuilder(); - - @AutoValue.Builder - abstract static class Builder { - - /** - * Sets the global default {@code Sampler}. It must be not {@code null} otherwise {@link - * #build()} will throw an exception. - * - * @param sampler the global default {@code Sampler}. - * @return this. - */ - abstract Builder setSampler(Sampler sampler); - - /** - * Sets the global default max number of attributes per {@link Span}. - * - * @param maxNumberOfAttributes the global default max number of attributes per {@link Span}. It - * must be positive otherwise {@link #build()} will throw an exception. - * @return this. - */ - abstract Builder setMaxNumberOfAttributes(int maxNumberOfAttributes); - - /** - * Sets the global default max number of {@link Annotation} events per {@link Span}. - * - * @param maxNumberOfAnnotations the global default max number of {@link Annotation} events per - * {@link Span}. It must be positive otherwise {@link #build()} will throw an exception. - * @return this. - */ - abstract Builder setMaxNumberOfAnnotations(int maxNumberOfAnnotations); - - /** - * Sets the global default max number of {@link NetworkEvent} events per {@link Span}. - * - * @param maxNumberOfNetworkEvents the global default max number of {@link NetworkEvent} events - * per {@link Span}. It must be positive otherwise {@link #build()} will throw an exception. - * @return this. - */ - abstract Builder setMaxNumberOfNetworkEvents(int maxNumberOfNetworkEvents); - - /** - * Sets the global default max number of {@link Link} entries per {@link Span}. - * - * @param maxNumberOfLinks the global default max number of {@link Link} entries per {@link - * Span}. It must be positive otherwise {@link #build()} will throw an exception. - * @return this. - */ - abstract Builder setMaxNumberOfLinks(int maxNumberOfLinks); - - abstract TraceParams autoBuild(); - - /** - * Builds and returns a {@code TraceParams} with the desired values. - * - * @return a {@code TraceParams} with the desired values. - * @throws NullPointerException if the sampler is null. - * @throws IllegalStateException if any of the max numbers are not positive. - */ - TraceParams build() { - TraceParams traceParams = autoBuild(); - checkNotNull(traceParams.getSampler(), "sampler"); - checkState(traceParams.getMaxNumberOfAttributes() > 0, "maxNumberOfAttributes"); - checkState(traceParams.getMaxNumberOfAnnotations() > 0, "maxNumberOfAnnotations"); - checkState(traceParams.getMaxNumberOfNetworkEvents() > 0, "maxNumberOfNetworkEvents"); - checkState(traceParams.getMaxNumberOfLinks() > 0, "maxNumberOfLinks"); - return traceParams; - } - } -} diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceConfigImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceConfigImplTest.java new file mode 100644 index 0000000000..584a3d6efb --- /dev/null +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceConfigImplTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.instrumentation.trace.TraceConfig.TraceParams; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TraceConfigImpl}. */ +@RunWith(JUnit4.class) +public class TraceConfigImplTest { + private final TraceConfigImpl traceConfig = new TraceConfigImpl(); + + @Test + public void defaultActiveTraceParams() { + assertThat(traceConfig.getActiveTraceParams()).isEqualTo(TraceParams.DEFAULT); + } + + @Test + public void updatePermanentelyTraceParams() { + TraceParams traceParams = + TraceParams.DEFAULT + .toBuilder() + .setSampler(Samplers.alwaysSample()) + .setMaxNumberOfAttributes(8) + .setMaxNumberOfAnnotations(9) + .setMaxNumberOfNetworkEvents(10) + .setMaxNumberOfLinks(11) + .build(); + traceConfig.updateActiveTraceParams(traceParams); + assertThat(traceConfig.getActiveTraceParams()).isEqualTo(traceParams); + traceConfig.updateActiveTraceParams(TraceParams.DEFAULT); + assertThat(traceConfig.getActiveTraceParams()).isEqualTo(TraceParams.DEFAULT); + } +} + From 23d3685cb3a795837c4e6015a66a04aab7130f5b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 4 May 2017 13:41:46 -0700 Subject: [PATCH 0042/1581] Simplify StatsManager by delegating stats operations to new a class, ViewManager. Classes in the StatsManager class hierarchy should just specify the classes that are used for different stats implementations. This commit moves all stats-handling logic out of StatsManagerImplBase into a new class, ViewManager. --- .../stats/StatsManagerImplBase.java | 96 ++------------ .../instrumentation/stats/ViewManager.java | 123 ++++++++++++++++++ 2 files changed, 132 insertions(+), 87 deletions(-) create mode 100644 core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java index 8c1eee7cec..78480a2f0f 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java @@ -15,66 +15,32 @@ import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.EventQueue; -import com.google.instrumentation.common.Function; -import com.google.instrumentation.stats.MutableView.MutableDistributionView; -import com.google.instrumentation.stats.MutableView.MutableIntervalView; -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; -import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; /** - * Native Implementation of {@link StatsManager}. + * Base implementation of {@link StatsManager}. */ class StatsManagerImplBase extends StatsManager { - private final EventQueue queue; - // clock used throughout the stats implementation - private final Clock clock; - - private final MeasurementDescriptorToViewMap measurementDescriptorToViewMap = - new MeasurementDescriptorToViewMap(); + // StatsManagerImplBase delegates all operations related to stats to ViewManager in order to keep + // StatsManagerImplBase simple. + private final ViewManager statsCollector; // The StatsContextFactoryImpl is lazily initialized because it references "this" and cannot be // created in the constructor. Multiple initializations are okay. private volatile StatsContextFactoryImpl statsContextFactory; StatsManagerImplBase(EventQueue queue, Clock clock) { - this.queue = queue; - this.clock = clock; + this.statsCollector = new ViewManager(queue, clock); } @Override public void registerView(ViewDescriptor viewDescriptor) { - // We are using a preset measurement RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY - // and view RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW for this prototype. - // The prototype does not allow setting measurement descriptor entries dynamically for now. - // TODO(songya): remove the logic for checking the preset descriptor. - if (!viewDescriptor.equals(SupportedViews.SUPPORTED_VIEW)) { - throw new UnsupportedOperationException( - "The prototype will only support Distribution View " - + SupportedViews.SUPPORTED_VIEW.getName()); - } - - if (measurementDescriptorToViewMap.getView(viewDescriptor, clock) != null) { - // Ignore views that are already registered. - return; - } - - MutableView mutableView = viewDescriptor.match( - new CreateMutableDistributionViewFunction(clock), new CreateMutableIntervalViewFunction()); - - measurementDescriptorToViewMap.putView( - viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName(), mutableView); + statsCollector.registerView(viewDescriptor); } @Override public View getView(ViewDescriptor viewDescriptor) { - View view = measurementDescriptorToViewMap.getView(viewDescriptor, clock); - if (view == null) { - throw new IllegalArgumentException( - "View for view descriptor " + viewDescriptor.getName() + " not found."); - } else { - return view; - } + return statsCollector.getView(viewDescriptor); } @Override @@ -92,52 +58,8 @@ StatsContextFactoryImpl getStatsContextFactory() { * @param tags the tags associated with the measurements * @param measurementValues the measurements to record */ + // TODO(sebright): Add this method to StatsManager. void record(StatsContextImpl tags, MeasurementMap measurementValues) { - queue.enqueue(new StatsEvent(this, tags, measurementValues)); - } - - // An EventQueue entry that records the stats from one call to StatsManager.record(...). - private static final class StatsEvent implements EventQueue.Entry { - private final StatsContextImpl tags; - private final MeasurementMap stats; - private final StatsManagerImplBase statsManager; - - StatsEvent( - StatsManagerImplBase statsManager, StatsContextImpl tags, MeasurementMap stats) { - this.statsManager = statsManager; - this.tags = tags; - this.stats = stats; - } - - @Override - public void process() { - statsManager - .measurementDescriptorToViewMap - .record(tags, stats); - } - } - - private static final class CreateMutableDistributionViewFunction - implements Function { - private final Clock clock; - - public CreateMutableDistributionViewFunction(Clock clock) { - this.clock = clock; - } - - @Override - public MutableView apply(DistributionViewDescriptor viewDescriptor) { - return MutableDistributionView.create( - viewDescriptor, clock.now()); - } - } - - private static final class CreateMutableIntervalViewFunction - implements Function { - @Override - public MutableView apply(IntervalViewDescriptor viewDescriptor) { - // TODO(songya): Create Interval Aggregations from internal Distributions. - return MutableIntervalView.create(viewDescriptor); - } + statsCollector.record(tags, measurementValues); } } diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java new file mode 100644 index 0000000000..e1f03fe41d --- /dev/null +++ b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java @@ -0,0 +1,123 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import com.google.instrumentation.common.Clock; +import com.google.instrumentation.common.EventQueue; +import com.google.instrumentation.common.Function; +import com.google.instrumentation.stats.MutableView.MutableDistributionView; +import com.google.instrumentation.stats.MutableView.MutableIntervalView; +import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; +import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; + +/** + * Object that stores all views and stats. + */ +final class ViewManager { + + private final EventQueue queue; + + // clock used throughout the stats implementation + private final Clock clock; + + private final MeasurementDescriptorToViewMap measurementDescriptorToViewMap = + new MeasurementDescriptorToViewMap(); + + ViewManager(EventQueue queue, Clock clock) { + this.queue = queue; + this.clock = clock; + } + + void registerView(ViewDescriptor viewDescriptor) { + // We are using a preset measurement RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY + // and view RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW for this prototype. + // The prototype does not allow setting measurement descriptor entries dynamically for now. + // TODO(songya): remove the logic for checking the preset descriptor. + if (!viewDescriptor.equals(SupportedViews.SUPPORTED_VIEW)) { + throw new UnsupportedOperationException( + "The prototype will only support Distribution View " + + SupportedViews.SUPPORTED_VIEW.getName()); + } + + if (measurementDescriptorToViewMap.getView(viewDescriptor, clock) != null) { + // Ignore views that are already registered. + return; + } + + MutableView mutableView = viewDescriptor.match( + new CreateMutableDistributionViewFunction(clock), new CreateMutableIntervalViewFunction()); + + measurementDescriptorToViewMap.putView( + viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName(), mutableView); + } + + View getView(ViewDescriptor viewDescriptor) { + View view = measurementDescriptorToViewMap.getView(viewDescriptor, clock); + if (view == null) { + throw new IllegalArgumentException( + "View for view descriptor " + viewDescriptor.getName() + " not found."); + } else { + return view; + } + } + + void record(StatsContextImpl tags, MeasurementMap measurementValues) { + queue.enqueue(new StatsEvent(this, tags, measurementValues)); + } + + // An EventQueue entry that records the stats from one call to StatsManager.record(...). + private static final class StatsEvent implements EventQueue.Entry { + private final StatsContextImpl tags; + private final MeasurementMap stats; + private final ViewManager statsCollector; + + StatsEvent( + ViewManager statsCollector, StatsContextImpl tags, MeasurementMap stats) { + this.statsCollector = statsCollector; + this.tags = tags; + this.stats = stats; + } + + @Override + public void process() { + statsCollector + .measurementDescriptorToViewMap + .record(tags, stats); + } + } + + private static final class CreateMutableDistributionViewFunction + implements Function { + private final Clock clock; + + CreateMutableDistributionViewFunction(Clock clock) { + this.clock = clock; + } + + @Override + public MutableView apply(DistributionViewDescriptor viewDescriptor) { + return MutableDistributionView.create( + viewDescriptor, clock.now()); + } + } + + private static final class CreateMutableIntervalViewFunction + implements Function { + @Override + public MutableView apply(IntervalViewDescriptor viewDescriptor) { + // TODO(songya): Create Interval Aggregations from internal Distributions. + return MutableIntervalView.create(viewDescriptor); + } + } +} From e085387ba75a550c7011b8414daef4ee279cc75f Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 4 May 2017 16:11:37 -0700 Subject: [PATCH 0043/1581] Rename a variable. --- .../instrumentation/stats/StatsManagerImplBase.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java index 78480a2f0f..5e2f54a90c 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java @@ -23,24 +23,24 @@ class StatsManagerImplBase extends StatsManager { // StatsManagerImplBase delegates all operations related to stats to ViewManager in order to keep // StatsManagerImplBase simple. - private final ViewManager statsCollector; + private final ViewManager viewManager; // The StatsContextFactoryImpl is lazily initialized because it references "this" and cannot be // created in the constructor. Multiple initializations are okay. private volatile StatsContextFactoryImpl statsContextFactory; StatsManagerImplBase(EventQueue queue, Clock clock) { - this.statsCollector = new ViewManager(queue, clock); + this.viewManager = new ViewManager(queue, clock); } @Override public void registerView(ViewDescriptor viewDescriptor) { - statsCollector.registerView(viewDescriptor); + viewManager.registerView(viewDescriptor); } @Override public View getView(ViewDescriptor viewDescriptor) { - return statsCollector.getView(viewDescriptor); + return viewManager.getView(viewDescriptor); } @Override @@ -60,6 +60,6 @@ StatsContextFactoryImpl getStatsContextFactory() { */ // TODO(sebright): Add this method to StatsManager. void record(StatsContextImpl tags, MeasurementMap measurementValues) { - statsCollector.record(tags, measurementValues); + viewManager.record(tags, measurementValues); } } From 59df59098494c17b9bae03278e6b9eafcb7cb156 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 4 May 2017 14:58:27 -0700 Subject: [PATCH 0044/1581] Remove an unused method. --- .../instrumentation/stats/MutableView.java | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java b/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java index 4a0eac4936..bb78442fa5 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java @@ -15,7 +15,6 @@ import com.google.common.annotations.VisibleForTesting; import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.Function; import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.stats.View.DistributionView; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; @@ -29,7 +28,6 @@ /** * A mutable version of {@link View}, used for recording stats and start/end time. */ -// TODO(songya): remove or modify the methods of this class, since it's not part of the API. abstract class MutableView { // TODO(songya): might want to update the default tag value later. @VisibleForTesting static final TagValue UNKNOWN_TAG_VALUE = TagValue.create("unknown/not set"); @@ -39,13 +37,6 @@ abstract class MutableView { */ abstract ViewDescriptor getViewDescriptor(); - /** - * Applies the given match function to the underlying data type. - */ - abstract T match( - Function p0, - Function p1); - /** * Record stats with the given tags. */ @@ -77,12 +68,6 @@ ViewDescriptor getViewDescriptor() { return distributionViewDescriptor; } - @Override - T match( - Function p0, Function p1) { - return p0.apply(this); - } - @Override void record(StatsContextImpl context, double value) { Map tags = context.tags; @@ -181,12 +166,6 @@ ViewDescriptor getViewDescriptor() { throw new UnsupportedOperationException("Not implemented."); } - @Override - T match( - Function p0, Function p1) { - throw new UnsupportedOperationException("Not implemented."); - } - @Override void record(StatsContextImpl tags, double value) { throw new UnsupportedOperationException("Not implemented."); From 519a25e39ed55bbcbbe3964d23e909b9603c7de5 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 4 May 2017 16:42:03 -0700 Subject: [PATCH 0045/1581] Remove some redundant keywords. --- .../instrumentation/stats/MeasurementDescriptorToViewMap.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java index 0471b3fc38..6c75e96479 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java @@ -36,7 +36,7 @@ final class MeasurementDescriptorToViewMap { /** * Returns a {@link View} corresponding to the given {@link ViewDescriptor}. */ - final View getView(ViewDescriptor viewDescriptor, Clock clock) { + View getView(ViewDescriptor viewDescriptor, Clock clock) { Collection views = mutableMap.get( viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); synchronized (mutableMap) { @@ -49,7 +49,7 @@ final View getView(ViewDescriptor viewDescriptor, Clock clock) { return null; } - private final MutableView getMutableView(ViewDescriptor viewDescriptor) { + private MutableView getMutableView(ViewDescriptor viewDescriptor) { Collection views = mutableMap.get( viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); synchronized (mutableMap) { From 85840dc3516389f1acf4df8db88a4fc872275290 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 4 May 2017 15:04:52 -0700 Subject: [PATCH 0046/1581] Refactor MeasurementDescriptorToViewMap.putView(...). Previously, ViewManager.registerView() called MeasurementDescriptorToViewMap.getView(...) followed by MeasurementDescriptorToViewMap.putView(...) to insert a view only if it was not present. There was no locking, so the view could be created multiple times. This commit refactors putView so that it covers the full transaction on the underlying multimap. It creates an empty MutableView if the view is not present and inserts it into the multimap. --- .../stats/MeasurementDescriptorToViewMap.java | 63 ++++++++++++++----- .../instrumentation/stats/ViewManager.java | 52 ++------------- .../MeasurementDescriptorToViewMapTest.java | 8 +-- 3 files changed, 56 insertions(+), 67 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java index 6c75e96479..7f6b6757ee 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java @@ -17,11 +17,16 @@ import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.google.instrumentation.common.Clock; +import com.google.instrumentation.common.Function; +import com.google.instrumentation.stats.MutableView.MutableDistributionView; +import com.google.instrumentation.stats.MutableView.MutableIntervalView; +import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; +import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Collection; /** - * A class that stores a singleton map from {@link MeasurementDescriptor.Name}s to - * {@link MutableView}s. + * A class that stores a singleton map from {@link MeasurementDescriptor.Name}s to {@link + * MutableView}s. */ final class MeasurementDescriptorToViewMap { @@ -33,12 +38,10 @@ final class MeasurementDescriptorToViewMap { Multimaps.synchronizedMultimap( HashMultimap.create()); - /** - * Returns a {@link View} corresponding to the given {@link ViewDescriptor}. - */ + /** Returns a {@link View} corresponding to the given {@link ViewDescriptor}. */ View getView(ViewDescriptor viewDescriptor, Clock clock) { - Collection views = mutableMap.get( - viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); + Collection views = + mutableMap.get(viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); synchronized (mutableMap) { for (MutableView view : views) { if (view.getViewDescriptor().equals(viewDescriptor)) { @@ -50,8 +53,8 @@ View getView(ViewDescriptor viewDescriptor, Clock clock) { } private MutableView getMutableView(ViewDescriptor viewDescriptor) { - Collection views = mutableMap.get( - viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); + Collection views = + mutableMap.get(viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); synchronized (mutableMap) { for (MutableView view : views) { if (view.getViewDescriptor().equals(viewDescriptor)) { @@ -62,11 +65,20 @@ private MutableView getMutableView(ViewDescriptor viewDescriptor) { return null; } - /** - * Map a new {@link View} to a {@link MeasurementDescriptor.Name}. - */ - void putView(MeasurementDescriptor.Name name, MutableView view) { - mutableMap.put(name, view); + /** Enable stats collection for the given {@link ViewDescriptor}. */ + void registerView(ViewDescriptor viewDescriptor, Clock clock) { + synchronized (mutableMap) { + if (getView(viewDescriptor, clock) != null) { + // Ignore views that are already registered. + return; + } + MutableView mutableView = + viewDescriptor.match( + new CreateMutableDistributionViewFunction(clock), + new CreateMutableIntervalViewFunction()); + mutableMap.put( + viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName(), mutableView); + } } // Records stats with a set of tags. @@ -89,4 +101,27 @@ private void recordSupportedMeasurement(StatsContextImpl tags, double value) { view.record(tags, value); } } + + private static final class CreateMutableDistributionViewFunction + implements Function { + private final Clock clock; + + CreateMutableDistributionViewFunction(Clock clock) { + this.clock = clock; + } + + @Override + public MutableView apply(DistributionViewDescriptor viewDescriptor) { + return MutableDistributionView.create(viewDescriptor, clock.now()); + } + } + + private static final class CreateMutableIntervalViewFunction + implements Function { + @Override + public MutableView apply(IntervalViewDescriptor viewDescriptor) { + // TODO(songya): Create Interval Aggregations from internal Distributions. + return MutableIntervalView.create(viewDescriptor); + } + } } diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java index e1f03fe41d..ba6f97b92a 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java @@ -15,15 +15,8 @@ import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.EventQueue; -import com.google.instrumentation.common.Function; -import com.google.instrumentation.stats.MutableView.MutableDistributionView; -import com.google.instrumentation.stats.MutableView.MutableIntervalView; -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; -import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; -/** - * Object that stores all views and stats. - */ +/** Object that stores all views and stats. */ final class ViewManager { private final EventQueue queue; @@ -49,17 +42,7 @@ void registerView(ViewDescriptor viewDescriptor) { "The prototype will only support Distribution View " + SupportedViews.SUPPORTED_VIEW.getName()); } - - if (measurementDescriptorToViewMap.getView(viewDescriptor, clock) != null) { - // Ignore views that are already registered. - return; - } - - MutableView mutableView = viewDescriptor.match( - new CreateMutableDistributionViewFunction(clock), new CreateMutableIntervalViewFunction()); - - measurementDescriptorToViewMap.putView( - viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName(), mutableView); + measurementDescriptorToViewMap.registerView(viewDescriptor, clock); } View getView(ViewDescriptor viewDescriptor) { @@ -82,8 +65,7 @@ private static final class StatsEvent implements EventQueue.Entry { private final MeasurementMap stats; private final ViewManager statsCollector; - StatsEvent( - ViewManager statsCollector, StatsContextImpl tags, MeasurementMap stats) { + StatsEvent(ViewManager statsCollector, StatsContextImpl tags, MeasurementMap stats) { this.statsCollector = statsCollector; this.tags = tags; this.stats = stats; @@ -91,33 +73,7 @@ private static final class StatsEvent implements EventQueue.Entry { @Override public void process() { - statsCollector - .measurementDescriptorToViewMap - .record(tags, stats); - } - } - - private static final class CreateMutableDistributionViewFunction - implements Function { - private final Clock clock; - - CreateMutableDistributionViewFunction(Clock clock) { - this.clock = clock; - } - - @Override - public MutableView apply(DistributionViewDescriptor viewDescriptor) { - return MutableDistributionView.create( - viewDescriptor, clock.now()); - } - } - - private static final class CreateMutableIntervalViewFunction - implements Function { - @Override - public MutableView apply(IntervalViewDescriptor viewDescriptor) { - // TODO(songya): Create Interval Aggregations from internal Distributions. - return MutableIntervalView.create(viewDescriptor); + statsCollector.measurementDescriptorToViewMap.record(tags, stats); } } } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java index 4cef662f58..9ec5707534 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java @@ -20,7 +20,6 @@ import com.google.instrumentation.common.Function; import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.internal.TestClock; -import com.google.instrumentation.stats.MutableView.MutableDistributionView; import com.google.instrumentation.stats.View.DistributionView; import com.google.instrumentation.stats.View.IntervalView; import org.junit.Test; @@ -34,11 +33,10 @@ public class MeasurementDescriptorToViewMapTest { new MeasurementDescriptorToViewMap(); @Test - public void testPutAndGetView() { + public void testRegisterAndGetView() { TestClock clock = TestClock.create(Timestamp.create(10, 20)); - measurementDescriptorToViewMap.putView( - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY.getMeasurementDescriptorName(), - MutableDistributionView.create(RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock.now())); + measurementDescriptorToViewMap.registerView( + RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock); clock.setTime(Timestamp.create(30, 40)); View actual = measurementDescriptorToViewMap.getView(RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock); actual.match( From ed85b779fe7768e14a15c27595f399029adf644c Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 4 May 2017 16:25:35 -0700 Subject: [PATCH 0047/1581] Use intrinsic locking in MeasurementDescriptorToViewMap. MeasurementDescriptorToViewMap previously used a SynchronizedMultimap for synchronization of its Multimap. However, every method ended up needing to access the Multimap within a synchronized block anyway, because the Multimap's values were not synchronized. It is simpler to just use a HashMultimap and synchronize on the whole MeasurementDescriptorToViewMap object. --- .../stats/MeasurementDescriptorToViewMap.java | 54 ++++++++----------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java index 7f6b6757ee..a031cce552 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java @@ -15,7 +15,6 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.Function; import com.google.instrumentation.stats.MutableView.MutableDistributionView; @@ -23,6 +22,7 @@ import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Collection; +import javax.annotation.concurrent.GuardedBy; /** * A class that stores a singleton map from {@link MeasurementDescriptor.Name}s to {@link @@ -34,55 +34,49 @@ final class MeasurementDescriptorToViewMap { * A synchronized singleton map that stores the one-to-many mapping from MeasurementDescriptors * to MutableViews. */ + @GuardedBy("this") private final Multimap mutableMap = - Multimaps.synchronizedMultimap( - HashMultimap.create()); + HashMultimap.create(); /** Returns a {@link View} corresponding to the given {@link ViewDescriptor}. */ - View getView(ViewDescriptor viewDescriptor, Clock clock) { + synchronized View getView(ViewDescriptor viewDescriptor, Clock clock) { Collection views = mutableMap.get(viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); - synchronized (mutableMap) { - for (MutableView view : views) { - if (view.getViewDescriptor().equals(viewDescriptor)) { - return view.toView(clock); - } + for (MutableView view : views) { + if (view.getViewDescriptor().equals(viewDescriptor)) { + return view.toView(clock); } } return null; } - private MutableView getMutableView(ViewDescriptor viewDescriptor) { + private synchronized MutableView getMutableView(ViewDescriptor viewDescriptor) { Collection views = mutableMap.get(viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); - synchronized (mutableMap) { - for (MutableView view : views) { - if (view.getViewDescriptor().equals(viewDescriptor)) { - return view; - } + for (MutableView view : views) { + if (view.getViewDescriptor().equals(viewDescriptor)) { + return view; } } return null; } /** Enable stats collection for the given {@link ViewDescriptor}. */ - void registerView(ViewDescriptor viewDescriptor, Clock clock) { - synchronized (mutableMap) { - if (getView(viewDescriptor, clock) != null) { - // Ignore views that are already registered. - return; - } - MutableView mutableView = - viewDescriptor.match( - new CreateMutableDistributionViewFunction(clock), - new CreateMutableIntervalViewFunction()); - mutableMap.put( - viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName(), mutableView); + synchronized void registerView(ViewDescriptor viewDescriptor, Clock clock) { + if (getView(viewDescriptor, clock) != null) { + // Ignore views that are already registered. + return; } + MutableView mutableView = + viewDescriptor.match( + new CreateMutableDistributionViewFunction(clock), + new CreateMutableIntervalViewFunction()); + mutableMap.put( + viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName(), mutableView); } // Records stats with a set of tags. - void record(StatsContextImpl tags, MeasurementMap stats) { + synchronized void record(StatsContextImpl tags, MeasurementMap stats) { for (MeasurementValue mv : stats) { if (mv.getMeasurement() .getMeasurementDescriptorName() @@ -97,9 +91,7 @@ private void recordSupportedMeasurement(StatsContextImpl tags, double value) { if (view == null) { throw new IllegalArgumentException("View not registered yet."); } - synchronized (mutableMap) { - view.record(tags, value); - } + view.record(tags, value); } private static final class CreateMutableDistributionViewFunction From 573229946f09ca978bcda434a1356885a2bb1ef6 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 5 May 2017 09:41:14 -0700 Subject: [PATCH 0048/1581] Rename a variable. --- .../com/google/instrumentation/stats/ViewManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java index ba6f97b92a..12aa5d0960 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java @@ -63,17 +63,17 @@ void record(StatsContextImpl tags, MeasurementMap measurementValues) { private static final class StatsEvent implements EventQueue.Entry { private final StatsContextImpl tags; private final MeasurementMap stats; - private final ViewManager statsCollector; + private final ViewManager viewManager; - StatsEvent(ViewManager statsCollector, StatsContextImpl tags, MeasurementMap stats) { - this.statsCollector = statsCollector; + StatsEvent(ViewManager viewManager, StatsContextImpl tags, MeasurementMap stats) { + this.viewManager = viewManager; this.tags = tags; this.stats = stats; } @Override public void process() { - statsCollector.measurementDescriptorToViewMap.record(tags, stats); + viewManager.measurementDescriptorToViewMap.record(tags, stats); } } } From f9d0da7ab7bbd291f9799a46d65a9faad22f148d Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 5 May 2017 09:47:27 -0700 Subject: [PATCH 0049/1581] Refactor getView to call getMutableView. --- .../stats/MeasurementDescriptorToViewMap.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java index a031cce552..6ab2e18103 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java @@ -40,14 +40,8 @@ final class MeasurementDescriptorToViewMap { /** Returns a {@link View} corresponding to the given {@link ViewDescriptor}. */ synchronized View getView(ViewDescriptor viewDescriptor, Clock clock) { - Collection views = - mutableMap.get(viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); - for (MutableView view : views) { - if (view.getViewDescriptor().equals(viewDescriptor)) { - return view.toView(clock); - } - } - return null; + MutableView view = getMutableView(viewDescriptor); + return view == null ? null : view.toView(clock); } private synchronized MutableView getMutableView(ViewDescriptor viewDescriptor) { From 9b18e97b092b0b7d3a97cdb07a09e366479dd20c Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 5 May 2017 09:49:31 -0700 Subject: [PATCH 0050/1581] Call getMutableView instead of getView to avoid creating unnecessary View. --- .../instrumentation/stats/MeasurementDescriptorToViewMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java index 6ab2e18103..e04809dda5 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java @@ -57,7 +57,7 @@ private synchronized MutableView getMutableView(ViewDescriptor viewDescriptor) { /** Enable stats collection for the given {@link ViewDescriptor}. */ synchronized void registerView(ViewDescriptor viewDescriptor, Clock clock) { - if (getView(viewDescriptor, clock) != null) { + if (getMutableView(viewDescriptor) != null) { // Ignore views that are already registered. return; } From c8b0c4d8278d77440e2ce50306e605cfba146bbd Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 5 May 2017 13:33:25 -0700 Subject: [PATCH 0051/1581] Make View's lists of aggregations immutable. --- .../main/java/com/google/instrumentation/stats/View.java | 9 +++++++-- .../instrumentation/stats/StatsManagerImplTest.java | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/View.java b/core/src/main/java/com/google/instrumentation/stats/View.java index 9099696020..304433386c 100644 --- a/core/src/main/java/com/google/instrumentation/stats/View.java +++ b/core/src/main/java/com/google/instrumentation/stats/View.java @@ -18,6 +18,8 @@ import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -96,7 +98,9 @@ public T match( private DistributionView(DistributionViewDescriptor distributionViewDescriptor, List distributionAggregations, Timestamp start, Timestamp end) { this.distributionViewDescriptor = distributionViewDescriptor; - this.distributionAggregations = distributionAggregations; + this.distributionAggregations = + Collections.unmodifiableList( + new ArrayList(distributionAggregations)); this.start = start; this.end = end; } @@ -142,7 +146,8 @@ public T match( private IntervalView(IntervalViewDescriptor intervalViewDescriptor, List intervalAggregations) { this.intervalViewDescriptor = intervalViewDescriptor; - this.intervalAggregations = intervalAggregations; + this.intervalAggregations = + Collections.unmodifiableList(new ArrayList(intervalAggregations)); } } } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 396f43ced3..2e2beb547a 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -20,6 +20,7 @@ import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.internal.TestClock; import com.google.instrumentation.stats.View.DistributionView; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; @@ -127,7 +128,8 @@ public void testRecordMultipleTagValues() { DistributionView view = (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - List distributionAggregations = view.getDistributionAggregations(); + List distributionAggregations = + new ArrayList(view.getDistributionAggregations()); assertThat(distributionAggregations).hasSize(2); // Sort distributionAggregations by count. Collections.sort(distributionAggregations, new Comparator() { From 8c079908d6c229e863b209cfe4e6b5951cab64f2 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Sun, 7 May 2017 12:09:41 -0700 Subject: [PATCH 0052/1581] Update BinaryPropagationHandler to not be a singleton to be consistent with other implementations. (#282) * Update BinaryPropagationHandler to not be a singleton to be consistent with other implementations. --- .../trace/BinaryPropagationHandlerImplBenchmark.java | 2 +- .../instrumentation/trace/BinaryPropagationHandlerImpl.java | 6 ++---- .../instrumentation/trace/TraceComponentImplBase.java | 4 ++-- .../trace/BinaryPropagationHandlerImplTest.java | 6 +++--- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/benchmarks/src/jmh/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplBenchmark.java b/benchmarks/src/jmh/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplBenchmark.java index e0f1ff114c..fc8d9846c2 100644 --- a/benchmarks/src/jmh/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplBenchmark.java +++ b/benchmarks/src/jmh/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplBenchmark.java @@ -34,7 +34,7 @@ public class BinaryPropagationHandlerImplBenchmark { private static final TraceOptions traceOptions = TraceOptions.fromBytes(traceOptionsBytes); private static final SpanContext spanContext = SpanContext.create(traceId, spanId, traceOptions); private static final BinaryPropagationHandler binaryPropagationHandler = - BinaryPropagationHandlerImpl.INSTANCE; + new BinaryPropagationHandlerImpl(); private static final byte[] spanContextBinary = binaryPropagationHandler.toBinaryValue(spanContext); diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/BinaryPropagationHandlerImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/BinaryPropagationHandlerImpl.java index 471249bf41..2a4532794b 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/BinaryPropagationHandlerImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/BinaryPropagationHandlerImpl.java @@ -53,8 +53,6 @@ * */ final class BinaryPropagationHandlerImpl extends BinaryPropagationHandler { - static final BinaryPropagationHandlerImpl INSTANCE = new BinaryPropagationHandlerImpl(); - private static final byte VERSION_ID = 0; private static final int VERSION_ID_OFFSET = 0; // The version_id/field_id size in bytes. @@ -71,6 +69,8 @@ final class BinaryPropagationHandlerImpl extends BinaryPropagationHandler { private static final int FORMAT_LENGTH = 4 * ID_SIZE + TraceId.SIZE + SpanId.SIZE + TraceOptions.SIZE; + BinaryPropagationHandlerImpl() {} + @Override public byte[] toBinaryValue(SpanContext spanContext) { checkNotNull(spanContext, "spanContext"); @@ -112,6 +112,4 @@ public SpanContext fromBinaryValue(byte[] bytes) throws ParseException { throw new ParseException("Invalid input: " + e.toString(), pos); } } - - private BinaryPropagationHandlerImpl() {} } diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java index 6d7e389e63..f2aacf1b36 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java @@ -18,8 +18,8 @@ /** Base implementation of the {@link TraceComponent}. */ public class TraceComponentImplBase extends TraceComponent { private static final Tracer tracer = Tracer.getNoopTracer(); - private static final BinaryPropagationHandler binaryPropagationHandler = - BinaryPropagationHandlerImpl.INSTANCE; + private final BinaryPropagationHandlerImpl binaryPropagationHandler = + new BinaryPropagationHandlerImpl(); private final Clock clock; private final TraceExporter traceExporter = TraceExporter.getNoopTraceExporter(); private final TraceConfig traceConfig = new TraceConfigImpl(); diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplTest.java index 1f9b4d35b3..20c11c6f38 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplTest.java @@ -41,10 +41,10 @@ public class BinaryPropagationHandlerImplTest { private static final SpanContext EXAMPLE_SPAN_CONTEXT = SpanContext.create(TRACE_ID, SPAN_ID, TRACE_OPTIONS); @Rule public ExpectedException expectedException = ExpectedException.none(); - private static final BinaryPropagationHandler binaryPropagationHandler = - BinaryPropagationHandlerImpl.INSTANCE; + private final BinaryPropagationHandler binaryPropagationHandler = + new BinaryPropagationHandlerImpl(); - private static void testSpanContextConversion(SpanContext spanContext) throws ParseException { + private void testSpanContextConversion(SpanContext spanContext) throws ParseException { SpanContext propagatedBinarySpanContext = binaryPropagationHandler.fromBinaryValue( binaryPropagationHandler.toBinaryValue(spanContext)); From 1bbefa6511468dee9fe493adff84920f357adbbe Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 5 May 2017 15:03:03 -0700 Subject: [PATCH 0053/1581] Add a class to represent a ViewDescriptor name. This class can be used to query Views, since ViewDescriptor names must be unique. This commit also prevents a view from being registered if it has the same name as an existing view but is not the same view. --- .../instrumentation/stats/ViewDescriptor.java | 79 +++++++++++++++++-- .../stats/ViewDescriptorTest.java | 15 ++++ .../stats/MeasurementDescriptorToViewMap.java | 41 +++++++--- .../stats/StatsManagerImplBase.java | 3 +- .../instrumentation/stats/ViewManager.java | 6 +- .../MeasurementDescriptorToViewMapTest.java | 4 +- .../stats/StatsManagerImplTest.java | 19 +++++ 7 files changed, 147 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java b/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java index c1226b7af4..b4a30ab8fe 100644 --- a/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java +++ b/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java @@ -13,6 +13,7 @@ package com.google.instrumentation.stats; +import com.google.auto.value.AutoValue; import com.google.instrumentation.common.Function; import java.util.ArrayList; @@ -27,10 +28,17 @@ public abstract class ViewDescriptor { /** * Name of view. Must be unique. */ - public final String getName() { + public final Name getViewDescriptorName() { return name; } + /** + * Name of view, as a {@code String}. + */ + public final String getName() { + return name.asString(); + } + /** * More detailed description, for documentation purposes. */ @@ -64,13 +72,13 @@ public abstract T match( Function p1); - private final String name; + private final Name name; private final String description; private final MeasurementDescriptor measurementDescriptor; private final List tagKeys; private ViewDescriptor( - String name, + Name name, String description, MeasurementDescriptor measurementDescriptor, List tagKeys) { @@ -80,6 +88,33 @@ private ViewDescriptor( this.tagKeys = Collections.unmodifiableList(new ArrayList(tagKeys)); } + /** + * The name of a {@code ViewDescriptor}. + */ + // This type should be used as the key when associating data with ViewDescriptors. + @AutoValue + public abstract static class Name { + + Name() {} + + /** + * Returns the name as a {@code String}. + * + * @return the name as a {@code String}. + */ + public abstract String asString(); + + /** + * Creates a {@code ViewDescriptor.Name} from a {@code String}. + * + * @param name the name {@code String}. + * @return a {@code ViewDescriptor.Name} with the given name {@code String}. + */ + public static Name create(String name) { + return new AutoValue_ViewDescriptor_Name(name); + } + } + /** * A {@link ViewDescriptor} for distribution-base aggregations. */ @@ -93,6 +128,23 @@ public static DistributionViewDescriptor create( MeasurementDescriptor measurementDescriptor, DistributionAggregationDescriptor distributionAggregationDescriptor, List tagKeys) { + return new DistributionViewDescriptor( + Name.create(name), + description, + measurementDescriptor, + distributionAggregationDescriptor, + tagKeys); + } + + /** + * Constructs a new {@link DistributionViewDescriptor}. + */ + public static DistributionViewDescriptor create( + Name name, + String description, + MeasurementDescriptor measurementDescriptor, + DistributionAggregationDescriptor distributionAggregationDescriptor, + List tagKeys) { return new DistributionViewDescriptor( name, description, measurementDescriptor, distributionAggregationDescriptor, tagKeys); } @@ -115,7 +167,7 @@ public T match( private final DistributionAggregationDescriptor distributionAggregationDescriptor; private DistributionViewDescriptor( - String name, + Name name, String description, MeasurementDescriptor measurementDescriptor, DistributionAggregationDescriptor distributionAggregationDescriptor, @@ -138,6 +190,23 @@ public static IntervalViewDescriptor create( MeasurementDescriptor measurementDescriptor, IntervalAggregationDescriptor intervalAggregationDescriptor, List tagKeys) { + return new IntervalViewDescriptor( + Name.create(name), + description, + measurementDescriptor, + intervalAggregationDescriptor, + tagKeys); + } + + /** + * Constructs a new {@link IntervalViewDescriptor}. + */ + public static IntervalViewDescriptor create( + Name name, + String description, + MeasurementDescriptor measurementDescriptor, + IntervalAggregationDescriptor intervalAggregationDescriptor, + List tagKeys) { return new IntervalViewDescriptor( name, description, measurementDescriptor, intervalAggregationDescriptor, tagKeys); } @@ -160,7 +229,7 @@ public T match( private final IntervalAggregationDescriptor intervalAggregationDescriptor; private IntervalViewDescriptor( - String name, + Name name, String description, MeasurementDescriptor measurementDescriptor, IntervalAggregationDescriptor intervalAggregationDescriptor, diff --git a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java index 570a3dec5b..8020332aea 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java @@ -17,6 +17,7 @@ import static org.junit.Assert.assertTrue; +import com.google.common.testing.EqualsTester; import com.google.instrumentation.common.Duration; import com.google.instrumentation.common.Function; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; @@ -88,6 +89,20 @@ public void testIntervalViewDescriptor() { })); } + @Test + public void testViewDescriptorName() { + assertThat(ViewDescriptor.Name.create("my name").asString()).isEqualTo("my name"); + } + + @Test + public void testViewDescriptorNameEquals() { + new EqualsTester() + .addEqualityGroup( + ViewDescriptor.Name.create("view-1"), ViewDescriptor.Name.create("view-1")) + .addEqualityGroup(ViewDescriptor.Name.create("view-2")) + .testEquals(); + } + private final String name = "test-view-name"; private final String description = "test-view-name description"; private final MeasurementDescriptor measurementDescriptor = MeasurementDescriptor.create( diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java index e04809dda5..d34a7770e2 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java @@ -22,6 +22,9 @@ import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; /** @@ -38,29 +41,47 @@ final class MeasurementDescriptorToViewMap { private final Multimap mutableMap = HashMultimap.create(); - /** Returns a {@link View} corresponding to the given {@link ViewDescriptor}. */ - synchronized View getView(ViewDescriptor viewDescriptor, Clock clock) { - MutableView view = getMutableView(viewDescriptor); + @GuardedBy("this") + private final Map registeredViews = + new HashMap(); + + /** Returns a {@link View} corresponding to the given {@link ViewDescriptor.Name}. */ + synchronized View getView(ViewDescriptor.Name viewName, Clock clock) { + MutableView view = getMutableView(viewName); return view == null ? null : view.toView(clock); } - private synchronized MutableView getMutableView(ViewDescriptor viewDescriptor) { + @Nullable + private synchronized MutableView getMutableView(ViewDescriptor.Name viewName) { + ViewDescriptor viewDescriptor = registeredViews.get(viewName); + if (viewDescriptor == null) { + return null; + } Collection views = mutableMap.get(viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); for (MutableView view : views) { - if (view.getViewDescriptor().equals(viewDescriptor)) { + if (view.getViewDescriptor().getViewDescriptorName().equals(viewName)) { return view; } } - return null; + throw new AssertionError("registeredViews and mutableMap contain different views: " + + "registeredViews=" + registeredViews + ", mutableMap=" + mutableMap); } /** Enable stats collection for the given {@link ViewDescriptor}. */ synchronized void registerView(ViewDescriptor viewDescriptor, Clock clock) { - if (getMutableView(viewDescriptor) != null) { - // Ignore views that are already registered. - return; + ViewDescriptor existing = registeredViews.get(viewDescriptor.getViewDescriptorName()); + if (existing != null) { + // TODO(sebright): Override equals(...) in ViewDescriptor. + if (existing.equals(viewDescriptor)) { + // Ignore views that are already registered. + return; + } else { + throw new IllegalArgumentException( + "A different view with the same name is already registered: " + existing); + } } + registeredViews.put(viewDescriptor.getViewDescriptorName(), viewDescriptor); MutableView mutableView = viewDescriptor.match( new CreateMutableDistributionViewFunction(clock), @@ -81,7 +102,7 @@ synchronized void record(StatsContextImpl tags, MeasurementMap stats) { } private void recordSupportedMeasurement(StatsContextImpl tags, double value) { - MutableView view = getMutableView(SupportedViews.SUPPORTED_VIEW); + MutableView view = getMutableView(SupportedViews.SUPPORTED_VIEW.getViewDescriptorName()); if (view == null) { throw new IllegalArgumentException("View not registered yet."); } diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java index 5e2f54a90c..30a883f18c 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java @@ -38,9 +38,10 @@ public void registerView(ViewDescriptor viewDescriptor) { viewManager.registerView(viewDescriptor); } + // TODO(sebright): This method should take a ViewDescriptor.Name. @Override public View getView(ViewDescriptor viewDescriptor) { - return viewManager.getView(viewDescriptor); + return viewManager.getView(viewDescriptor.getViewDescriptorName()); } @Override diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java index 12aa5d0960..243313107f 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java @@ -45,11 +45,11 @@ void registerView(ViewDescriptor viewDescriptor) { measurementDescriptorToViewMap.registerView(viewDescriptor, clock); } - View getView(ViewDescriptor viewDescriptor) { - View view = measurementDescriptorToViewMap.getView(viewDescriptor, clock); + View getView(ViewDescriptor.Name viewName) { + View view = measurementDescriptorToViewMap.getView(viewName, clock); if (view == null) { throw new IllegalArgumentException( - "View for view descriptor " + viewDescriptor.getName() + " not found."); + "View for view descriptor " + viewName + " not found."); } else { return view; } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java index 9ec5707534..c6e219c22d 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java @@ -38,7 +38,9 @@ public void testRegisterAndGetView() { measurementDescriptorToViewMap.registerView( RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock); clock.setTime(Timestamp.create(30, 40)); - View actual = measurementDescriptorToViewMap.getView(RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock); + View actual = + measurementDescriptorToViewMap.getView( + RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW.getViewDescriptorName(), clock); actual.match( new Function() { @Override diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 2e2beb547a..f935124ff9 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -20,11 +20,13 @@ import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.internal.TestClock; import com.google.instrumentation.stats.View.DistributionView; +import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -82,6 +84,23 @@ public void testRegisterViewDescriptorTwice() { RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); } + // TODO(sebright) Enable this test once we support more than one view. + @Ignore + @Test + public void preventRegisteringDifferentViewDescriptorWithSameName() { + statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + ViewDescriptor view2 = + DistributionViewDescriptor.create( + "grpc.io/client/roundtrip_latency/distribution_cumulative", + "This is a different description.", + RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, + DistributionAggregationDescriptor.create(RpcViewConstants.RPC_MILLIS_BUCKET_BOUNDARIES), + Arrays.asList(RpcMeasurementConstants.RPC_CLIENT_METHOD)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("A different view with the same name is already registered"); + statsManager.registerView(view2); + } + @Test public void testGetNonexistentView() throws Exception { thrown.expect(IllegalArgumentException.class); From 8b3a262a9822489cf06e342ded67ddcaa77ebbf8 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 5 May 2017 16:38:35 -0700 Subject: [PATCH 0054/1581] Test ViewDescriptor.getViewDescriptorName(). --- .../google/instrumentation/stats/ViewDescriptorTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java index 8020332aea..31d57a1305 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java @@ -42,7 +42,8 @@ public void testDistributionViewDescriptor() { final ViewDescriptor viewDescriptor = DistributionViewDescriptor.create( name, description, measurementDescriptor, dAggrDescriptor, keys); - assertThat(viewDescriptor.getName()).isEqualTo(name); + assertThat(viewDescriptor.getViewDescriptorName()).isEqualTo(name); + assertThat(viewDescriptor.getName()).isEqualTo(name.asString()); assertThat(viewDescriptor.getDescription()).isEqualTo(description); assertThat(viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()) .isEqualTo(measurementDescriptor.getMeasurementDescriptorName()); @@ -69,7 +70,8 @@ public void testIntervalViewDescriptor() { final ViewDescriptor viewDescriptor = IntervalViewDescriptor.create( name, description, measurementDescriptor, iAggrDescriptor, keys); - assertThat(viewDescriptor.getName()).isEqualTo(name); + assertThat(viewDescriptor.getViewDescriptorName()).isEqualTo(name); + assertThat(viewDescriptor.getName()).isEqualTo(name.asString()); assertThat(viewDescriptor.getDescription()).isEqualTo(description); assertThat(viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()) .isEqualTo(measurementDescriptor.getMeasurementDescriptorName()); @@ -103,7 +105,7 @@ public void testViewDescriptorNameEquals() { .testEquals(); } - private final String name = "test-view-name"; + private final ViewDescriptor.Name name = ViewDescriptor.Name.create("test-view-name"); private final String description = "test-view-name description"; private final MeasurementDescriptor measurementDescriptor = MeasurementDescriptor.create( "measurement", From 7db65da5d16526343ea7dbfb6b1e2d0c64fac269 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 5 May 2017 16:39:53 -0700 Subject: [PATCH 0055/1581] Use AutoValue to implement ViewDescriptor. --- .../instrumentation/stats/ViewDescriptor.java | 93 +++++-------------- .../stats/ViewDescriptorTest.java | 25 +++++ .../stats/MeasurementDescriptorToViewMap.java | 1 - 3 files changed, 50 insertions(+), 69 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java b/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java index b4a30ab8fe..3212a30ddb 100644 --- a/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java +++ b/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java @@ -28,30 +28,24 @@ public abstract class ViewDescriptor { /** * Name of view. Must be unique. */ - public final Name getViewDescriptorName() { - return name; - } + public abstract Name getViewDescriptorName(); /** * Name of view, as a {@code String}. */ public final String getName() { - return name.asString(); + return getViewDescriptorName().asString(); } /** * More detailed description, for documentation purposes. */ - public final String getDescription() { - return description; - } + public abstract String getDescription(); /** * Measurement type of this view. */ - public final MeasurementDescriptor getMeasurementDescriptor() { - return measurementDescriptor; - } + public abstract MeasurementDescriptor getMeasurementDescriptor(); /** * Tag keys to match with the associated {@link MeasurementDescriptor}. If no keys are specified, @@ -60,9 +54,7 @@ public final MeasurementDescriptor getMeasurementDescriptor() { *

Note: The returned list is unmodifiable, attempts to update it will throw an * UnsupportedOperationException. */ - public final List getTagKeys() { - return tagKeys; - } + public abstract List getTagKeys(); /** * Applies the given match function to the underlying data type. @@ -71,23 +63,6 @@ public abstract T match( Function p0, Function p1); - - private final Name name; - private final String description; - private final MeasurementDescriptor measurementDescriptor; - private final List tagKeys; - - private ViewDescriptor( - Name name, - String description, - MeasurementDescriptor measurementDescriptor, - List tagKeys) { - this.name = name; - this.description = description; - this.measurementDescriptor = measurementDescriptor; - this.tagKeys = Collections.unmodifiableList(new ArrayList(tagKeys)); - } - /** * The name of a {@code ViewDescriptor}. */ @@ -118,7 +93,8 @@ public static Name create(String name) { /** * A {@link ViewDescriptor} for distribution-base aggregations. */ - public static class DistributionViewDescriptor extends ViewDescriptor { + @AutoValue + public abstract static class DistributionViewDescriptor extends ViewDescriptor { /** * Constructs a new {@link DistributionViewDescriptor}. */ @@ -128,7 +104,7 @@ public static DistributionViewDescriptor create( MeasurementDescriptor measurementDescriptor, DistributionAggregationDescriptor distributionAggregationDescriptor, List tagKeys) { - return new DistributionViewDescriptor( + return create( Name.create(name), description, measurementDescriptor, @@ -145,17 +121,19 @@ public static DistributionViewDescriptor create( MeasurementDescriptor measurementDescriptor, DistributionAggregationDescriptor distributionAggregationDescriptor, List tagKeys) { - return new DistributionViewDescriptor( - name, description, measurementDescriptor, distributionAggregationDescriptor, tagKeys); + return new AutoValue_ViewDescriptor_DistributionViewDescriptor( + name, + description, + measurementDescriptor, + Collections.unmodifiableList(new ArrayList(tagKeys)), + distributionAggregationDescriptor); } /** * The {@link DistributionAggregationDescriptor} associated with this * {@link DistributionViewDescriptor}. */ - public DistributionAggregationDescriptor getDistributionAggregationDescriptor() { - return distributionAggregationDescriptor; - } + public abstract DistributionAggregationDescriptor getDistributionAggregationDescriptor(); @Override public T match( @@ -163,24 +141,13 @@ public T match( Function p1) { return p0.apply(this); } - - private final DistributionAggregationDescriptor distributionAggregationDescriptor; - - private DistributionViewDescriptor( - Name name, - String description, - MeasurementDescriptor measurementDescriptor, - DistributionAggregationDescriptor distributionAggregationDescriptor, - List tagKeys) { - super(name, description, measurementDescriptor, tagKeys); - this.distributionAggregationDescriptor = distributionAggregationDescriptor; - } } /** * A {@link ViewDescriptor} for interval-based aggregations. */ - public static class IntervalViewDescriptor extends ViewDescriptor { + @AutoValue + public abstract static class IntervalViewDescriptor extends ViewDescriptor { /** * Constructs a new {@link IntervalViewDescriptor}. */ @@ -190,7 +157,7 @@ public static IntervalViewDescriptor create( MeasurementDescriptor measurementDescriptor, IntervalAggregationDescriptor intervalAggregationDescriptor, List tagKeys) { - return new IntervalViewDescriptor( + return create( Name.create(name), description, measurementDescriptor, @@ -207,17 +174,19 @@ public static IntervalViewDescriptor create( MeasurementDescriptor measurementDescriptor, IntervalAggregationDescriptor intervalAggregationDescriptor, List tagKeys) { - return new IntervalViewDescriptor( - name, description, measurementDescriptor, intervalAggregationDescriptor, tagKeys); + return new AutoValue_ViewDescriptor_IntervalViewDescriptor( + name, + description, + measurementDescriptor, + Collections.unmodifiableList(new ArrayList(tagKeys)), + intervalAggregationDescriptor); } /** * The {@link IntervalAggregationDescriptor} associated with this * {@link IntervalViewDescriptor}. */ - public IntervalAggregationDescriptor getIntervalAggregationDescriptor() { - return intervalAggregationDescriptor; - } + public abstract IntervalAggregationDescriptor getIntervalAggregationDescriptor(); @Override public T match( @@ -225,17 +194,5 @@ public T match( Function p1) { return p1.apply(this); } - - private final IntervalAggregationDescriptor intervalAggregationDescriptor; - - private IntervalViewDescriptor( - Name name, - String description, - MeasurementDescriptor measurementDescriptor, - IntervalAggregationDescriptor intervalAggregationDescriptor, - List tagKeys) { - super(name, description, measurementDescriptor, tagKeys); - this.intervalAggregationDescriptor = intervalAggregationDescriptor; - } } } diff --git a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java index 31d57a1305..4b78e5a20b 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java @@ -91,6 +91,31 @@ public void testIntervalViewDescriptor() { })); } + @Test + public void testViewDescriptorEquals() { + DistributionAggregationDescriptor dAggrDescriptor = DistributionAggregationDescriptor.create(); + IntervalAggregationDescriptor iAggrDescriptor = IntervalAggregationDescriptor.create( + Arrays.asList(Duration.fromMillis(1), Duration.fromMillis(22), Duration.fromMillis(333))); + new EqualsTester() + .addEqualityGroup( + DistributionViewDescriptor.create( + name, description, measurementDescriptor, dAggrDescriptor, keys), + DistributionViewDescriptor.create( + name, description, measurementDescriptor, dAggrDescriptor, keys)) + .addEqualityGroup( + DistributionViewDescriptor.create( + name, description + 2, measurementDescriptor, dAggrDescriptor, keys)) + .addEqualityGroup( + IntervalViewDescriptor.create( + name, description, measurementDescriptor, iAggrDescriptor, keys), + IntervalViewDescriptor.create( + name, description, measurementDescriptor, iAggrDescriptor, keys)) + .addEqualityGroup( + IntervalViewDescriptor.create( + name, description + 2, measurementDescriptor, iAggrDescriptor, keys)) + .testEquals(); + } + @Test public void testViewDescriptorName() { assertThat(ViewDescriptor.Name.create("my name").asString()).isEqualTo("my name"); diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java index d34a7770e2..1a795b3154 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java @@ -72,7 +72,6 @@ private synchronized MutableView getMutableView(ViewDescriptor.Name viewName) { synchronized void registerView(ViewDescriptor viewDescriptor, Clock clock) { ViewDescriptor existing = registeredViews.get(viewDescriptor.getViewDescriptorName()); if (existing != null) { - // TODO(sebright): Override equals(...) in ViewDescriptor. if (existing.equals(viewDescriptor)) { // Ignore views that are already registered. return; From 576216de96b451a86de98a4ceb74e5e6daf64539 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Sun, 7 May 2017 13:59:17 -0700 Subject: [PATCH 0056/1581] Test that ViewDescriptors cannot be created with null names. --- .../stats/ViewDescriptorTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java index 4b78e5a20b..1385b9a87e 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java @@ -116,6 +116,46 @@ public void testViewDescriptorEquals() { .testEquals(); } + @Test(expected = NullPointerException.class) + public void preventNullDistributionViewDescriptorName() { + DistributionViewDescriptor.create( + (ViewDescriptor.Name) null, + description, + measurementDescriptor, + DistributionAggregationDescriptor.create(), + keys); + } + + @Test(expected = NullPointerException.class) + public void preventNullDistributionViewDescriptorStringName() { + DistributionViewDescriptor.create( + (String) null, + description, + measurementDescriptor, + DistributionAggregationDescriptor.create(), + keys); + } + + @Test(expected = NullPointerException.class) + public void preventNullIntervalViewDescriptorName() { + IntervalViewDescriptor.create( + (ViewDescriptor.Name) null, + description, + measurementDescriptor, + IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(1))), + keys); + } + + @Test(expected = NullPointerException.class) + public void preventNullIntervalViewDescriptorStringName() { + IntervalViewDescriptor.create( + (String) null, + description, + measurementDescriptor, + IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(1))), + keys); + } + @Test public void testViewDescriptorName() { assertThat(ViewDescriptor.Name.create("my name").asString()).isEqualTo("my name"); From c34c42ad309fe9932c0c54f8b50688a31d7eb78e Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Sun, 7 May 2017 13:59:17 -0700 Subject: [PATCH 0057/1581] Test that ViewDescriptor.Names cannot be created with null strings. --- .../com/google/instrumentation/stats/ViewDescriptorTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java index 1385b9a87e..89f843c454 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java @@ -161,6 +161,11 @@ public void testViewDescriptorName() { assertThat(ViewDescriptor.Name.create("my name").asString()).isEqualTo("my name"); } + @Test(expected = NullPointerException.class) + public void preventNullNameString() { + ViewDescriptor.Name.create(null); + } + @Test public void testViewDescriptorNameEquals() { new EqualsTester() From 59d39c9ce342a18237e1b119f7d0549485db8047 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Sun, 7 May 2017 13:59:17 -0700 Subject: [PATCH 0058/1581] Improve assertion error message. --- .../instrumentation/stats/MeasurementDescriptorToViewMap.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java index 1a795b3154..5534e82230 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java @@ -64,8 +64,8 @@ private synchronized MutableView getMutableView(ViewDescriptor.Name viewName) { return view; } } - throw new AssertionError("registeredViews and mutableMap contain different views: " - + "registeredViews=" + registeredViews + ", mutableMap=" + mutableMap); + throw new AssertionError("Internal error: Not recording stats for view: \"" + viewName + + "\" registeredViews=" + registeredViews + ", mutableMap=" + mutableMap); } /** Enable stats collection for the given {@link ViewDescriptor}. */ From 597a476bd13b087679fd227db712faf89addf903 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Sun, 7 May 2017 16:00:34 -0700 Subject: [PATCH 0059/1581] Add hasRemoteParent property to SpanImpl and SpanData. (#283) --- .../instrumentation/trace/SpanData.java | 10 ++++ .../instrumentation/trace/SpanDataTest.java | 56 +++++++++++-------- .../instrumentation/trace/SpanImpl.java | 9 ++- .../instrumentation/trace/SpanImplTest.java | 11 ++++ 4 files changed, 61 insertions(+), 25 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/trace/SpanData.java b/core/src/main/java/com/google/instrumentation/trace/SpanData.java index 579b03733e..296870787d 100644 --- a/core/src/main/java/com/google/instrumentation/trace/SpanData.java +++ b/core/src/main/java/com/google/instrumentation/trace/SpanData.java @@ -36,6 +36,7 @@ public abstract class SpanData { * @param context the {@code SpanContext} of the {@code Span}. * @param parentSpanId the parent {@code SpanId} of the {@code Span}. {@code null} if the {@code * Span} is a root. + * @param hasRemoteParent {@code true} if the parent is on a different process. * @param displayName the name of the {@code Span}. * @param startTimestamp the start {@code Timestamp} of the {@code Span}. * @param attributes the attributes associated with the {@code Span}. @@ -51,6 +52,7 @@ public abstract class SpanData { public static SpanData create( SpanContext context, @Nullable SpanId parentSpanId, + boolean hasRemoteParent, String displayName, Timestamp startTimestamp, Attributes attributes, @@ -62,6 +64,7 @@ public static SpanData create( return new AutoValue_SpanData( context, parentSpanId, + hasRemoteParent, displayName, startTimestamp, attributes, @@ -87,6 +90,13 @@ public static SpanData create( @Nullable public abstract SpanId getParentSpanId(); + /** + * Returns {@code true} if the parent is on a different process. + * + * @return {@code true} if the parent is on a different process. + */ + public abstract boolean getHasRemoteParent(); + /** * Returns the display name of this {@code Span}. * diff --git a/core/src/test/java/com/google/instrumentation/trace/SpanDataTest.java b/core/src/test/java/com/google/instrumentation/trace/SpanDataTest.java index 9b2e6d7abd..6303dc1b91 100644 --- a/core/src/test/java/com/google/instrumentation/trace/SpanDataTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/SpanDataTest.java @@ -86,6 +86,7 @@ public void spanData_AllValues() { SpanData.create( spanContext, parentSpanId, + true, DISPLAY_NAME, startTimestamp, attributes, @@ -96,6 +97,7 @@ public void spanData_AllValues() { endTimestamp); assertThat(spanData.getContext()).isEqualTo(spanContext); assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); + assertThat(spanData.getHasRemoteParent()).isTrue(); assertThat(spanData.getDisplayName()).isEqualTo(DISPLAY_NAME); assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); assertThat(spanData.getAttributes()).isEqualTo(attributes); @@ -112,6 +114,7 @@ public void spanData_RootActiveSpan() { SpanData.create( spanContext, null, + false, DISPLAY_NAME, startTimestamp, attributes, @@ -122,6 +125,7 @@ public void spanData_RootActiveSpan() { null); assertThat(spanData.getContext()).isEqualTo(spanContext); assertThat(spanData.getParentSpanId()).isNull(); + assertThat(spanData.getHasRemoteParent()).isFalse(); assertThat(spanData.getDisplayName()).isEqualTo(DISPLAY_NAME); assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); assertThat(spanData.getAttributes()).isEqualTo(attributes); @@ -138,6 +142,7 @@ public void spanData_AllDataEmpty() { SpanData.create( spanContext, parentSpanId, + false, DISPLAY_NAME, startTimestamp, Attributes.create(Collections.emptyMap(), 0), @@ -148,6 +153,7 @@ public void spanData_AllDataEmpty() { endTimestamp); assertThat(spanData.getContext()).isEqualTo(spanContext); assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); + assertThat(spanData.getHasRemoteParent()).isFalse(); assertThat(spanData.getDisplayName()).isEqualTo(DISPLAY_NAME); assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); assertThat(spanData.getAttributes().getAttributeMap().isEmpty()).isTrue(); @@ -160,36 +166,37 @@ public void spanData_AllDataEmpty() { @Test public void spanDataEquals() { - String allSpanData1 = + SpanData allSpanData1 = SpanData.create( - spanContext, - parentSpanId, - DISPLAY_NAME, - startTimestamp, - attributes, - annotations, - networkEvents, - links, - status, - endTimestamp) - .toString(); - String allSpanData2 = + spanContext, + parentSpanId, + false, + DISPLAY_NAME, + startTimestamp, + attributes, + annotations, + networkEvents, + links, + status, + endTimestamp); + SpanData allSpanData2 = SpanData.create( - spanContext, - parentSpanId, - DISPLAY_NAME, - startTimestamp, - attributes, - annotations, - networkEvents, - links, - status, - endTimestamp) - .toString(); + spanContext, + parentSpanId, + false, + DISPLAY_NAME, + startTimestamp, + attributes, + annotations, + networkEvents, + links, + status, + endTimestamp); SpanData emptySpanData = SpanData.create( spanContext, parentSpanId, + false, DISPLAY_NAME, startTimestamp, Attributes.create(Collections.emptyMap(), 0), @@ -210,6 +217,7 @@ public void spanData_ToString() { SpanData.create( spanContext, parentSpanId, + false, DISPLAY_NAME, startTimestamp, attributes, diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java index e1917e9330..691c161ee5 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java @@ -32,6 +32,8 @@ final class SpanImpl extends Span { // The parent SpanId of this span. Null if this is a root. private final SpanId parentSpanId; + // True if the parent is on a different process. + private final boolean hasRemoteParent; // Handler called when the span starts and ends. private final StartEndHandler startEndHandler; // The displayed name of the span. @@ -63,12 +65,14 @@ static SpanImpl startSpan( @Nullable EnumSet options, String name, @Nullable SpanId parentSpanId, + boolean hasRemoteParent, StartEndHandler startEndHandler, @Nullable TimestampConverter timestampConverter, Clock clock) { SpanImpl span = new SpanImpl( - context, options, name, parentSpanId, startEndHandler, timestampConverter, clock); + context, options, name, parentSpanId, hasRemoteParent, startEndHandler, + timestampConverter, clock); // Call onStart here instead of calling in the constructor to make sure the span is completely // initialized. if (span.getOptions().contains(Options.RECORD_EVENTS)) { @@ -102,6 +106,7 @@ SpanData toSpanData() { return SpanData.create( getContext(), parentSpanId, + hasRemoteParent, name, timestampConverter.convertNanoTime(startNanoTime), SpanData.Attributes.create(Collections.emptyMap(), 0), @@ -177,11 +182,13 @@ private SpanImpl( @Nullable EnumSet options, String name, @Nullable SpanId parentSpanId, + boolean hasRemoteParent, StartEndHandler startEndHandler, @Nullable TimestampConverter timestampConverter, Clock clock) { super(context, options); this.parentSpanId = parentSpanId; + this.hasRemoteParent = hasRemoteParent; this.name = name; this.startEndHandler = startEndHandler; this.clock = clock; diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java index 2f205546a5..7b03aecc5f 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java @@ -62,6 +62,7 @@ public void toSpanData_NoRecordEvents() { noRecordSpanOptions, SPAN_NAME, parentSpanId, + false, startEndHandler, timestampConverter, testClock); @@ -78,11 +79,16 @@ public void toSpanData_ActiveSpan() { recordSpanOptions, SPAN_NAME, parentSpanId, + true, startEndHandler, timestampConverter, testClock); Mockito.verify(startEndHandler, Mockito.times(1)).onStart(span); SpanData spanData = span.toSpanData(); + assertThat(spanData.getContext()).isEqualTo(spanContext); + assertThat(spanData.getDisplayName()).isEqualTo(SPAN_NAME); + assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); + assertThat(spanData.getHasRemoteParent()).isTrue(); assertThat(spanData.getStartTimestamp()).isEqualTo(timestamp); assertThat(spanData.getStatus()).isNull(); assertThat(spanData.getEndTimestamp()).isNull(); @@ -96,6 +102,7 @@ public void toSpanData_EndedSpan() { recordSpanOptions, SPAN_NAME, parentSpanId, + false, startEndHandler, timestampConverter, testClock); @@ -104,6 +111,10 @@ public void toSpanData_EndedSpan() { span.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build()); Mockito.verify(startEndHandler, Mockito.times(1)).onEnd(span); SpanData spanData = span.toSpanData(); + assertThat(spanData.getContext()).isEqualTo(spanContext); + assertThat(spanData.getDisplayName()).isEqualTo(SPAN_NAME); + assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); + assertThat(spanData.getHasRemoteParent()).isFalse(); assertThat(spanData.getStartTimestamp()).isEqualTo(timestamp); assertThat(spanData.getStatus()).isEqualTo(Status.CANCELLED); assertThat(spanData.getEndTimestamp()).isEqualTo(timestamp.addNanos(7777)); From 04f4b1744d9a84b629281beadc8d47e8bf5dd696 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 8 May 2017 15:12:54 -0700 Subject: [PATCH 0060/1581] Use AutoValue to implement BucketBoundaries. --- .../instrumentation/stats/BucketBoundaries.java | 16 +++++----------- .../stats/BucketBoundariesTest.java | 11 +++++++++++ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java b/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java index 7d74d895d4..ac4b4d2417 100644 --- a/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java +++ b/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java @@ -16,6 +16,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.auto.value.AutoValue; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -23,8 +24,8 @@ /** * The optional histogram bucket boundaries for a {@link Distribution}. */ -public final class BucketBoundaries { - private final List bucketBoundaries; +@AutoValue +public abstract class BucketBoundaries { /** * @param bucketBoundaries the boundaries for the buckets in the underlying {@link Distribution}. @@ -42,18 +43,11 @@ public static final BucketBoundaries create(List bucketBoundaries) { checkArgument(lower < next, "Bucket boundaries not sorted."); lower = next; } - - return new BucketBoundaries(Collections.unmodifiableList(bucketBoundariesCopy)); + return new AutoValue_BucketBoundaries(Collections.unmodifiableList(bucketBoundariesCopy)); } /** * @return a list of histogram bucket boundaries. */ - public final List getBoundaries() { - return bucketBoundaries; - } - - private BucketBoundaries(List bucketBoundaries) { - this.bucketBoundaries = bucketBoundaries; - } + public abstract List getBoundaries(); } diff --git a/core/src/test/java/com/google/instrumentation/stats/BucketBoundariesTest.java b/core/src/test/java/com/google/instrumentation/stats/BucketBoundariesTest.java index b707402ef2..130009c5fd 100644 --- a/core/src/test/java/com/google/instrumentation/stats/BucketBoundariesTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/BucketBoundariesTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.common.testing.EqualsTester; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -73,4 +74,14 @@ public void testNoBoundaries() throws Exception { thrown.expect(IllegalArgumentException.class); BucketBoundaries.create(buckets); } + + @Test + public void testBucketBoundariesEquals() { + new EqualsTester() + .addEqualityGroup( + BucketBoundaries.create(Arrays.asList(-1.0, 2.0)), + BucketBoundaries.create(Arrays.asList(-1.0, 2.0))) + .addEqualityGroup(BucketBoundaries.create(Arrays.asList(-1.0))) + .testEquals(); + } } From 54fe84d027b1f9774a3a0475025723c59b8fd61a Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 8 May 2017 15:13:08 -0700 Subject: [PATCH 0061/1581] Use AutoValue to implement DistributionAggregationDescriptor. --- .../DistributionAggregationDescriptor.java | 20 +++++++++++-------- ...DistributionAggregationDescriptorTest.java | 13 ++++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregationDescriptor.java b/core/src/main/java/com/google/instrumentation/stats/DistributionAggregationDescriptor.java index 70bdde984b..c43a07907f 100644 --- a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregationDescriptor.java +++ b/core/src/main/java/com/google/instrumentation/stats/DistributionAggregationDescriptor.java @@ -13,6 +13,7 @@ package com.google.instrumentation.stats; +import com.google.auto.value.AutoValue; import java.util.List; import javax.annotation.Nullable; @@ -34,13 +35,14 @@ *

Note: If N = 1, there are no finite buckets and the single bucket is both the overflow * and underflow bucket. */ -public final class DistributionAggregationDescriptor { +@AutoValue +public abstract class DistributionAggregationDescriptor { /** * Constructs a new {@link DistributionAggregationDescriptor} with the optional * histogram bucket boundaries. */ public static DistributionAggregationDescriptor create(List bucketBoundaries) { - return new DistributionAggregationDescriptor(BucketBoundaries.create(bucketBoundaries)); + return createInternal(BucketBoundaries.create(bucketBoundaries)); } /** @@ -48,7 +50,12 @@ public static DistributionAggregationDescriptor create(List bucketBounda * histogram bucket boundaries. */ public static DistributionAggregationDescriptor create() { - return new DistributionAggregationDescriptor(null); + return createInternal(null); + } + + private static DistributionAggregationDescriptor createInternal( + @Nullable BucketBoundaries bucketBoundaries) { + return new AutoValue_DistributionAggregationDescriptor(bucketBoundaries); } /** @@ -59,13 +66,10 @@ public static DistributionAggregationDescriptor create() { */ @Nullable public List getBucketBoundaries() { + BucketBoundaries bucketBoundaries = getBucketBoundariesObject(); return bucketBoundaries == null ? null : bucketBoundaries.getBoundaries(); } @Nullable - private final BucketBoundaries bucketBoundaries; - - private DistributionAggregationDescriptor(@Nullable BucketBoundaries bucketBoundaries) { - this.bucketBoundaries = bucketBoundaries; - } + abstract BucketBoundaries getBucketBoundariesObject(); } diff --git a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationDescriptorTest.java b/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationDescriptorTest.java index abc57c5b7f..4eb77d6f65 100644 --- a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationDescriptorTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationDescriptorTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.common.testing.EqualsTester; import java.util.Arrays; import org.junit.Test; import org.junit.runner.RunWith; @@ -43,4 +44,16 @@ public void testDistributionAggregationDescriptor() { .isWithin(0.00000001).of(buckets[i]); } } + + @Test + public void testDistributionAggregationDescriptorEquals() { + new EqualsTester() + .addEqualityGroup( + DistributionAggregationDescriptor.create(Arrays.asList(1.0, 2.0, 5.0)), + DistributionAggregationDescriptor.create(Arrays.asList(1.0, 2.0, 5.0))) + .addEqualityGroup( + DistributionAggregationDescriptor.create(), + DistributionAggregationDescriptor.create()) + .testEquals(); + } } From 58d6edecc94b410812f1db7ab09642dc2b4052da Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 8 May 2017 15:33:23 -0700 Subject: [PATCH 0062/1581] Add implementation for TraceExporter. (#279) * Add implementation for TraceExporter. --- .../instrumentation/trace/TraceExporter.java | 9 +- .../trace/TraceComponentImplBase.java | 10 +- .../trace/TraceExporterImpl.java | 182 ++++++++++++++++++ .../trace/TimestampConverterTest.java | 9 +- .../trace/TraceComponentImplBaseTest.java | 50 +++++ .../trace/TraceConfigImplTest.java | 3 +- .../trace/TraceExporterImplTest.java | 178 +++++++++++++++++ .../trace/TraceComponentImplTest.java | 3 +- .../trace/TraceComponentImplTest.java | 3 +- .../trace/TraceComponentImplTest.java | 3 +- 10 files changed, 429 insertions(+), 21 deletions(-) create mode 100644 core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java create mode 100644 core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java create mode 100644 core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java index d9aa074f05..b68909563c 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java @@ -13,6 +13,7 @@ package com.google.instrumentation.trace; +import java.util.List; import javax.annotation.Nullable; import javax.annotation.concurrent.ThreadSafe; @@ -60,17 +61,17 @@ public abstract class TraceExporter { public abstract static class ServiceHandler { /** - * It is called every time after a sampled (see {@link TraceOptions#isSampled()}) {@link Span} - * is ended. + * Exports a list of sampled (see {@link TraceOptions#isSampled()}) {@link Span}s using the + * immutable representation {@link SpanData}. * *

This may be called from a different thread than the one that called {@link Span#end()}. * *

Implementation SHOULD not block the calling thread. It should execute the export on a * different thread if possible. * - * @param spanData the immutable representation of all data collected by the {@code Span}. + * @param spanDataList a list of {@code SpanData} objects to be exported. */ - public abstract void export(SpanData spanData); + public abstract void export(List spanDataList); } /** diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java index f2aacf1b36..1225dc621d 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java @@ -17,12 +17,16 @@ /** Base implementation of the {@link TraceComponent}. */ public class TraceComponentImplBase extends TraceComponent { - private static final Tracer tracer = Tracer.getNoopTracer(); - private final BinaryPropagationHandlerImpl binaryPropagationHandler = + private static final int TRACE_EXPORTER_BUFFER_SIZE = 32; + // Enforces that trace exporter exports data at least once every 2 seconds. + private static final long TRACE_EXPORTER_SCHEDULE_DELAY_MS = 2000; + private final BinaryPropagationHandler binaryPropagationHandler = new BinaryPropagationHandlerImpl(); private final Clock clock; - private final TraceExporter traceExporter = TraceExporter.getNoopTraceExporter(); + private final TraceExporterImpl traceExporter = + TraceExporterImpl.create(TRACE_EXPORTER_BUFFER_SIZE, TRACE_EXPORTER_SCHEDULE_DELAY_MS); private final TraceConfig traceConfig = new TraceConfigImpl(); + private final Tracer tracer = Tracer.getNoopTracer(); TraceComponentImplBase(Clock clock) { this.clock = clock; diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java new file mode 100644 index 0000000000..e2891d0ba8 --- /dev/null +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java @@ -0,0 +1,182 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import com.google.common.annotations.VisibleForTesting; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.concurrent.GuardedBy; + +/** Implementation of the {@link TraceExporter}. */ +final class TraceExporterImpl extends TraceExporter { + private static final Logger logger = Logger.getLogger(TraceExporter.class.getName()); + + private final WorkerThread workerThread; + + /** + * Constructs a {@code TraceExporterImpl} that exports the {@link SpanData} asynchronously. + * + *

Starts a separate thread that wakes up every {@code scheduleDelay} and exports any available + * spans data. If the number of buffered SpanData objects is greater than {@code bufferSize} then + * the thread wakes up sooner. + * + * @param bufferSize the size of the buffered span data. + * @param scheduleDelayMillis the maximum delay in milliseconds. + */ + static TraceExporterImpl create(int bufferSize, long scheduleDelayMillis) { + WorkerThread workerThread = new WorkerThread(bufferSize, scheduleDelayMillis); + workerThread.setDaemon(true); + workerThread.setName("TraceExporter.WorkerThread"); + workerThread.start(); + return new TraceExporterImpl(workerThread); + // TODO(bdrutu): Consider to add a shutdown hook to not avoid dropping data. + } + + @Override + public void registerServiceHandler(String name, ServiceHandler serviceHandler) { + workerThread.registerServiceHandler(name, serviceHandler); + } + + @Override + public void unregisterServiceHandler(String name) { + workerThread.unregisterServiceHandler(name); + } + + /** + * Adds a {@link SpanImpl} to be exported. + * + * @param span the {@code SpanImpl} that will be exported. + */ + void addSpan(SpanImpl span) { + workerThread.addSpan(span); + } + + @VisibleForTesting + Thread getWorkerThread() { + return workerThread; + } + + private TraceExporterImpl(WorkerThread workerThread) { + this.workerThread = workerThread; + } + + // Worker thread that batches multiple span data and calls the registered services to export + // that data. + // + // The map of registered handlers is implemented using ConcurrentHashMap ensuring full + // concurrency of retrievals and adjustable expected concurrency for updates. Retrievals + // reflect the results of the most recently completed update operations held upon their onset. + // + // The list of batched data is protected by an explicit monitor object which ensures full + // concurrency. + private static final class WorkerThread extends Thread { + private final Object monitor = new Object(); + @GuardedBy("monitor") + private final List spans; + private final Map serviceHandlers = + new ConcurrentHashMap(); + private final int bufferSize; + private final long scheduleDelayMillis; + + // See TraceExporterImpl#addSpan. + private void addSpan(SpanImpl span) { + synchronized (monitor) { + this.spans.add(span); + if (spans.size() > bufferSize) { + monitor.notifyAll(); + } + } + } + + // See TraceExporterImpl#registerServiceHandler. + private void registerServiceHandler(String name, ServiceHandler serviceHandler) { + serviceHandlers.put(name, serviceHandler); + } + + // See TraceExporterImpl#unregisterServiceHandler. + private void unregisterServiceHandler(String name) { + serviceHandlers.remove(name); + } + + // Exports the list of SpanData to all the ServiceHandlers. + private void onBatchExport(List spanDataList) { + // From the java documentation of the ConcurrentHashMap#entrySet(): + // The view's iterator is a "weakly consistent" iterator that will never throw + // ConcurrentModificationException, and guarantees to traverse elements as they existed + // upon construction of the iterator, and may (but is not guaranteed to) reflect any + // modifications subsequent to construction. + for (Map.Entry it : serviceHandlers.entrySet()) { + // In case of any exception thrown by the service handlers continue to run. + try { + it.getValue().export(spanDataList); + } catch (Throwable e) { + logger.log(Level.WARNING, "Exception thrown by the service exporter " + it.getKey(), e); + } + } + } + + private WorkerThread(int bufferSize, long scheduleDelayMillis) { + spans = new LinkedList(); + this.bufferSize = bufferSize; + this.scheduleDelayMillis = scheduleDelayMillis; + } + + // Returns an unmodifiable list of all buffered spans data to ensure that any registered + // service handler cannot modify the list. + private static List fromSpanImplToSpanData(List spans) { + List spanDatas = new ArrayList(spans.size()); + for (SpanImpl span : spans) { + spanDatas.add(span.toSpanData()); + } + return Collections.unmodifiableList(spanDatas); + } + + @Override + public void run() { + while (true) { + // Copy all the batched spans in a separate list to release the monitor lock asap to + // avoid blocking the producer thread. + List spansCopy; + synchronized (monitor) { + if (spans.size() < bufferSize) { + do { + // In the case of a spurious wakeup we export only if we have at least one span in + // the batch. It is acceptable because batching is a best effort mechanism here. + try { + monitor.wait(scheduleDelayMillis); + } catch (InterruptedException ie) { + // Preserve the interruption status as per guidance and stop doing any work. + Thread.currentThread().interrupt(); + return; + } + } while (spans.isEmpty()); + } + spansCopy = new ArrayList(spans); + spans.clear(); + } + // Execute the batch export outside the synchronized to not block all producers. + final List spanDataList = fromSpanImplToSpanData(spansCopy); + if (!spanDataList.isEmpty()) { + onBatchExport(spanDataList); + } + } + } + } +} diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TimestampConverterTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TimestampConverterTest.java index 8f506fdfe3..b1e486315d 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TimestampConverterTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TimestampConverterTest.java @@ -41,11 +41,8 @@ public void convertNanoTime() { when(mockClock.now()).thenReturn(timestamp); when(mockClock.nowNanos()).thenReturn(1234L); TimestampConverter timeConverter = TimestampConverter.now(mockClock); - assertThat(timeConverter.convertNanoTime(6234)) - .isEqualTo(Timestamp.create(1234, 10678)); - assertThat(timeConverter.convertNanoTime(1000)) - .isEqualTo(Timestamp.create(1234, 5444)); - assertThat(timeConverter.convertNanoTime(999995556)) - .isEqualTo(Timestamp.create(1235, 0)); + assertThat(timeConverter.convertNanoTime(6234)).isEqualTo(Timestamp.create(1234, 10678)); + assertThat(timeConverter.convertNanoTime(1000)).isEqualTo(Timestamp.create(1234, 5444)); + assertThat(timeConverter.convertNanoTime(999995556)).isEqualTo(Timestamp.create(1235, 0)); } } diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java new file mode 100644 index 0000000000..c090df387a --- /dev/null +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.instrumentation.internal.MillisClock; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TraceComponentImplBase}. */ +@RunWith(JUnit4.class) +public class TraceComponentImplBaseTest { + private final TraceComponent traceComponent = + new TraceComponentImplBase(MillisClock.getInstance()); + + @Test + public void implementationOfTracer() { + // TODO(bdrutu): Change this when TracerImpl is available. + assertThat(traceComponent.getTracer()).isSameAs(Tracer.getNoopTracer()); + } + + @Test + public void implementationOfBinaryPropagationHandler() { + assertThat(traceComponent.getBinaryPropagationHandler()) + .isInstanceOf(BinaryPropagationHandlerImpl.class); + } + + @Test + public void implementationOfClock() { + assertThat(traceComponent.getClock()).isInstanceOf(MillisClock.class); + } + + @Test + public void implementationOfTraceExporter() { + assertThat(traceComponent.getTraceExporter()).isInstanceOf(TraceExporterImpl.class); + } +} diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceConfigImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceConfigImplTest.java index 584a3d6efb..1535f5738a 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceConfigImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceConfigImplTest.java @@ -31,7 +31,7 @@ public void defaultActiveTraceParams() { } @Test - public void updatePermanentelyTraceParams() { + public void updateTraceParams() { TraceParams traceParams = TraceParams.DEFAULT .toBuilder() @@ -47,4 +47,3 @@ public void updatePermanentelyTraceParams() { assertThat(traceConfig.getActiveTraceParams()).isEqualTo(TraceParams.DEFAULT); } } - diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java new file mode 100644 index 0000000000..7109ab0809 --- /dev/null +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java @@ -0,0 +1,178 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.anyListOf; +import static org.mockito.Mockito.doThrow; + +import com.google.instrumentation.internal.MillisClock; +import com.google.instrumentation.trace.Span.Options; +import com.google.instrumentation.trace.SpanImpl.StartEndHandler; +import com.google.instrumentation.trace.TraceExporter.ServiceHandler; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import javax.annotation.concurrent.GuardedBy; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link TraceExporterImpl}. */ +@RunWith(JUnit4.class) +public class TraceExporterImplTest { + private static final String SPAN_NAME_1 = "MySpanName/1"; + private static final String SPAN_NAME_2 = "MySpanName/2"; + private final Random random = new Random(1234); + private final SpanContext spanContext = + SpanContext.create( + TraceId.generateRandomId(random), + SpanId.generateRandomId(random), + TraceOptions.builder().setIsSampled().build()); + private final TraceExporterImpl traceExporter = TraceExporterImpl.create(4, 1000); + private EnumSet recordSpanOptions = EnumSet.of(Options.RECORD_EVENTS); + private final FakeServiceHandler serviceHandler = new FakeServiceHandler(); + @Mock private StartEndHandler startEndHandler; + @Mock private ServiceHandler mockServiceHandler; + + private static final class FakeServiceHandler extends ServiceHandler { + private final Object monitor = new Object(); + + @GuardedBy("monitor") + List spanDataList = new LinkedList(); + + @Override + public void export(List spanDataList) { + synchronized (monitor) { + this.spanDataList.addAll(spanDataList); + monitor.notifyAll(); + } + } + + // Waits until we received numberOfSpans spans to export; Returns null if the current thread is + // interrupted. + private List waitForExport(int numberOfSpans) { + List ret; + synchronized (monitor) { + while (spanDataList.size() < numberOfSpans) { + try { + monitor.wait(); + } catch (InterruptedException e) { + // Preserve the interruption status as per guidance. + Thread.currentThread().interrupt(); + return null; + } + } + ret = new ArrayList(spanDataList); + spanDataList.clear(); + } + return ret; + } + } + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + traceExporter.registerServiceHandler("test.service", serviceHandler); + } + + private final SpanImpl generateSpan(String spanName) { + SpanImpl span = + SpanImpl.startSpan( + spanContext, + recordSpanOptions, + spanName, + null, + false, + startEndHandler, + null, + MillisClock.getInstance()); + span.end(); + return span; + } + + @Test + public void exportDifferentSampledSpans() { + traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + traceExporter.addSpan(generateSpan(SPAN_NAME_2)); + List exported = serviceHandler.waitForExport(2); + assertThat(exported.size()).isEqualTo(2); + assertThat(exported.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); + assertThat(exported.get(1).getDisplayName()).isEqualTo(SPAN_NAME_2); + } + + @Test + public void exportMoreSpansThanTheBufferSize() { + traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + List exported = serviceHandler.waitForExport(6); + assertThat(exported.size()).isEqualTo(6); + assertThat(exported.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); + assertThat(exported.get(1).getDisplayName()).isEqualTo(SPAN_NAME_1); + assertThat(exported.get(2).getDisplayName()).isEqualTo(SPAN_NAME_1); + assertThat(exported.get(3).getDisplayName()).isEqualTo(SPAN_NAME_1); + assertThat(exported.get(4).getDisplayName()).isEqualTo(SPAN_NAME_1); + assertThat(exported.get(5).getDisplayName()).isEqualTo(SPAN_NAME_1); + } + + @Test + public void interruptWorkerThreadStops() throws InterruptedException { + Thread workerThread = traceExporter.getWorkerThread(); + workerThread.interrupt(); + // Test that the worker thread will stop. + workerThread.join(); + } + + @Test + public void serviceHandlerThrowsException() { + doThrow(new IllegalArgumentException("No export for you.")) + .when(mockServiceHandler) + .export(anyListOf(SpanData.class)); + traceExporter.registerServiceHandler("mock.service", mockServiceHandler); + traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + List exported = serviceHandler.waitForExport(1); + assertThat(exported.size()).isEqualTo(1); + assertThat(exported.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); + // Continue to export after the exception was received. + traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + exported = serviceHandler.waitForExport(1); + assertThat(exported.size()).isEqualTo(1); + assertThat(exported.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); + } + + @Test + public void exportSpansToMultipleServices() { + FakeServiceHandler serviceHandler2 = new FakeServiceHandler(); + traceExporter.registerServiceHandler("test.service2", serviceHandler2); + traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + traceExporter.addSpan(generateSpan(SPAN_NAME_2)); + List exported1 = serviceHandler.waitForExport(2); + List exported2 = serviceHandler2.waitForExport(2); + assertThat(exported1.size()).isEqualTo(2); + assertThat(exported2.size()).isEqualTo(2); + assertThat(exported1.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); + assertThat(exported2.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); + assertThat(exported1.get(1).getDisplayName()).isEqualTo(SPAN_NAME_2); + assertThat(exported2.get(1).getDisplayName()).isEqualTo(SPAN_NAME_2); + } +} diff --git a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index 26f7c8b123..3111c1dc26 100644 --- a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -42,7 +42,6 @@ public void implementationOfClock() { @Test public void implementationOfTraceExporter() { - // TODO(bdrutu): Change this when TraceExporterImpl is available. - assertThat(Tracing.getTraceExporter()).isSameAs(TraceExporter.getNoopTraceExporter()); + assertThat(Tracing.getTraceExporter()).isInstanceOf(TraceExporterImpl.class); } } diff --git a/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index 26f7c8b123..3111c1dc26 100644 --- a/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -42,7 +42,6 @@ public void implementationOfClock() { @Test public void implementationOfTraceExporter() { - // TODO(bdrutu): Change this when TraceExporterImpl is available. - assertThat(Tracing.getTraceExporter()).isSameAs(TraceExporter.getNoopTraceExporter()); + assertThat(Tracing.getTraceExporter()).isInstanceOf(TraceExporterImpl.class); } } diff --git a/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index 7a20e31acf..65a78fda4e 100644 --- a/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -42,7 +42,6 @@ public void implementationOfClock() { @Test public void implementationOfTraceExporter() { - // TODO(bdrutu): Change this when TraceExporterImpl is available. - assertThat(Tracing.getTraceExporter()).isSameAs(TraceExporter.getNoopTraceExporter()); + assertThat(Tracing.getTraceExporter()).isInstanceOf(TraceExporterImpl.class); } } From bce8765da463d0e868416673ab77e434731ac0e2 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 8 May 2017 15:48:03 -0700 Subject: [PATCH 0063/1581] Add Immutable annotation to AutoValue stats classes. --- .../com/google/instrumentation/stats/BucketBoundaries.java | 2 ++ .../java/com/google/instrumentation/stats/Distribution.java | 1 + .../stats/DistributionAggregationDescriptor.java | 2 ++ .../google/instrumentation/stats/MeasurementDescriptor.java | 4 ++++ .../src/main/java/com/google/instrumentation/stats/Tag.java | 2 ++ .../main/java/com/google/instrumentation/stats/TagKey.java | 2 ++ .../java/com/google/instrumentation/stats/TagValue.java | 2 ++ .../com/google/instrumentation/stats/ViewDescriptor.java | 6 +++++- 8 files changed, 20 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java b/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java index ac4b4d2417..317beb4df9 100644 --- a/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java +++ b/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java @@ -20,10 +20,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.annotation.concurrent.Immutable; /** * The optional histogram bucket boundaries for a {@link Distribution}. */ +@Immutable @AutoValue public abstract class BucketBoundaries { diff --git a/core/src/main/java/com/google/instrumentation/stats/Distribution.java b/core/src/main/java/com/google/instrumentation/stats/Distribution.java index dd3016a581..6dbea406c0 100644 --- a/core/src/main/java/com/google/instrumentation/stats/Distribution.java +++ b/core/src/main/java/com/google/instrumentation/stats/Distribution.java @@ -142,6 +142,7 @@ final double getMean() { /** Describes a range of population values. */ // TODO(sebright): Decide what to do when the distribution contains no values. + @Immutable @AutoValue abstract static class Range { diff --git a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregationDescriptor.java b/core/src/main/java/com/google/instrumentation/stats/DistributionAggregationDescriptor.java index c43a07907f..e0d9167bbf 100644 --- a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregationDescriptor.java +++ b/core/src/main/java/com/google/instrumentation/stats/DistributionAggregationDescriptor.java @@ -16,6 +16,7 @@ import com.google.auto.value.AutoValue; import java.util.List; import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; /** * Describes data aggregations based on distributions. @@ -35,6 +36,7 @@ *

Note: If N = 1, there are no finite buckets and the single bucket is both the overflow * and underflow bucket. */ +@Immutable @AutoValue public abstract class DistributionAggregationDescriptor { /** diff --git a/core/src/main/java/com/google/instrumentation/stats/MeasurementDescriptor.java b/core/src/main/java/com/google/instrumentation/stats/MeasurementDescriptor.java index a47b4a209e..d44c4eabec 100644 --- a/core/src/main/java/com/google/instrumentation/stats/MeasurementDescriptor.java +++ b/core/src/main/java/com/google/instrumentation/stats/MeasurementDescriptor.java @@ -18,12 +18,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.annotation.concurrent.Immutable; /** * MeasurementDescriptor. * *

Note: MeasurementDescriptor names are {@link String}s with enforced restrictions. */ +@Immutable @AutoValue public abstract class MeasurementDescriptor { public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; @@ -83,6 +85,7 @@ public enum BasicUnit { * The name of a {@code MeasurementDescriptor}. */ // This type should be used as the key when associating data with MeasurementDescriptors. + @Immutable @AutoValue public abstract static class Name { @@ -136,6 +139,7 @@ public static Name create(String name) { * power10: -9 * numerator: SECS */ + @Immutable @AutoValue public abstract static class MeasurementUnit { diff --git a/core/src/main/java/com/google/instrumentation/stats/Tag.java b/core/src/main/java/com/google/instrumentation/stats/Tag.java index bb7dc36f13..7486055884 100644 --- a/core/src/main/java/com/google/instrumentation/stats/Tag.java +++ b/core/src/main/java/com/google/instrumentation/stats/Tag.java @@ -14,10 +14,12 @@ package com.google.instrumentation.stats; import com.google.auto.value.AutoValue; +import javax.annotation.concurrent.Immutable; /** * A pair of consisting of an associated {@link TagKey} and {@link TagValue}. */ +@Immutable @AutoValue public abstract class Tag { Tag() {} diff --git a/core/src/main/java/com/google/instrumentation/stats/TagKey.java b/core/src/main/java/com/google/instrumentation/stats/TagKey.java index 6c60c10c12..873202873b 100644 --- a/core/src/main/java/com/google/instrumentation/stats/TagKey.java +++ b/core/src/main/java/com/google/instrumentation/stats/TagKey.java @@ -15,12 +15,14 @@ import com.google.auto.value.AutoValue; import com.google.instrumentation.internal.StringUtil; +import javax.annotation.concurrent.Immutable; /** * Tag keys. * *

TagKey's are {@link String}s with enforced restrictions. */ +@Immutable @AutoValue public abstract class TagKey { public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; diff --git a/core/src/main/java/com/google/instrumentation/stats/TagValue.java b/core/src/main/java/com/google/instrumentation/stats/TagValue.java index 72b9484844..f27003b45d 100644 --- a/core/src/main/java/com/google/instrumentation/stats/TagValue.java +++ b/core/src/main/java/com/google/instrumentation/stats/TagValue.java @@ -15,12 +15,14 @@ import com.google.auto.value.AutoValue; import com.google.instrumentation.internal.StringUtil; +import javax.annotation.concurrent.Immutable; /** * Tag values. * *

TagValue's are {@link String}s with enforced restrictions. */ +@Immutable @AutoValue public abstract class TagValue { public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; diff --git a/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java b/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java index 3212a30ddb..5550795fb9 100644 --- a/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java +++ b/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java @@ -15,15 +15,16 @@ import com.google.auto.value.AutoValue; import com.google.instrumentation.common.Function; - import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.annotation.concurrent.Immutable; /** * A ViewDescriptor specifies an aggregation and a set of tag keys. The aggregation will be broken * down by the unique set of matching tag values for each measurement. */ +@Immutable public abstract class ViewDescriptor { /** * Name of view. Must be unique. @@ -67,6 +68,7 @@ public abstract T match( * The name of a {@code ViewDescriptor}. */ // This type should be used as the key when associating data with ViewDescriptors. + @Immutable @AutoValue public abstract static class Name { @@ -93,6 +95,7 @@ public static Name create(String name) { /** * A {@link ViewDescriptor} for distribution-base aggregations. */ + @Immutable @AutoValue public abstract static class DistributionViewDescriptor extends ViewDescriptor { /** @@ -146,6 +149,7 @@ public T match( /** * A {@link ViewDescriptor} for interval-based aggregations. */ + @Immutable @AutoValue public abstract static class IntervalViewDescriptor extends ViewDescriptor { /** From 8e68b29fd3b9af7ea0fc0738fb67b024405d8673 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 8 May 2017 19:11:38 -0700 Subject: [PATCH 0064/1581] Add an export service handler which logs all the SpanData. (#286) * Add an export service handler which logs all the SpanData. Add factory method for LoggingServiceHandler. --- .../instrumentation/trace/TraceExporter.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java index b68909563c..7318b85459 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java @@ -14,6 +14,8 @@ package com.google.instrumentation.trace; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.annotation.Nullable; import javax.annotation.concurrent.ThreadSafe; @@ -74,6 +76,44 @@ public abstract static class ServiceHandler { public abstract void export(List spanDataList); } + /** + * Implementation of the {@link ServiceHandler} which logs all the exported {@link SpanData}. + * + *

Example of usage: + * + *

{@code
+   * public static void main(String[] args) {
+   *   Tracing.getTraceExporter().registerServiceHandler(
+   *       "com.google.instrumentation.LoggingServiceHandler", LoggingServiceHandler.getInstance());
+   *   // ...
+   * }
+   * }
+ * + */ + @ThreadSafe + public static final class LoggingServiceHandler extends ServiceHandler { + private static final Logger logger = Logger.getLogger(LoggingServiceHandler.class.getName()); + private static final LoggingServiceHandler INSTANCE = new LoggingServiceHandler(); + + /** + * Returns the instance of the {@code LoggingServiceHandler}. + * + * @return the instance of the {@code LoggingServiceHandler}. + */ + public static LoggingServiceHandler getInstance() { + return INSTANCE; + } + + @Override + public void export(List spanDataList) { + for (SpanData spanData : spanDataList) { + logger.log(Level.INFO, spanData.toString()); + } + } + + private LoggingServiceHandler() {} + } + /** * Returns the no-op implementation of the {@code TraceExporter}. * From 797c5594a88e3077919864c749e1cabc09733e8a Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 9 May 2017 14:36:56 -0700 Subject: [PATCH 0065/1581] Add span factory implementation. (#284) * Add span factory implementation. --- .../trace/SpanFactoryImpl.java | 127 +++++++++++++ .../instrumentation/trace/SpanImpl.java | 12 +- .../trace/SpanFactoryImplTest.java | 169 ++++++++++++++++++ 3 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java create mode 100644 core_impl/src/test/java/com/google/instrumentation/trace/SpanFactoryImplTest.java diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java new file mode 100644 index 0000000000..c9cf17f3d1 --- /dev/null +++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java @@ -0,0 +1,127 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.instrumentation.common.Clock; +import com.google.instrumentation.trace.Link.Type; +import com.google.instrumentation.trace.Span.Options; +import com.google.instrumentation.trace.TraceConfig.TraceParams; +import java.util.EnumSet; +import java.util.List; +import java.util.Random; +import javax.annotation.Nullable; + +/** Implementation of the {@link SpanFactory}. */ +final class SpanFactoryImpl extends SpanFactory { + private final RandomHandler randomHandler; + private final SpanImpl.StartEndHandler startEndHandler; + private final Clock clock; + private final TraceConfig traceConfig; + + @Override + protected Span startSpan(@Nullable Span parent, String name, StartSpanOptions options) { + SpanContext parentContext = null; + TimestampConverter timestampConverter = null; + if (parent != null) { + parentContext = parent.getContext(); + // Pass the timestamp converter from the parent to ensure that the recorded events are in + // the right order. Implementation uses System.nanoTime() which is monotonically increasing. + if (parent instanceof SpanImpl) { + timestampConverter = ((SpanImpl) parent).getTimestampConverter(); + } + } + return startSpanInternal(parentContext, false, name, options, timestampConverter); + } + + @Override + protected Span startSpanWithRemoteParent( + @Nullable SpanContext remoteParent, String name, StartSpanOptions options) { + return startSpanInternal(remoteParent, true, name, options, null); + } + + Span startSpanInternal( + @Nullable SpanContext parent, + boolean hasRemoteParent, + String name, + StartSpanOptions startSpanOptions, + @Nullable TimestampConverter timestampConverter) { + TraceParams activeTraceParams = traceConfig.getActiveTraceParams(); + Random random = randomHandler.current(); + TraceId traceId; + SpanId spanId = SpanId.generateRandomId(random); + SpanId parentSpanId = null; + TraceOptions.Builder traceOptionsBuilder; + if (parent == null || !parent.isValid()) { + // New root span. + traceId = TraceId.generateRandomId(random); + traceOptionsBuilder = TraceOptions.builder(); + // This is a root span so no remote or local parent. + hasRemoteParent = false; + } else { + // New child span. + traceId = parent.getTraceId(); + parentSpanId = parent.getSpanId(); + traceOptionsBuilder = TraceOptions.builder(parent.getTraceOptions()); + } + Sampler sampler = + startSpanOptions.getSampler() != null + ? startSpanOptions.getSampler() + : activeTraceParams.getSampler(); + if (sampler.shouldSample( + parent, hasRemoteParent, traceId, spanId, name, startSpanOptions.getParentLinks())) { + traceOptionsBuilder.setIsSampled(); + } + TraceOptions traceOptions = traceOptionsBuilder.build(); + EnumSet spanOptions = EnumSet.noneOf(Options.class); + if (traceOptions.isSampled() + || (startSpanOptions.getRecordEvents() != null && startSpanOptions.getRecordEvents())) { + spanOptions.add(Options.RECORD_EVENTS); + } + Span span = + SpanImpl.startSpan( + SpanContext.create(traceId, spanId, traceOptions), + spanOptions, + name, + parentSpanId, + hasRemoteParent, + startEndHandler, + timestampConverter, + clock); + linkSpans(span, startSpanOptions.getParentLinks()); + return span; + } + + private static void linkSpans(Span span, List parentLinks) { + if (!parentLinks.isEmpty()) { + Link childLink = Link.fromSpanContext(span.getContext(), Type.CHILD); + for (Span linkedSpan : parentLinks) { + linkedSpan.addLink(childLink); + span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Type.PARENT)); + } + } + } + + SpanFactoryImpl( + RandomHandler randomHandler, + SpanImpl.StartEndHandler startEndHandler, + Clock clock, + TraceConfig traceConfig) { + this.randomHandler = checkNotNull(randomHandler, "randomHandler"); + this.startEndHandler = checkNotNull(startEndHandler, "startEndHandler"); + this.clock = checkNotNull(clock, "clock"); + this.traceConfig = checkNotNull(traceConfig, "traceConfig"); + } +} diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java index 691c161ee5..408ff48852 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java @@ -90,6 +90,16 @@ String getName() { return name; } + /** + * Returns the {@code TimestampConverter} used by this {@code Span}. + * + * @return the {@code TimestampConverter} used by this {@code Span}. + */ + @Nullable + TimestampConverter getTimestampConverter() { + return timestampConverter; + } + /** * Returns an immutable representation of all the data from this {@code Span}. * @@ -199,7 +209,7 @@ private SpanImpl( startNanoTime = clock.nowNanos(); } else { this.startNanoTime = 0; - this.timestampConverter = null; + this.timestampConverter = timestampConverter; } } } diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/SpanFactoryImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/SpanFactoryImplTest.java new file mode 100644 index 0000000000..7411920fb9 --- /dev/null +++ b/core_impl/src/test/java/com/google/instrumentation/trace/SpanFactoryImplTest.java @@ -0,0 +1,169 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; + +import com.google.instrumentation.internal.TestClock; +import com.google.instrumentation.trace.Span.Options; +import com.google.instrumentation.trace.SpanImpl.StartEndHandler; +import com.google.instrumentation.trace.TraceConfig.TraceParams; +import java.util.Random; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link SpanFactoryImpl}. */ +@RunWith(JUnit4.class) +public class SpanFactoryImplTest { + private static final String SPAN_NAME = "MySpanName"; + private SpanFactoryImpl spanFactory; + private TraceParams alwaysSampleTraceParams = + TraceParams.DEFAULT.toBuilder().setSampler(Samplers.alwaysSample()).build(); + private final TestClock testClock = TestClock.create(); + private final RandomHandler randomHandler = new FakeRandomHandler(); + @Mock private StartEndHandler startEndHandler; + @Mock private TraceConfig traceConfig; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + spanFactory = new SpanFactoryImpl(randomHandler, startEndHandler, testClock, traceConfig); + } + + @Test + public void startSpanNullParent() { + StartSpanOptions startSpanOptions = new StartSpanOptions(); + when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); + Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + assertThat(span.getContext().isValid()).isTrue(); + assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); + assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); + assertThat(span instanceof SpanImpl).isTrue(); + SpanData spanData = ((SpanImpl) span).toSpanData(); + assertThat(spanData.getParentSpanId()).isNull(); + assertThat(spanData.getHasRemoteParent()).isFalse(); + assertThat(spanData.getStartTimestamp()).isEqualTo(testClock.now()); + assertThat(spanData.getDisplayName()).isEqualTo(SPAN_NAME); + } + + @Test + public void startSpanNullParentWithRecordEvents() { + StartSpanOptions startSpanOptions = new StartSpanOptions(); + startSpanOptions.setSampler(Samplers.neverSample()); + startSpanOptions.setRecordEvents(true); + when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); + Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + assertThat(span.getContext().isValid()).isTrue(); + assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); + assertThat(span.getContext().getTraceOptions().isSampled()).isFalse(); + assertThat(span instanceof SpanImpl).isTrue(); + SpanData spanData = ((SpanImpl) span).toSpanData(); + assertThat(spanData.getParentSpanId()).isNull(); + assertThat(spanData.getHasRemoteParent()).isFalse(); + } + + @Test + public void startSpanNullParentNoRecordOptions() { + StartSpanOptions startSpanOptions = new StartSpanOptions(); + startSpanOptions.setSampler(Samplers.neverSample()); + when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); + Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + assertThat(span.getContext().isValid()).isTrue(); + assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isFalse(); + assertThat(span.getContext().getTraceOptions().isSampled()).isFalse(); + } + + @Test + public void startRemoteSpanNullParent() { + StartSpanOptions startSpanOptions = new StartSpanOptions(); + when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); + Span span = spanFactory.startSpanWithRemoteParent(null, SPAN_NAME, startSpanOptions); + assertThat(span.getContext().isValid()).isTrue(); + assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); + assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); + assertThat(span instanceof SpanImpl).isTrue(); + SpanData spanData = ((SpanImpl) span).toSpanData(); + assertThat(spanData.getParentSpanId()).isNull(); + assertThat(spanData.getHasRemoteParent()).isFalse(); + } + + @Test + public void startChildSpan() { + StartSpanOptions startSpanOptions = new StartSpanOptions(); + when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); + Span rootSpan = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + assertThat(rootSpan.getContext().isValid()).isTrue(); + assertThat(rootSpan.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); + assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isTrue(); + Span childSpan = spanFactory.startSpan(rootSpan, SPAN_NAME, startSpanOptions); + assertThat(childSpan.getContext().isValid()).isTrue(); + assertThat(childSpan.getContext().getTraceId()).isEqualTo(rootSpan.getContext().getTraceId()); + assertThat(((SpanImpl) childSpan).toSpanData().getParentSpanId()) + .isEqualTo(rootSpan.getContext().getSpanId()); + assertThat(((SpanImpl) childSpan).getTimestampConverter()) + .isEqualTo(((SpanImpl) rootSpan).getTimestampConverter()); + } + + @Test + public void startRemoteSpanInvalidParent() { + StartSpanOptions startSpanOptions = new StartSpanOptions(); + when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); + Span span = + spanFactory.startSpanWithRemoteParent(SpanContext.INVALID, SPAN_NAME, startSpanOptions); + assertThat(span.getContext().isValid()).isTrue(); + assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); + assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); + assertThat(span instanceof SpanImpl).isTrue(); + SpanData spanData = ((SpanImpl) span).toSpanData(); + assertThat(spanData.getParentSpanId()).isNull(); + assertThat(spanData.getHasRemoteParent()).isFalse(); + } + + @Test + public void startRemoteSpan() { + SpanContext spanContext = + SpanContext.create( + TraceId.generateRandomId(randomHandler.current()), + SpanId.generateRandomId(randomHandler.current()), + TraceOptions.DEFAULT); + StartSpanOptions startSpanOptions = new StartSpanOptions(); + when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); + Span span = spanFactory.startSpanWithRemoteParent(spanContext, SPAN_NAME, startSpanOptions); + assertThat(span.getContext().isValid()).isTrue(); + assertThat(span.getContext().getTraceId()).isEqualTo(spanContext.getTraceId()); + assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); + assertThat(span instanceof SpanImpl).isTrue(); + SpanData spanData = ((SpanImpl) span).toSpanData(); + assertThat(spanData.getParentSpanId()).isEqualTo(spanContext.getSpanId()); + assertThat(spanData.getHasRemoteParent()).isTrue(); + } + + private static final class FakeRandomHandler extends RandomHandler { + private final Random random; + + FakeRandomHandler() { + this.random = new Random(1234); + } + + @Override + Random current() { + return random; + } + } +} From 2883bec3e0a8b8aeb29bf76bdb0b9303218e02ad Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 9 May 2017 15:46:58 -0700 Subject: [PATCH 0066/1581] Change TraceExporterImpl to implement also the StartEndHandler. (#288) Change TraceExporterImpl to implement also the StartEndHandler. Supports only service export for the moment. --- .../instrumentation/trace/SpanImpl.java | 20 +- .../trace/TraceComponentImplBase.java | 8 +- .../trace/TraceExporterImpl.java | 78 +++++--- .../trace/TraceComponentImplBaseTest.java | 3 +- .../trace/TraceExporterImplTest.java | 181 +++++++++++------- .../trace/TraceComponentImpl.java | 3 +- .../trace/TraceComponentImplJava.java | 3 +- 7 files changed, 189 insertions(+), 107 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java index 408ff48852..671a990bd9 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java @@ -71,8 +71,14 @@ static SpanImpl startSpan( Clock clock) { SpanImpl span = new SpanImpl( - context, options, name, parentSpanId, hasRemoteParent, startEndHandler, - timestampConverter, clock); + context, + options, + name, + parentSpanId, + hasRemoteParent, + startEndHandler, + timestampConverter, + clock); // Call onStart here instead of calling in the constructor to make sure the span is completely // initialized. if (span.getOptions().contains(Options.RECORD_EVENTS)) { @@ -172,8 +178,8 @@ public void end(EndSpanOptions options) { } /** - * Abstract class to handle the start and end operations for a {@link Span} only when the {@code - * Span} has {@link Span.Options#RECORD_EVENTS} option. + * Interface to handle the start and end operations for a {@link Span} only when the {@code Span} + * has {@link Span.Options#RECORD_EVENTS} option. * *

Implementation must avoid high overhead work in any of the methods because the code is * executed on the critical path. @@ -181,10 +187,10 @@ public void end(EndSpanOptions options) { *

One instance can be called by multiple threads in the same time, so the implementation must * be thread-safe. */ - abstract static class StartEndHandler { - abstract void onStart(SpanImpl span); + interface StartEndHandler { + void onStart(SpanImpl span); - abstract void onEnd(SpanImpl span); + void onEnd(SpanImpl span); } private SpanImpl( diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java index 1225dc621d..158af752f9 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java @@ -14,6 +14,7 @@ package com.google.instrumentation.trace; import com.google.instrumentation.common.Clock; +import com.google.instrumentation.common.EventQueue; /** Base implementation of the {@link TraceComponent}. */ public class TraceComponentImplBase extends TraceComponent { @@ -23,13 +24,14 @@ public class TraceComponentImplBase extends TraceComponent { private final BinaryPropagationHandler binaryPropagationHandler = new BinaryPropagationHandlerImpl(); private final Clock clock; - private final TraceExporterImpl traceExporter = - TraceExporterImpl.create(TRACE_EXPORTER_BUFFER_SIZE, TRACE_EXPORTER_SCHEDULE_DELAY_MS); + private final TraceExporterImpl traceExporter; private final TraceConfig traceConfig = new TraceConfigImpl(); private final Tracer tracer = Tracer.getNoopTracer(); - TraceComponentImplBase(Clock clock) { + TraceComponentImplBase(Clock clock, EventQueue eventQueue) { this.clock = clock; + traceExporter = TraceExporterImpl.create(TRACE_EXPORTER_BUFFER_SIZE, + TRACE_EXPORTER_SCHEDULE_DELAY_MS, eventQueue); } @Override diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java index e2891d0ba8..b373727d60 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java @@ -14,6 +14,8 @@ package com.google.instrumentation.trace; import com.google.common.annotations.VisibleForTesting; +import com.google.instrumentation.common.EventQueue; +import com.google.instrumentation.trace.SpanImpl.StartEndHandler; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; @@ -24,11 +26,17 @@ import java.util.logging.Logger; import javax.annotation.concurrent.GuardedBy; -/** Implementation of the {@link TraceExporter}. */ -final class TraceExporterImpl extends TraceExporter { +/** + * Implementation of the {@link TraceExporter}, implements also {@link StartEndHandler}. + * + *

Uses the provided {@link EventQueue} to defer processing/exporting of the {@link SpanData} to + * avoid impacting the critical path. + */ +final class TraceExporterImpl extends TraceExporter implements StartEndHandler { private static final Logger logger = Logger.getLogger(TraceExporter.class.getName()); - private final WorkerThread workerThread; + private final ServiceExporterThread serviceExporterThread; + private final EventQueue eventQueue; /** * Constructs a {@code TraceExporterImpl} that exports the {@link SpanData} asynchronously. @@ -40,41 +48,45 @@ final class TraceExporterImpl extends TraceExporter { * @param bufferSize the size of the buffered span data. * @param scheduleDelayMillis the maximum delay in milliseconds. */ - static TraceExporterImpl create(int bufferSize, long scheduleDelayMillis) { - WorkerThread workerThread = new WorkerThread(bufferSize, scheduleDelayMillis); - workerThread.setDaemon(true); - workerThread.setName("TraceExporter.WorkerThread"); + static TraceExporterImpl create(int bufferSize, long scheduleDelayMillis, EventQueue eventQueue) { + ServiceExporterThread workerThread = new ServiceExporterThread(bufferSize, scheduleDelayMillis); workerThread.start(); - return new TraceExporterImpl(workerThread); + return new TraceExporterImpl(workerThread, eventQueue); // TODO(bdrutu): Consider to add a shutdown hook to not avoid dropping data. } @Override public void registerServiceHandler(String name, ServiceHandler serviceHandler) { - workerThread.registerServiceHandler(name, serviceHandler); + serviceExporterThread.registerServiceHandler(name, serviceHandler); } @Override public void unregisterServiceHandler(String name) { - workerThread.unregisterServiceHandler(name); + serviceExporterThread.unregisterServiceHandler(name); } - /** - * Adds a {@link SpanImpl} to be exported. - * - * @param span the {@code SpanImpl} that will be exported. - */ - void addSpan(SpanImpl span) { - workerThread.addSpan(span); + @Override + public void onStart(SpanImpl span) { + // Do nothing. When ActiveSpans functionality is implemented this will change to record the + // Span into the ActiveSpans list. + } + + @Override + public void onEnd(SpanImpl span) { + // TODO(bdrutu): Change to RECORD_EVENTS option when active/samples is supported. + if (span.getContext().getTraceOptions().isSampled()) { + eventQueue.enqueue(new SpanEndEvent(span, serviceExporterThread)); + } } @VisibleForTesting - Thread getWorkerThread() { - return workerThread; + Thread getServiceExporterThread() { + return serviceExporterThread; } - private TraceExporterImpl(WorkerThread workerThread) { - this.workerThread = workerThread; + private TraceExporterImpl(ServiceExporterThread serviceExporterThread, EventQueue eventQueue) { + this.serviceExporterThread = serviceExporterThread; + this.eventQueue = eventQueue; } // Worker thread that batches multiple span data and calls the registered services to export @@ -86,10 +98,12 @@ private TraceExporterImpl(WorkerThread workerThread) { // // The list of batched data is protected by an explicit monitor object which ensures full // concurrency. - private static final class WorkerThread extends Thread { + private static final class ServiceExporterThread extends Thread { private final Object monitor = new Object(); + @GuardedBy("monitor") private final List spans; + private final Map serviceHandlers = new ConcurrentHashMap(); private final int bufferSize; @@ -132,10 +146,12 @@ private void onBatchExport(List spanDataList) { } } - private WorkerThread(int bufferSize, long scheduleDelayMillis) { + private ServiceExporterThread(int bufferSize, long scheduleDelayMillis) { spans = new LinkedList(); this.bufferSize = bufferSize; this.scheduleDelayMillis = scheduleDelayMillis; + setDaemon(true); + setName("TraceExporter.ServiceExporterThread"); } // Returns an unmodifiable list of all buffered spans data to ensure that any registered @@ -179,4 +195,20 @@ public void run() { } } } + + // An EventQueue entry that records the end of the span event. + private static final class SpanEndEvent implements EventQueue.Entry { + private final SpanImpl span; + private final ServiceExporterThread serviceExporterThread; + + SpanEndEvent(SpanImpl span, ServiceExporterThread serviceExporterThread) { + this.span = span; + this.serviceExporterThread = serviceExporterThread; + } + + @Override + public void process() { + serviceExporterThread.addSpan(span); + } + } } diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java index c090df387a..362a2df075 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.instrumentation.common.SimpleEventQueue; import com.google.instrumentation.internal.MillisClock; import org.junit.Test; import org.junit.runner.RunWith; @@ -24,7 +25,7 @@ @RunWith(JUnit4.class) public class TraceComponentImplBaseTest { private final TraceComponent traceComponent = - new TraceComponentImplBase(MillisClock.getInstance()); + new TraceComponentImplBase(MillisClock.getInstance(), new SimpleEventQueue()); @Test public void implementationOfTracer() { diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java index 7109ab0809..22cd60be57 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java @@ -17,9 +17,9 @@ import static org.mockito.Matchers.anyListOf; import static org.mockito.Mockito.doThrow; +import com.google.instrumentation.common.SimpleEventQueue; import com.google.instrumentation.internal.MillisClock; import com.google.instrumentation.trace.Span.Options; -import com.google.instrumentation.trace.SpanImpl.StartEndHandler; import com.google.instrumentation.trace.TraceExporter.ServiceHandler; import java.util.ArrayList; import java.util.EnumSet; @@ -40,67 +40,50 @@ public class TraceExporterImplTest { private static final String SPAN_NAME_1 = "MySpanName/1"; private static final String SPAN_NAME_2 = "MySpanName/2"; private final Random random = new Random(1234); - private final SpanContext spanContext = + private final SpanContext sampledSpanContext = SpanContext.create( TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.builder().setIsSampled().build()); - private final TraceExporterImpl traceExporter = TraceExporterImpl.create(4, 1000); + private final SpanContext notSampledSpanContext = + SpanContext.create( + TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); + private final TraceExporterImpl traceExporter = + TraceExporterImpl.create(4, 1000, new SimpleEventQueue()); private EnumSet recordSpanOptions = EnumSet.of(Options.RECORD_EVENTS); private final FakeServiceHandler serviceHandler = new FakeServiceHandler(); - @Mock private StartEndHandler startEndHandler; @Mock private ServiceHandler mockServiceHandler; - private static final class FakeServiceHandler extends ServiceHandler { - private final Object monitor = new Object(); - - @GuardedBy("monitor") - List spanDataList = new LinkedList(); - - @Override - public void export(List spanDataList) { - synchronized (monitor) { - this.spanDataList.addAll(spanDataList); - monitor.notifyAll(); - } - } - - // Waits until we received numberOfSpans spans to export; Returns null if the current thread is - // interrupted. - private List waitForExport(int numberOfSpans) { - List ret; - synchronized (monitor) { - while (spanDataList.size() < numberOfSpans) { - try { - monitor.wait(); - } catch (InterruptedException e) { - // Preserve the interruption status as per guidance. - Thread.currentThread().interrupt(); - return null; - } - } - ret = new ArrayList(spanDataList); - spanDataList.clear(); - } - return ret; - } - } - @Before public void setUp() { MockitoAnnotations.initMocks(this); traceExporter.registerServiceHandler("test.service", serviceHandler); } - private final SpanImpl generateSpan(String spanName) { + private final SpanImpl createSampledEndedSpan(String spanName) { + SpanImpl span = + SpanImpl.startSpan( + sampledSpanContext, + recordSpanOptions, + spanName, + null, + false, + traceExporter, + null, + MillisClock.getInstance()); + span.end(); + return span; + } + + private final SpanImpl createNotSampledEndedSpan(String spanName) { SpanImpl span = SpanImpl.startSpan( - spanContext, + notSampledSpanContext, recordSpanOptions, spanName, null, false, - startEndHandler, + traceExporter, null, MillisClock.getInstance()); span.end(); @@ -109,38 +92,38 @@ private final SpanImpl generateSpan(String spanName) { @Test public void exportDifferentSampledSpans() { - traceExporter.addSpan(generateSpan(SPAN_NAME_1)); - traceExporter.addSpan(generateSpan(SPAN_NAME_2)); + SpanImpl span1 = createSampledEndedSpan(SPAN_NAME_1); + SpanImpl span2 = createSampledEndedSpan(SPAN_NAME_2); List exported = serviceHandler.waitForExport(2); assertThat(exported.size()).isEqualTo(2); - assertThat(exported.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); - assertThat(exported.get(1).getDisplayName()).isEqualTo(SPAN_NAME_2); + assertThat(exported.get(0)).isEqualTo(span1.toSpanData()); + assertThat(exported.get(1)).isEqualTo(span2.toSpanData()); } @Test public void exportMoreSpansThanTheBufferSize() { - traceExporter.addSpan(generateSpan(SPAN_NAME_1)); - traceExporter.addSpan(generateSpan(SPAN_NAME_1)); - traceExporter.addSpan(generateSpan(SPAN_NAME_1)); - traceExporter.addSpan(generateSpan(SPAN_NAME_1)); - traceExporter.addSpan(generateSpan(SPAN_NAME_1)); - traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + SpanImpl span1 = createSampledEndedSpan(SPAN_NAME_1); + SpanImpl span2 = createSampledEndedSpan(SPAN_NAME_1); + SpanImpl span3 = createSampledEndedSpan(SPAN_NAME_1); + SpanImpl span4 = createSampledEndedSpan(SPAN_NAME_1); + SpanImpl span5 = createSampledEndedSpan(SPAN_NAME_1); + SpanImpl span6 = createSampledEndedSpan(SPAN_NAME_1); List exported = serviceHandler.waitForExport(6); assertThat(exported.size()).isEqualTo(6); - assertThat(exported.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); - assertThat(exported.get(1).getDisplayName()).isEqualTo(SPAN_NAME_1); - assertThat(exported.get(2).getDisplayName()).isEqualTo(SPAN_NAME_1); - assertThat(exported.get(3).getDisplayName()).isEqualTo(SPAN_NAME_1); - assertThat(exported.get(4).getDisplayName()).isEqualTo(SPAN_NAME_1); - assertThat(exported.get(5).getDisplayName()).isEqualTo(SPAN_NAME_1); + assertThat(exported.get(0)).isEqualTo(span1.toSpanData()); + assertThat(exported.get(1)).isEqualTo(span2.toSpanData()); + assertThat(exported.get(2)).isEqualTo(span3.toSpanData()); + assertThat(exported.get(3)).isEqualTo(span4.toSpanData()); + assertThat(exported.get(4)).isEqualTo(span5.toSpanData()); + assertThat(exported.get(5)).isEqualTo(span6.toSpanData()); } @Test public void interruptWorkerThreadStops() throws InterruptedException { - Thread workerThread = traceExporter.getWorkerThread(); - workerThread.interrupt(); + Thread serviceExporterThread = traceExporter.getServiceExporterThread(); + serviceExporterThread.interrupt(); // Test that the worker thread will stop. - workerThread.join(); + serviceExporterThread.join(); } @Test @@ -149,30 +132,86 @@ public void serviceHandlerThrowsException() { .when(mockServiceHandler) .export(anyListOf(SpanData.class)); traceExporter.registerServiceHandler("mock.service", mockServiceHandler); - traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + SpanImpl span1 = createSampledEndedSpan(SPAN_NAME_1); List exported = serviceHandler.waitForExport(1); assertThat(exported.size()).isEqualTo(1); - assertThat(exported.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); + assertThat(exported.get(0)).isEqualTo(span1.toSpanData()); // Continue to export after the exception was received. - traceExporter.addSpan(generateSpan(SPAN_NAME_1)); + SpanImpl span2 = createSampledEndedSpan(SPAN_NAME_1); exported = serviceHandler.waitForExport(1); assertThat(exported.size()).isEqualTo(1); - assertThat(exported.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); + assertThat(exported.get(0)).isEqualTo(span2.toSpanData()); } @Test public void exportSpansToMultipleServices() { FakeServiceHandler serviceHandler2 = new FakeServiceHandler(); traceExporter.registerServiceHandler("test.service2", serviceHandler2); - traceExporter.addSpan(generateSpan(SPAN_NAME_1)); - traceExporter.addSpan(generateSpan(SPAN_NAME_2)); + SpanImpl span1 = createSampledEndedSpan(SPAN_NAME_1); + SpanImpl span2 = createSampledEndedSpan(SPAN_NAME_2); List exported1 = serviceHandler.waitForExport(2); List exported2 = serviceHandler2.waitForExport(2); assertThat(exported1.size()).isEqualTo(2); assertThat(exported2.size()).isEqualTo(2); - assertThat(exported1.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); - assertThat(exported2.get(0).getDisplayName()).isEqualTo(SPAN_NAME_1); - assertThat(exported1.get(1).getDisplayName()).isEqualTo(SPAN_NAME_2); - assertThat(exported2.get(1).getDisplayName()).isEqualTo(SPAN_NAME_2); + assertThat(exported1.get(0)).isEqualTo(span1.toSpanData()); + assertThat(exported2.get(0)).isEqualTo(span1.toSpanData()); + assertThat(exported1.get(1)).isEqualTo(span2.toSpanData()); + assertThat(exported2.get(1)).isEqualTo(span2.toSpanData()); + } + + @Test + public void exportNotSampledSpans() { + SpanImpl span1 = createNotSampledEndedSpan(SPAN_NAME_1); + SpanImpl span2 = createSampledEndedSpan(SPAN_NAME_2); + // Spans are recorded and exported in the same order as they are ended, we test that a non + // sampled span is not exported by creating and ending a sampled span after a non sampled span + // and checking that the first exported span is the sampled span (the non sampled did not get + // exported). + List exported = serviceHandler.waitForExport(1); + assertThat(exported.size()).isEqualTo(1); + assertThat(exported.get(0)).isNotEqualTo(span1.toSpanData()); + assertThat(exported.get(0)).isEqualTo(span2.toSpanData()); + } + + /** Fake {@link ServiceHandler} for testing only. */ + private static final class FakeServiceHandler extends ServiceHandler { + private final Object monitor = new Object(); + + @GuardedBy("monitor") + private final List spanDataList = new LinkedList(); + + @Override + public void export(List spanDataList) { + synchronized (monitor) { + this.spanDataList.addAll(spanDataList); + monitor.notifyAll(); + } + } + + /** + * Waits until we received numberOfSpans spans to export. Returns the list of exported {@link + * SpanData} objects, otherwise {@code null} if the current thread is interrupted. + * + * @param numberOfSpans the number of minimum spans to be collected. + * @return the list of exported {@link SpanData} objects, otherwise {@code null} if the current + * thread is interrupted. + */ + private List waitForExport(int numberOfSpans) { + List ret; + synchronized (monitor) { + while (spanDataList.size() < numberOfSpans) { + try { + monitor.wait(); + } catch (InterruptedException e) { + // Preserve the interruption status as per guidance. + Thread.currentThread().interrupt(); + return null; + } + } + ret = new ArrayList(spanDataList); + spanDataList.clear(); + } + return ret; + } } } diff --git a/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java index 276b19dcbb..43416e6acb 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -13,12 +13,13 @@ package com.google.instrumentation.trace; +import com.google.instrumentation.common.SimpleEventQueue; import com.google.instrumentation.internal.MillisClock; /** Android-compatible implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplBase { public TraceComponentImpl() { - super(MillisClock.getInstance()); + super(MillisClock.getInstance(), new SimpleEventQueue()); } } diff --git a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java index da87f05f86..74c9abded8 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java @@ -14,11 +14,12 @@ package com.google.instrumentation.trace; import com.google.instrumentation.common.Clock; +import com.google.instrumentation.common.DisruptorEventQueue; /** Java 7 and 8 implementation of the {@link TraceComponent}. */ public abstract class TraceComponentImplJava extends TraceComponentImplBase { public TraceComponentImplJava(Clock clock) { - super(clock); + super(clock, DisruptorEventQueue.getInstance()); } } From c47993f827beb57db8a72494fe5bbc4cde117f80 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 9 May 2017 15:47:28 -0700 Subject: [PATCH 0067/1581] Fix Boolean comparison in SpanFactoryImpl. (#289) --- .../java/com/google/instrumentation/trace/SpanFactoryImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java index c9cf17f3d1..be651d0c90 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java @@ -86,8 +86,7 @@ Span startSpanInternal( } TraceOptions traceOptions = traceOptionsBuilder.build(); EnumSet spanOptions = EnumSet.noneOf(Options.class); - if (traceOptions.isSampled() - || (startSpanOptions.getRecordEvents() != null && startSpanOptions.getRecordEvents())) { + if (traceOptions.isSampled() || Boolean.TRUE.equals(startSpanOptions.getRecordEvents())) { spanOptions.add(Options.RECORD_EVENTS); } Span span = From 7e64d4d5142f2e02d647cd4a7c8d3fd39c52b044 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 10 May 2017 12:09:14 -0700 Subject: [PATCH 0068/1581] Use AutoValue to implement View. --- .../google/instrumentation/stats/View.java | 84 +++++++------------ .../instrumentation/stats/ViewTest.java | 55 +++++++++++- 2 files changed, 83 insertions(+), 56 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/View.java b/core/src/main/java/com/google/instrumentation/stats/View.java index 304433386c..34ed8b95cd 100644 --- a/core/src/main/java/com/google/instrumentation/stats/View.java +++ b/core/src/main/java/com/google/instrumentation/stats/View.java @@ -13,18 +13,20 @@ package com.google.instrumentation.stats; +import com.google.auto.value.AutoValue; import com.google.instrumentation.common.Function; import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; - import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.annotation.concurrent.Immutable; /** * The aggregated data for a particular {@link ViewDescriptor}. */ +@Immutable public abstract class View { /** * The {@link ViewDescriptor} associated with this {@link View}. @@ -45,109 +47,83 @@ private View() { /** * A {@link View} for distribution-based aggregations. */ - public static final class DistributionView extends View { + @Immutable + @AutoValue + public abstract static class DistributionView extends View { /** * Constructs a new {@link DistributionView}. */ public static DistributionView create(DistributionViewDescriptor distributionViewDescriptor, List distributionAggregations, Timestamp start, Timestamp end) { - return new DistributionView(distributionViewDescriptor, distributionAggregations, start, end); + return new AutoValue_View_DistributionView( + distributionViewDescriptor, + Collections.unmodifiableList( + new ArrayList(distributionAggregations)), + start, + end); } + @Override + public abstract DistributionViewDescriptor getViewDescriptor(); + /** * The {@link DistributionAggregation}s associated with this {@link DistributionView}. * *

Note: The returned list is unmodifiable, attempts to update it will throw an * UnsupportedOperationException. */ - public List getDistributionAggregations() { - return distributionAggregations; - } + public abstract List getDistributionAggregations(); /** * Returns start timestamp for this aggregation. */ - public Timestamp getStart() { - return start; - } + public abstract Timestamp getStart(); /** * Returns end timestamp for this aggregation. */ - public Timestamp getEnd() { - return end; - } + public abstract Timestamp getEnd(); @Override - public DistributionViewDescriptor getViewDescriptor() { - return distributionViewDescriptor; - } - - @Override - public T match( + public final T match( Function p0, Function p1) { return p0.apply(this); } - - private final DistributionViewDescriptor distributionViewDescriptor; - private final List distributionAggregations; - private final Timestamp start; - private final Timestamp end; - - private DistributionView(DistributionViewDescriptor distributionViewDescriptor, - List distributionAggregations, Timestamp start, Timestamp end) { - this.distributionViewDescriptor = distributionViewDescriptor; - this.distributionAggregations = - Collections.unmodifiableList( - new ArrayList(distributionAggregations)); - this.start = start; - this.end = end; - } } /** * A {@link View} for interval-base aggregations. */ - public static final class IntervalView extends View { + @Immutable + @AutoValue + public abstract static class IntervalView extends View { /** * Constructs a new {@link IntervalView}. */ public static IntervalView create(IntervalViewDescriptor intervalViewDescriptor, List intervalAggregations) { - return new IntervalView(intervalViewDescriptor, intervalAggregations); + return new AutoValue_View_IntervalView( + intervalViewDescriptor, + Collections.unmodifiableList(new ArrayList(intervalAggregations))); } + @Override + public abstract IntervalViewDescriptor getViewDescriptor(); + /** * The {@link IntervalAggregation}s associated with this {@link IntervalView}. * *

Note: The returned list is unmodifiable, attempts to update it will throw an * UnsupportedOperationException. */ - public List getIntervalAggregations() { - return intervalAggregations; - } - - @Override - public IntervalViewDescriptor getViewDescriptor() { - return intervalViewDescriptor; - } + public abstract List getIntervalAggregations(); @Override - public T match( + public final T match( Function p0, Function p1) { return p1.apply(this); } - - private final IntervalViewDescriptor intervalViewDescriptor; - private final List intervalAggregations; - - private IntervalView(IntervalViewDescriptor intervalViewDescriptor, - List intervalAggregations) { - this.intervalViewDescriptor = intervalViewDescriptor; - this.intervalAggregations = - Collections.unmodifiableList(new ArrayList(intervalAggregations)); - } } } diff --git a/core/src/test/java/com/google/instrumentation/stats/ViewTest.java b/core/src/test/java/com/google/instrumentation/stats/ViewTest.java index 7a1dd4839f..73462b1962 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ViewTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/ViewTest.java @@ -14,9 +14,9 @@ package com.google.instrumentation.stats; import static com.google.common.truth.Truth.assertThat; - import static org.junit.Assert.assertTrue; +import com.google.common.testing.EqualsTester; import com.google.instrumentation.common.Duration; import com.google.instrumentation.common.Function; import com.google.instrumentation.common.Timestamp; @@ -28,8 +28,8 @@ import com.google.instrumentation.stats.View.IntervalView; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; - import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; @@ -104,6 +104,57 @@ public void testIntervalView() { })); } + @Test + public void testViewEquals() { + DistributionViewDescriptor dViewDescriptor = + DistributionViewDescriptor.create( + name, + description, + measurementDescriptor, + DistributionAggregationDescriptor.create(Arrays.asList(10.0)), + tagKeys); + List dAggregations = + Arrays.asList( + DistributionAggregation.create( + 5, 5.0, 15.0, Range.create(1.0, 5.0), tags1, Arrays.asList(1L))); + IntervalViewDescriptor iViewDescriptor = + IntervalViewDescriptor.create( + name, + description, + measurementDescriptor, + IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(111))), + tagKeys); + List iAggregations = + Arrays.asList( + IntervalAggregation.create( + tags1, Arrays.asList(Interval.create(Duration.fromMillis(111), 10, 100)))); + + new EqualsTester() + .addEqualityGroup( + DistributionView.create( + dViewDescriptor, + dAggregations, + Timestamp.fromMillis(1000), + Timestamp.fromMillis(2000)), + DistributionView.create( + dViewDescriptor, + dAggregations, + Timestamp.fromMillis(1000), + Timestamp.fromMillis(2000))) + .addEqualityGroup( + DistributionView.create( + dViewDescriptor, + dAggregations, + Timestamp.fromMillis(1000), + Timestamp.fromMillis(3000))) + .addEqualityGroup( + IntervalView.create(iViewDescriptor, iAggregations), + IntervalView.create(iViewDescriptor, iAggregations)) + .addEqualityGroup( + IntervalView.create(iViewDescriptor, Collections.emptyList())) + .testEquals(); + } + // tag keys private static final TagKey K1 = TagKey.create("k1"); private static final TagKey K2 = TagKey.create("k2"); From 54a084014185d80cd27b81cc4318bb5d62333288 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 10 May 2017 12:43:49 -0700 Subject: [PATCH 0069/1581] Remove java7/8 directories. Currently we do not need any feature from java8. (#292) --- benchmarks/build.gradle | 1 - ...gerImplJava.java => StatsManagerImpl.java} | 8 +-- .../trace/TraceComponentImpl.java | 7 +-- .../trace/TraceComponentImplJava.java | 25 --------- .../instrumentation/stats/StatsTest.java | 4 +- .../instrumentation/trace/TracingTest.java | 4 +- core_impl_java_7/README.md | 6 --- core_impl_java_7/build.gradle | 16 ------ .../stats/StatsManagerImpl.java | 26 ---------- .../instrumentation/stats/StatsTest.java | 31 ----------- core_impl_java_8/README.md | 5 -- core_impl_java_8/build.gradle | 16 ------ .../internal/InstantClock.java | 51 ------------------- .../stats/StatsManagerImpl.java | 26 ---------- .../trace/TraceComponentImpl.java | 24 --------- .../trace/TraceComponentImplTest.java | 47 ----------------- examples/build.gradle | 1 - settings.gradle | 4 -- 18 files changed, 11 insertions(+), 291 deletions(-) rename core_impl_java/src/main/java/com/google/instrumentation/stats/{StatsManagerImplJava.java => StatsManagerImpl.java} (77%) rename {core_impl_java_7 => core_impl_java}/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java (79%) delete mode 100644 core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java rename {core_impl_java_8 => core_impl_java}/src/test/java/com/google/instrumentation/stats/StatsTest.java (91%) rename core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java => core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java (92%) delete mode 100644 core_impl_java_7/README.md delete mode 100644 core_impl_java_7/build.gradle delete mode 100644 core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java delete mode 100644 core_impl_java_7/src/test/java/com/google/instrumentation/stats/StatsTest.java delete mode 100644 core_impl_java_8/README.md delete mode 100644 core_impl_java_8/build.gradle delete mode 100644 core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java delete mode 100644 core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java delete mode 100644 core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java delete mode 100644 core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java diff --git a/benchmarks/build.gradle b/benchmarks/build.gradle index 73e52ecbef..b001f268b5 100644 --- a/benchmarks/build.gradle +++ b/benchmarks/build.gradle @@ -26,7 +26,6 @@ dependencies { compile project(':instrumentation-java-core'), project(':instrumentation-java-core-impl') project(':instrumentation-java-core-impl-java') - project(':instrumentation-java-core-impl-java-8') } compileJmhJava { diff --git a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImplJava.java b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java similarity index 77% rename from core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImplJava.java rename to core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java index 5c43eff6a0..e1b164316d 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImplJava.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -13,15 +13,15 @@ package com.google.instrumentation.stats; -import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.DisruptorEventQueue; +import com.google.instrumentation.internal.MillisClock; /** * Java 7 and 8 implementation of {@link StatsManager}. */ -public abstract class StatsManagerImplJava extends StatsManagerImplBase { +public final class StatsManagerImpl extends StatsManagerImplBase { - public StatsManagerImplJava(Clock clock) { - super(DisruptorEventQueue.getInstance(), clock); + public StatsManagerImpl() { + super(DisruptorEventQueue.getInstance(), MillisClock.getInstance()); } } diff --git a/core_impl_java_7/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java similarity index 79% rename from core_impl_java_7/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java rename to core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java index 881ad6f840..6ced470645 100644 --- a/core_impl_java_7/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -13,12 +13,13 @@ package com.google.instrumentation.trace; +import com.google.instrumentation.common.DisruptorEventQueue; import com.google.instrumentation.internal.MillisClock; -/** Java 7 implementation of the {@link TraceComponent}. */ -public final class TraceComponentImpl extends TraceComponentImplJava { +/** Java 7 and 8 implementation of the {@link TraceComponent}. */ +public final class TraceComponentImpl extends TraceComponentImplBase { public TraceComponentImpl() { - super(MillisClock.getInstance()); + super(MillisClock.getInstance(), DisruptorEventQueue.getInstance()); } } diff --git a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java deleted file mode 100644 index 74c9abded8..0000000000 --- a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImplJava.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.trace; - -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.DisruptorEventQueue; - -/** Java 7 and 8 implementation of the {@link TraceComponent}. */ -public abstract class TraceComponentImplJava extends TraceComponentImplBase { - - public TraceComponentImplJava(Clock clock) { - super(clock, DisruptorEventQueue.getInstance()); - } -} diff --git a/core_impl_java_8/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core_impl_java/src/test/java/com/google/instrumentation/stats/StatsTest.java similarity index 91% rename from core_impl_java_8/src/test/java/com/google/instrumentation/stats/StatsTest.java rename to core_impl_java/src/test/java/com/google/instrumentation/stats/StatsTest.java index e5ed1d9ee4..6f968a65aa 100644 --- a/core_impl_java_8/src/test/java/com/google/instrumentation/stats/StatsTest.java +++ b/core_impl_java/src/test/java/com/google/instrumentation/stats/StatsTest.java @@ -19,9 +19,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Test for accessing the {@link StatsManager} through the {@link Stats} class. - */ +/** Test for accessing the {@link StatsManager} through the {@link Stats} class. */ @RunWith(JUnit4.class) public final class StatsTest { @Test diff --git a/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java similarity index 92% rename from core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java rename to core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java index 3111c1dc26..8678290391 100644 --- a/core_impl_java_7/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java @@ -20,9 +20,9 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@link TraceComponentImpl}. */ +/** Test for accessing the {@link TraceComponent} through the {@link Tracing} class. */ @RunWith(JUnit4.class) -public class TraceComponentImplTest { +public class TracingTest { @Test public void implementationOfTracer() { // TODO(bdrutu): Change this when TracerImpl is available. diff --git a/core_impl_java_7/README.md b/core_impl_java_7/README.md deleted file mode 100644 index 20d04a7b90..0000000000 --- a/core_impl_java_7/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Instrumentation Java 7 implementation -====================================================== - -* Java 7 compatible. -* StatsManager specifies the stats implementation classes that should be used - with Java 7. diff --git a/core_impl_java_7/build.gradle b/core_impl_java_7/build.gradle deleted file mode 100644 index e504da837f..0000000000 --- a/core_impl_java_7/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -description = 'Instrumentation Core Impl Java 7' - -apply plugin: 'java' - -[compileJava, compileTestJava].each() { - it.sourceCompatibility = 1.7 - it.targetCompatibility = 1.7 -} - -dependencies { - compile project(':instrumentation-java-core'), - project(':instrumentation-java-core-impl'), - project(':instrumentation-java-core-impl-java') - - signature "org.codehaus.mojo.signature:java17:+@signature" -} diff --git a/core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java deleted file mode 100644 index 1d8bea1cef..0000000000 --- a/core_impl_java_7/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.stats; - -import com.google.instrumentation.internal.MillisClock; - -/** - * Java 7 implementation of {@link StatsManager}. - */ -public final class StatsManagerImpl extends StatsManagerImplJava { - - public StatsManagerImpl() { - super(MillisClock.getInstance()); - } -} diff --git a/core_impl_java_7/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core_impl_java_7/src/test/java/com/google/instrumentation/stats/StatsTest.java deleted file mode 100644 index e5ed1d9ee4..0000000000 --- a/core_impl_java_7/src/test/java/com/google/instrumentation/stats/StatsTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.stats; - -import static com.google.common.truth.Truth.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Test for accessing the {@link StatsManager} through the {@link Stats} class. - */ -@RunWith(JUnit4.class) -public final class StatsTest { - @Test - public void getStatsContextFactory() { - assertThat(Stats.getStatsContextFactory()).isNotNull(); - } -} diff --git a/core_impl_java_8/README.md b/core_impl_java_8/README.md deleted file mode 100644 index 35e61c4f67..0000000000 --- a/core_impl_java_8/README.md +++ /dev/null @@ -1,5 +0,0 @@ -Instrumentation Java 8 implementation -====================================================== - -* StatsManager specifies the stats implementation classes that should be used - with Java 8. diff --git a/core_impl_java_8/build.gradle b/core_impl_java_8/build.gradle deleted file mode 100644 index 12393dbeea..0000000000 --- a/core_impl_java_8/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -description = 'Instrumentation Core Impl Java 8' - -apply plugin: 'java' - -[compileJava, compileTestJava].each() { - it.sourceCompatibility = 1.8 - it.targetCompatibility = 1.8 -} - -dependencies { - compile project(':instrumentation-java-core'), - project(':instrumentation-java-core-impl'), - project(':instrumentation-java-core-impl-java') - - signature "org.codehaus.mojo.signature:java18:+@signature" -} diff --git a/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java b/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java deleted file mode 100644 index bc2a57436d..0000000000 --- a/core_impl_java_8/src/main/java/com/google/instrumentation/internal/InstantClock.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.internal; - -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.Timestamp; -import javax.annotation.concurrent.ThreadSafe; - -/** - * A {@link Clock} that uses {@code Instant#now()}. - */ -@ThreadSafe -public final class InstantClock extends Clock { - private static final InstantClock INSTANCE = new InstantClock(); - - private InstantClock() {} - - /** - * Returns an {@code InstantClock}. - * - * @return an {@code InstantClock}. - */ - public static InstantClock getInstance() { - return INSTANCE; - } - - @Override - public Timestamp now() { - // // TODO(sebright): Use Instant once we skip building this class with Java 7. - // Instant instant = Instant.now(); - // return Timestamp.create(instant.getEpochSecond(), instant.getNano()); - - return Timestamp.fromMillis(System.currentTimeMillis()); - } - - @Override - public long nowNanos() { - return System.nanoTime(); - } -} diff --git a/core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java deleted file mode 100644 index 9c1aaed428..0000000000 --- a/core_impl_java_8/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.stats; - -import com.google.instrumentation.internal.InstantClock; - -/** - * Java 8 implementation of {@link StatsManager}. - */ -public final class StatsManagerImpl extends StatsManagerImplJava { - - public StatsManagerImpl() { - super(InstantClock.getInstance()); - } -} diff --git a/core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java deleted file mode 100644 index 0f6df78737..0000000000 --- a/core_impl_java_8/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.trace; - -import com.google.instrumentation.internal.InstantClock; - -/** Java 8 implementation of the {@link TraceComponent}. */ -public final class TraceComponentImpl extends TraceComponentImplJava { - - public TraceComponentImpl() { - super(InstantClock.getInstance()); - } -} diff --git a/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java deleted file mode 100644 index 65a78fda4e..0000000000 --- a/core_impl_java_8/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.trace; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.instrumentation.internal.InstantClock; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link TraceComponentImpl}. */ -@RunWith(JUnit4.class) -public class TraceComponentImplTest { - @Test - public void implementationOfTracer() { - // TODO(bdrutu): Change this when TracerImpl is available. - assertThat(Tracing.getTracer()).isSameAs(Tracer.getNoopTracer()); - } - - @Test - public void implementationOfBinaryPropagationHandler() { - assertThat(Tracing.getBinaryPropagationHandler()) - .isInstanceOf(BinaryPropagationHandlerImpl.class); - } - - @Test - public void implementationOfClock() { - assertThat(Tracing.getClock()).isInstanceOf(InstantClock.class); - } - - @Test - public void implementationOfTraceExporter() { - assertThat(Tracing.getTraceExporter()).isInstanceOf(TraceExporterImpl.class); - } -} diff --git a/examples/build.gradle b/examples/build.gradle index c20bcb7ea5..e69c088e52 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -9,7 +9,6 @@ dependencies { compile project(':instrumentation-java-core'), project(':instrumentation-java-core-impl'), project(':instrumentation-java-core-impl-java'), - project(':instrumentation-java-core-impl-java-8'), libraries.grpc_context } diff --git a/settings.gradle b/settings.gradle index bd454c36c0..d06d25bb3d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,7 +3,6 @@ include ":instrumentation-java-all" include ":instrumentation-java-core" include ":instrumentation-java-core-impl" include ":instrumentation-java-core-impl-java" -include ":instrumentation-java-core-impl-java-7" include ":instrumentation-java-core-impl-android" include ":shared" @@ -11,7 +10,6 @@ project(':instrumentation-java-all').projectDir = "$rootDir/all" as File project(':instrumentation-java-core').projectDir = "$rootDir/core" as File project(':instrumentation-java-core-impl').projectDir = "$rootDir/core_impl" as File project(':instrumentation-java-core-impl-java').projectDir = "$rootDir/core_impl_java" as File -project(':instrumentation-java-core-impl-java-7').projectDir = "$rootDir/core_impl_java_7" as File project(':instrumentation-java-core-impl-android').projectDir = "$rootDir/core_impl_android" as File project(':shared').projectDir = "$rootDir/shared" as File @@ -19,9 +17,7 @@ project(':shared').projectDir = "$rootDir/shared" as File if (JavaVersion.current().isJava8Compatible()) { include ":instrumentation-examples" include ":instrumentation-java-benchmarks" - include ":instrumentation-java-core-impl-java-8" project(':instrumentation-examples').projectDir = "$rootDir/examples" as File project(':instrumentation-java-benchmarks').projectDir = "$rootDir/benchmarks" as File - project(':instrumentation-java-core-impl-java-8').projectDir = "$rootDir/core_impl_java_8" as File } From affea37044e8ca1f52e44127ecc4db7c8f8e7576 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 10 May 2017 13:52:07 -0700 Subject: [PATCH 0070/1581] Use AutoValue to implement DistributionAggregation. --- .../stats/DistributionAggregation.java | 95 +++++++------------ .../stats/DistributionAggregationTest.java | 14 +++ 2 files changed, 46 insertions(+), 63 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java b/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java index 290cf5b579..9900bf0aec 100644 --- a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java +++ b/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java @@ -13,10 +13,12 @@ package com.google.instrumentation.stats; +import com.google.auto.value.AutoValue; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; // TODO(aveitch) The below class should be changed to use a Distribution as a private member. /** @@ -29,64 +31,61 @@ *

Although not forbidden, it is generally a bad idea to include non-finite values (infinities * or NaNs) in the population of values, as this will render the {@code mean} meaningless. */ -public final class DistributionAggregation { +@Immutable +@AutoValue +public abstract class DistributionAggregation { /** * Constructs a new {@link DistributionAggregation}. */ - public static final DistributionAggregation create( + public static DistributionAggregation create( long count, double mean, double sum, Range range, List tags) { - return new DistributionAggregation(count, mean, sum, range, tags, null); + return createInternal(count, mean, sum, range, tags, null); } /** * Constructs a new {@link DistributionAggregation} with the optional {@code bucketCount}s. */ - public static final DistributionAggregation create( + public static DistributionAggregation create( long count, double mean, double sum, Range range, List tags, List bucketCounts) { - return new DistributionAggregation(count, mean, sum, range, tags, + return createInternal(count, mean, sum, range, tags, Collections.unmodifiableList(new ArrayList(bucketCounts))); } - /** - * {@link Tag}s associated with this {@link DistributionAggregation}. - * - *

Note: The returned list is unmodifiable, attempts to update it will throw an - * UnsupportedOperationException. - */ - public final List getTags() { - return tags; + private static DistributionAggregation createInternal( + long count, double mean, double sum, Range range, List tags, List bucketCounts) { + return new AutoValue_DistributionAggregation(count, mean, sum, range, tags, bucketCounts); } /** * The number of values in the population. Must be non-negative. */ - public long getCount() { - return count; - } + public abstract long getCount(); /** * The arithmetic mean of the values in the population. If {@link #getCount()} is zero then this * value must also be zero. */ - public double getMean() { - return mean; - } + public abstract double getMean(); /** * The sum of the values in the population. If {@link #getCount()} is zero then this values must * also be zero. */ - public double getSum() { - return sum; - } + public abstract double getSum(); /** * The range of the population values. If {@link #getCount()} is zero then this returned range is * implementation-dependent. */ - public Range getRange() { - return range; - } + public abstract Range getRange(); + + /** + * {@link Tag}s associated with this {@link DistributionAggregation}. + * + *

Note: The returned list is unmodifiable, attempts to update it will throw an + * UnsupportedOperationException. + */ + public abstract List getTags(); /** * A Distribution may optionally contain a histogram of the values in the population. The @@ -109,59 +108,29 @@ public Range getRange() { * {@link DistributionAggregationDescriptor#getBucketBoundaries()} returns null. */ @Nullable - public List getBucketCounts() { - return bucketCounts; - } - - private final long count; - private final double mean; - private final double sum; - private final Range range; - private final List tags; - private final List bucketCounts; - - private DistributionAggregation( - long count, double mean, double sum, Range range, List tags, - @Nullable List bucketCounts) { - this.count = count; - this.mean = mean; - this.sum = sum; - this.range = range; - this.tags = tags; - this.bucketCounts = bucketCounts; - } + public abstract List getBucketCounts(); /** * Describes a range of population values. */ - public static final class Range { + @Immutable + @AutoValue + public abstract static class Range { /** * Constructs a new {@link Range}. */ - public static final Range create(double min, double max) { - return new Range(min, max); + public static Range create(double min, double max) { + return new AutoValue_DistributionAggregation_Range(min, max); } /** * The minimum of the population values. */ - public double getMin() { - return min; - } + public abstract double getMin(); /** * The maximum of the population values. */ - public double getMax() { - return max; - } - - private double min; - private double max; - - private Range(double min, double max) { - this.min = min; - this.max = max; - } + public abstract double getMax(); } } diff --git a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java b/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java index 55e0e4e06a..633de2bb99 100644 --- a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java @@ -17,6 +17,7 @@ import com.google.instrumentation.stats.DistributionAggregation.Range; +import com.google.common.testing.EqualsTester; import java.util.Arrays; import java.util.List; import org.junit.Test; @@ -67,6 +68,19 @@ public void testDistributionAggregationWithBuckets() { } } + @Test + public void testDistributionAggregationEquals() { + List buckets = Arrays.asList(1L, 2L, 3L); + new EqualsTester() + .addEqualityGroup( + DistributionAggregation.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS), + DistributionAggregation.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS)) + .addEqualityGroup( + DistributionAggregation.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS, buckets), + DistributionAggregation.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS, buckets)) + .testEquals(); + } + private static final TagKey K1 = TagKey.create("k1"); private static final TagKey K2 = TagKey.create("k2"); From 414e2a0d4b8f9d51ec8d391c3d8fcf11d4dfacb1 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 10 May 2017 14:03:50 -0700 Subject: [PATCH 0071/1581] Add Tracer implementation. Fix visibility for some classes. (#290) --- .../instrumentation/trace/RandomHandler.java | 13 ++++++++++ .../trace/TraceComponentImplBase.java | 12 ++++++---- .../instrumentation/trace/TracerImpl.java | 24 +++++++------------ .../trace/TraceComponentImplBaseTest.java | 7 +++--- .../trace/TraceComponentImpl.java | 3 ++- .../trace/TraceComponentImplTest.java | 3 +-- .../stats/StatsManagerImpl.java | 5 ++-- ...ava.java => ThreadLocalRandomHandler.java} | 8 +++---- .../trace/TraceComponentImpl.java | 6 ++++- .../instrumentation/trace/TracingTest.java | 3 +-- 10 files changed, 47 insertions(+), 37 deletions(-) rename core_impl_android/src/main/java/com/google/instrumentation/trace/RandomHandlerAndroid.java => core_impl/src/main/java/com/google/instrumentation/trace/TracerImpl.java (61%) rename core_impl_java/src/main/java/com/google/instrumentation/trace/{RandomHandlerJava.java => ThreadLocalRandomHandler.java} (82%) diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/RandomHandler.java b/core_impl/src/main/java/com/google/instrumentation/trace/RandomHandler.java index 0d58543a46..e5f4ea948e 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/RandomHandler.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/RandomHandler.java @@ -13,6 +13,7 @@ package com.google.instrumentation.trace; +import java.security.SecureRandom; import java.util.Random; import javax.annotation.concurrent.ThreadSafe; @@ -29,4 +30,16 @@ abstract class RandomHandler { * @return the current {@code Random}. */ abstract Random current(); + + @ThreadSafe + static final class SecureRandomHandler extends RandomHandler { + private final Random random = new SecureRandom(); + + SecureRandomHandler() {} + + @Override + Random current() { + return random; + } + } } diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java index 158af752f9..6b0c693b80 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java @@ -17,21 +17,23 @@ import com.google.instrumentation.common.EventQueue; /** Base implementation of the {@link TraceComponent}. */ -public class TraceComponentImplBase extends TraceComponent { +class TraceComponentImplBase extends TraceComponent { private static final int TRACE_EXPORTER_BUFFER_SIZE = 32; // Enforces that trace exporter exports data at least once every 2 seconds. private static final long TRACE_EXPORTER_SCHEDULE_DELAY_MS = 2000; private final BinaryPropagationHandler binaryPropagationHandler = new BinaryPropagationHandlerImpl(); private final Clock clock; - private final TraceExporterImpl traceExporter; + private final TraceExporter traceExporter; private final TraceConfig traceConfig = new TraceConfigImpl(); - private final Tracer tracer = Tracer.getNoopTracer(); + private final Tracer tracer; - TraceComponentImplBase(Clock clock, EventQueue eventQueue) { + TraceComponentImplBase(Clock clock, RandomHandler randomHandler, EventQueue eventQueue) { this.clock = clock; - traceExporter = TraceExporterImpl.create(TRACE_EXPORTER_BUFFER_SIZE, + TraceExporterImpl traceExporterImpl = TraceExporterImpl.create(TRACE_EXPORTER_BUFFER_SIZE, TRACE_EXPORTER_SCHEDULE_DELAY_MS, eventQueue); + traceExporter = traceExporterImpl; + tracer = new TracerImpl(randomHandler, traceExporterImpl, clock, traceConfig); } @Override diff --git a/core_impl_android/src/main/java/com/google/instrumentation/trace/RandomHandlerAndroid.java b/core_impl/src/main/java/com/google/instrumentation/trace/TracerImpl.java similarity index 61% rename from core_impl_android/src/main/java/com/google/instrumentation/trace/RandomHandlerAndroid.java rename to core_impl/src/main/java/com/google/instrumentation/trace/TracerImpl.java index 61a8697348..218124bb9d 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/trace/RandomHandlerAndroid.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TracerImpl.java @@ -13,21 +13,15 @@ package com.google.instrumentation.trace; -import java.security.SecureRandom; -import java.util.Random; -import javax.annotation.concurrent.ThreadSafe; +import com.google.instrumentation.common.Clock; -/** - * Implementation of the {@link RandomHandler} using {@link SecureRandom}. - */ -@ThreadSafe -final class RandomHandlerAndroid extends RandomHandler { - private final Random random = new SecureRandom(); - - RandomHandlerAndroid() {} - - @Override - Random current() { - return random; +/** Implementation of the {@link Tracer}. */ +final class TracerImpl extends Tracer { + TracerImpl( + RandomHandler randomHandler, + SpanImpl.StartEndHandler startEndHandler, + Clock clock, + TraceConfig traceConfig) { + super(new SpanFactoryImpl(randomHandler, startEndHandler, clock, traceConfig)); } } diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java index 362a2df075..d82c6d0955 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java @@ -17,6 +17,7 @@ import com.google.instrumentation.common.SimpleEventQueue; import com.google.instrumentation.internal.MillisClock; +import com.google.instrumentation.trace.RandomHandler.SecureRandomHandler; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -25,12 +26,12 @@ @RunWith(JUnit4.class) public class TraceComponentImplBaseTest { private final TraceComponent traceComponent = - new TraceComponentImplBase(MillisClock.getInstance(), new SimpleEventQueue()); + new TraceComponentImplBase( + MillisClock.getInstance(), new SecureRandomHandler(), new SimpleEventQueue()); @Test public void implementationOfTracer() { - // TODO(bdrutu): Change this when TracerImpl is available. - assertThat(traceComponent.getTracer()).isSameAs(Tracer.getNoopTracer()); + assertThat(traceComponent.getTracer()).isInstanceOf(TracerImpl.class); } @Test diff --git a/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java index 43416e6acb..cfa44e065c 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -15,11 +15,12 @@ import com.google.instrumentation.common.SimpleEventQueue; import com.google.instrumentation.internal.MillisClock; +import com.google.instrumentation.trace.RandomHandler.SecureRandomHandler; /** Android-compatible implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplBase { public TraceComponentImpl() { - super(MillisClock.getInstance(), new SimpleEventQueue()); + super(MillisClock.getInstance(), new SecureRandomHandler(), new SimpleEventQueue()); } } diff --git a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index 3111c1dc26..66a2b6d5e5 100644 --- a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -25,8 +25,7 @@ public class TraceComponentImplTest { @Test public void implementationOfTracer() { - // TODO(bdrutu): Change this when TracerImpl is available. - assertThat(Tracing.getTracer()).isSameAs(Tracer.getNoopTracer()); + assertThat(Tracing.getTracer()).isInstanceOf(TracerImpl.class); } @Test diff --git a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java index e1b164316d..2f9ff4d6e2 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -16,11 +16,10 @@ import com.google.instrumentation.common.DisruptorEventQueue; import com.google.instrumentation.internal.MillisClock; -/** - * Java 7 and 8 implementation of {@link StatsManager}. - */ +/** Java 7 and 8 implementation of {@link StatsManager}. */ public final class StatsManagerImpl extends StatsManagerImplBase { + /** Public constructor to be used with reflection loading. */ public StatsManagerImpl() { super(DisruptorEventQueue.getInstance(), MillisClock.getInstance()); } diff --git a/core_impl_java/src/main/java/com/google/instrumentation/trace/RandomHandlerJava.java b/core_impl_java/src/main/java/com/google/instrumentation/trace/ThreadLocalRandomHandler.java similarity index 82% rename from core_impl_java/src/main/java/com/google/instrumentation/trace/RandomHandlerJava.java rename to core_impl_java/src/main/java/com/google/instrumentation/trace/ThreadLocalRandomHandler.java index d04000fbcf..c467a897c6 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/trace/RandomHandlerJava.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/trace/ThreadLocalRandomHandler.java @@ -17,12 +17,10 @@ import java.util.concurrent.ThreadLocalRandom; import javax.annotation.concurrent.ThreadSafe; -/** - * Implementation of the {@link RandomHandler} using {@link ThreadLocalRandom}. - */ +/** Implementation of the {@link RandomHandler} using {@link ThreadLocalRandom}. */ @ThreadSafe -final class RandomHandlerJava extends RandomHandler { - RandomHandlerJava() {} +final class ThreadLocalRandomHandler extends RandomHandler { + ThreadLocalRandomHandler() {} @Override Random current() { diff --git a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java index 6ced470645..766bc7fbd4 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -19,7 +19,11 @@ /** Java 7 and 8 implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplBase { + /** Public constructor to be used with reflection loading. */ public TraceComponentImpl() { - super(MillisClock.getInstance(), DisruptorEventQueue.getInstance()); + super( + MillisClock.getInstance(), + new ThreadLocalRandomHandler(), + DisruptorEventQueue.getInstance()); } } diff --git a/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java b/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java index 8678290391..dcff6973ea 100644 --- a/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java +++ b/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java @@ -25,8 +25,7 @@ public class TracingTest { @Test public void implementationOfTracer() { - // TODO(bdrutu): Change this when TracerImpl is available. - assertThat(Tracing.getTracer()).isSameAs(Tracer.getNoopTracer()); + assertThat(Tracing.getTracer()).isInstanceOf(TracerImpl.class); } @Test From 8eb9bf893d69d67f1f62fef8c9e9a736f1571d8c Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 10 May 2017 15:53:50 -0700 Subject: [PATCH 0072/1581] Improve formatting of DistributionAggregation's Javadocs and check invariants. --- .../stats/DistributionAggregation.java | 111 ++++++++++++------ 1 file changed, 77 insertions(+), 34 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java b/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java index 9900bf0aec..a6aeaa475d 100644 --- a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java +++ b/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java @@ -14,6 +14,7 @@ package com.google.instrumentation.stats; import com.google.auto.value.AutoValue; +import com.google.common.base.Preconditions; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -28,14 +29,22 @@ * histogram representing the distribution of those values across a specified set of histogram * buckets, as defined in {@link DistributionAggregationDescriptor#getBucketBoundaries()}. * - *

Although not forbidden, it is generally a bad idea to include non-finite values (infinities - * or NaNs) in the population of values, as this will render the {@code mean} meaningless. + *

Although not forbidden, it is generally a bad idea to include non-finite values (infinities or + * NaNs) in the population of values, as this will render the {@code mean} meaningless. */ @Immutable @AutoValue public abstract class DistributionAggregation { /** - * Constructs a new {@link DistributionAggregation}. + * Constructs a {@code DistributionAggregation} without bucket counts. + * + * @param count the number of values in the population. It must be non-negative. + * @param mean the arithmetic mean of the values. If {@code count} is zero then this value must + * also be zero. + * @param sum the sum of the values. If {@code count} is zero then this value must also be zero. + * @param range the range of the values. + * @param tags the {@code Tag}s associated with the {@code DistributionAggregation}. + * @return a {@code DistributionAggregation} without bucket counts. */ public static DistributionAggregation create( long count, double mean, double sum, Range range, List tags) { @@ -43,93 +52,127 @@ public static DistributionAggregation create( } /** - * Constructs a new {@link DistributionAggregation} with the optional {@code bucketCount}s. + * Constructs a {@code DistributionAggregation} with bucket counts. + * + * @param count the number of values in the population. It must be non-negative. + * @param mean the arithmetic mean of the values. If {@code count} is zero then this value must + * also be zero. + * @param sum the sum of the values. If {@code count} is zero then this value must also be zero. + * @param range the range of the values. + * @param tags the {@code Tag}s associated with the {@code DistributionAggregation}. + * @param bucketCounts the bucket counts for the histogram associated with the {@code + * DistributionAggregation}. + * @return a {@code DistributionAggregation} with bucket counts. */ public static DistributionAggregation create( long count, double mean, double sum, Range range, List tags, List bucketCounts) { - return createInternal(count, mean, sum, range, tags, + return createInternal( + count, + mean, + sum, + range, + tags, Collections.unmodifiableList(new ArrayList(bucketCounts))); } private static DistributionAggregation createInternal( long count, double mean, double sum, Range range, List tags, List bucketCounts) { + Preconditions.checkArgument(count >= 0); + Preconditions.checkArgument(count != 0 || mean == 0); + Preconditions.checkArgument(count != 0 || sum == 0); return new AutoValue_DistributionAggregation(count, mean, sum, range, tags, bucketCounts); } /** - * The number of values in the population. Must be non-negative. + * Returns the number of values in the population. + * + * @return the number of values in the population. */ public abstract long getCount(); /** - * The arithmetic mean of the values in the population. If {@link #getCount()} is zero then this - * value must also be zero. + * Returns the arithmetic mean of the values in the population. + * + * @return the arithmetic mean of the values in the population. */ public abstract double getMean(); /** - * The sum of the values in the population. If {@link #getCount()} is zero then this values must - * also be zero. + * Returns the sum of the values in the population. + * + * @return the sum of the values in the population. */ public abstract double getSum(); /** - * The range of the population values. If {@link #getCount()} is zero then this returned range is - * implementation-dependent. + * Returns the range of the population values. If {@link #getCount()} is zero then the returned + * range is implementation-dependent. + * + * @return the range of the population values. */ public abstract Range getRange(); /** - * {@link Tag}s associated with this {@link DistributionAggregation}. + * Returns the {@code Tag}s associated with this {@code DistributionAggregation}. * - *

Note: The returned list is unmodifiable, attempts to update it will throw an - * UnsupportedOperationException. + * @return the {@code Tag}s associated with this {@code DistributionAggregation}. */ public abstract List getTags(); /** - * A Distribution may optionally contain a histogram of the values in the population. The - * histogram is given in {@link #getBucketCounts()} as counts of values that fall into one of a - * sequence of non-overlapping buckets, described by - * {@link DistributionAggregationDescriptor#getBucketBoundaries()}. - * The sum of the values in {@link #getBucketCounts()} must equal the value in - * {@link #getCount()}. + * Returns the bucket counts, or {@code null} if this {@code DistributionAggregation}'s associated + * {@link DistributionAggregationDescriptor} has no buckets. + * + *

A Distribution may contain a histogram of the values in the population. The histogram is + * given in {@link #getBucketCounts()} as counts of values that fall into one of a sequence of + * non-overlapping buckets, described by {@link + * DistributionAggregationDescriptor#getBucketBoundaries()}. The sum of the values in {@link + * #getBucketCounts()} must equal the value in {@link #getCount()}. * - *

Bucket counts are given in order under the numbering scheme described - * above (the underflow bucket has number 0; the finite buckets, if any, - * have numbers 1 through N-2; the overflow bucket has number N-1). + *

Bucket counts are given in order under the numbering scheme described in the link above (the + * underflow bucket has number 0; the finite buckets, if any, have numbers 1 through N-2; the + * overflow bucket has number N-1). * - *

The size of {@link #getBucketCounts()} must be no greater than N as defined in - * {@link DistributionAggregationDescriptor#getBucketBoundaries()}. + *

The size of {@link #getBucketCounts()} must be no greater than N as defined in {@link + * DistributionAggregationDescriptor#getBucketBoundaries()}. * *

Any suffix of trailing buckets containing only zero may be omitted. * - *

{@link #getBucketCounts()} will return null iff the associated - * {@link DistributionAggregationDescriptor#getBucketBoundaries()} returns null. + *

{@link #getBucketCounts()} will return null iff the associated {@link + * DistributionAggregationDescriptor#getBucketBoundaries()} returns null. + * + * @return the bucket counts, or {@code null} if this {@code DistributionAggregation}'s associated + * {@link DistributionAggregationDescriptor} has no buckets. */ @Nullable public abstract List getBucketCounts(); - /** - * Describes a range of population values. - */ + /** The range of a population's values. */ @Immutable @AutoValue public abstract static class Range { /** - * Constructs a new {@link Range}. + * Returns a {@code Range} with the given bounds. + * + * @param min the minimum of the population values. + * @param max the maximum of the population values. + * @return a {@code Range} with the given bounds. */ public static Range create(double min, double max) { return new AutoValue_DistributionAggregation_Range(min, max); } /** - * The minimum of the population values. + * Returns the minimum of the population values. + * + * @return the minimum of the population values. */ public abstract double getMin(); /** - * The maximum of the population values. + * Returns the maximum of the population values. + * + * @return the maximum of the population values. */ public abstract double getMax(); } From 86c48eb546f5de39fc9dd8cb1446dec70873018e Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 10 May 2017 16:47:52 -0700 Subject: [PATCH 0073/1581] Update gRPC context dependency version to 1.3.0. (#295) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 22c4628adf..c423917f67 100644 --- a/build.gradle +++ b/build.gradle @@ -100,7 +100,7 @@ subprojects { ext { autoValueVersion = '1.4' guavaVersion = '19.0' - grpcContextVersion = '1.2.0' + grpcContextVersion = '1.3.0' libraries = [ auto_value : "com.google.auto.value:auto-value:${autoValueVersion}", From cc416d09e5a2000749568a8e57e924a7444c094e Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 12 May 2017 00:01:58 -0700 Subject: [PATCH 0074/1581] Add implementation to support annotations,links and network events. (#296) * Add implementation to support annotations,links and network events. --- .../trace/SpanFactoryImpl.java | 1 + .../instrumentation/trace/SpanImpl.java | 165 ++++++++++++- .../instrumentation/trace/SpanImplTest.java | 229 +++++++++++++++++- .../trace/TraceExporterImplTest.java | 3 + 4 files changed, 384 insertions(+), 14 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java index be651d0c90..38c1c5f8a8 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java @@ -96,6 +96,7 @@ Span startSpanInternal( name, parentSpanId, hasRemoteParent, + activeTraceParams, startEndHandler, timestampConverter, clock); diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java index 671a990bd9..96fced49b5 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java @@ -13,11 +13,17 @@ package com.google.instrumentation.trace; +import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; +import com.google.common.collect.EvictingQueue; import com.google.instrumentation.common.Clock; +import com.google.instrumentation.trace.SpanData.TimedEvent; +import com.google.instrumentation.trace.TraceConfig.TraceParams; +import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; +import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -34,6 +40,8 @@ final class SpanImpl extends Span { private final SpanId parentSpanId; // True if the parent is on a different process. private final boolean hasRemoteParent; + // Active trace params when the Span was created. + private final TraceParams traceParams; // Handler called when the span starts and ends. private final StartEndHandler startEndHandler; // The displayed name of the span. @@ -46,6 +54,15 @@ final class SpanImpl extends Span { // The start time of the span. Set when the span is created iff the RECORD_EVENTS options is // set, otherwise 0. private final long startNanoTime; + // List of the recorded annotations. + @GuardedBy("this") + private TraceEvents> annotations; + // List of the recorded network events. + @GuardedBy("this") + private TraceEvents> networkEvents; + // List of the recorded links. + @GuardedBy("this") + private TraceEvents links; // The status of the span. Set when the span is ended iff the RECORD_EVENTS options is set. @GuardedBy("this") private Status status; @@ -66,6 +83,7 @@ static SpanImpl startSpan( String name, @Nullable SpanId parentSpanId, boolean hasRemoteParent, + TraceParams traceParams, StartEndHandler startEndHandler, @Nullable TimestampConverter timestampConverter, Clock clock) { @@ -76,6 +94,7 @@ static SpanImpl startSpan( name, parentSpanId, hasRemoteParent, + traceParams, startEndHandler, timestampConverter, clock); @@ -117,8 +136,15 @@ SpanData toSpanData() { getOptions().contains(Options.RECORD_EVENTS), "Getting SpanData for a Span without RECORD_EVENTS option."); synchronized (this) { - // TODO(bdrutu): Set the attributes, annotations, network events and links in the SpanData - // when add the support for them. + // TODO(bdrutu): Set the attributes in the SpanData when add the support for them. + SpanData.TimedEvents annotationsSpanData = + createTimedEvents(annotations, timestampConverter); + SpanData.TimedEvents networkEventsSpanData = + createTimedEvents(networkEvents, timestampConverter); + SpanData.Links linksSpanData = + links == null + ? SpanData.Links.create(Collections.emptyList(), 0) + : SpanData.Links.create(new ArrayList(links.events), links.getDroppedEvents()); return SpanData.create( getContext(), parentSpanId, @@ -126,10 +152,9 @@ SpanData toSpanData() { name, timestampConverter.convertNanoTime(startNanoTime), SpanData.Attributes.create(Collections.emptyMap(), 0), - SpanData.TimedEvents.create(Collections.>emptyList(), 0), - SpanData.TimedEvents.create( - Collections.>emptyList(), 0), - SpanData.Links.create(Collections.emptyList(), 0), + annotationsSpanData, + networkEventsSpanData, + linksSpanData, hasBeenEnded ? status : null, hasBeenEnded ? timestampConverter.convertNanoTime(endNanoTime) : null); } @@ -142,22 +167,68 @@ public void addAttributes(Map attributes) { @Override public void addAnnotation(String description, Map attributes) { - // TODO(bdrutu): Implement this. + if (!getOptions().contains(Options.RECORD_EVENTS)) { + return; + } + synchronized (this) { + if (hasBeenEnded) { + logger.log(Level.FINE, "Calling end() on an ended Span."); + return; + } + getInitializedAnnotations() + .addEvent( + new EventWithNanoTime( + clock.nowNanos(), + Annotation.fromDescriptionAndAttributes(description, attributes))); + } } @Override public void addAnnotation(Annotation annotation) { - // TODO(bdrutu): Implement this. + if (!getOptions().contains(Options.RECORD_EVENTS)) { + return; + } + synchronized (this) { + if (hasBeenEnded) { + logger.log(Level.FINE, "Calling end() on an ended Span."); + return; + } + getInitializedAnnotations() + .addEvent( + new EventWithNanoTime( + clock.nowNanos(), checkNotNull(annotation, "annotation"))); + } } @Override public void addNetworkEvent(NetworkEvent networkEvent) { - // TODO(bdrutu): Implement this. + if (!getOptions().contains(Options.RECORD_EVENTS)) { + return; + } + synchronized (this) { + if (hasBeenEnded) { + logger.log(Level.FINE, "Calling end() on an ended Span."); + return; + } + getInitializedNetworkEvents() + .addEvent( + new EventWithNanoTime( + clock.nowNanos(), checkNotNull(networkEvent, "networkEvent"))); + } } @Override public void addLink(Link link) { - // TODO(bdrutu): Implement this. + if (!getOptions().contains(Options.RECORD_EVENTS)) { + return; + } + synchronized (this) { + if (hasBeenEnded) { + logger.log(Level.FINE, "Calling end() on an ended Span."); + return; + } + getInitializedLinks().addEvent(checkNotNull(link, "link")); + } } @Override @@ -177,6 +248,45 @@ public void end(EndSpanOptions options) { } } + @GuardedBy("this") + private TraceEvents> getInitializedAnnotations() { + if (annotations == null) { + annotations = + new TraceEvents>(traceParams.getMaxNumberOfAnnotations()); + } + return annotations; + } + + @GuardedBy("this") + private TraceEvents> getInitializedNetworkEvents() { + if (networkEvents == null) { + networkEvents = + new TraceEvents>( + traceParams.getMaxNumberOfNetworkEvents()); + } + return networkEvents; + } + + @GuardedBy("this") + private TraceEvents getInitializedLinks() { + if (links == null) { + links = new TraceEvents(traceParams.getMaxNumberOfLinks()); + } + return links; + } + + private static SpanData.TimedEvents createTimedEvents( + TraceEvents> events, TimestampConverter timestampConverter) { + if (events == null) { + return SpanData.TimedEvents.create(Collections.>emptyList(), 0); + } + List> eventsList = new ArrayList>(events.events.size()); + for (EventWithNanoTime networkEvent : events.events) { + eventsList.add(networkEvent.toSpanDataTimedEvent(timestampConverter)); + } + return SpanData.TimedEvents.create(eventsList, events.getDroppedEvents()); + } + /** * Interface to handle the start and end operations for a {@link Span} only when the {@code Span} * has {@link Span.Options#RECORD_EVENTS} option. @@ -193,12 +303,46 @@ interface StartEndHandler { void onEnd(SpanImpl span); } + private static final class TraceEvents { + private int totalRecordedevents = 0; + private final EvictingQueue events; + + private int getDroppedEvents() { + return totalRecordedevents - events.size(); + } + + TraceEvents(int maxNumEvents) { + events = EvictingQueue.create(maxNumEvents); + } + + void addEvent(T event) { + totalRecordedevents++; + events.add(event); + } + } + + // Timed event that uses nanoTime to represent the Timestamp. + private static final class EventWithNanoTime { + private final long nanoTime; + private final T event; + + private EventWithNanoTime(long nanoTime, T event) { + this.nanoTime = nanoTime; + this.event = event; + } + + private SpanData.TimedEvent toSpanDataTimedEvent(TimestampConverter timestampConverter) { + return SpanData.TimedEvent.create(timestampConverter.convertNanoTime(nanoTime), event); + } + } + private SpanImpl( SpanContext context, @Nullable EnumSet options, String name, @Nullable SpanId parentSpanId, boolean hasRemoteParent, + TraceParams traceParams, StartEndHandler startEndHandler, @Nullable TimestampConverter timestampConverter, Clock clock) { @@ -206,6 +350,7 @@ private SpanImpl( this.parentSpanId = parentSpanId; this.hasRemoteParent = hasRemoteParent; this.name = name; + this.traceParams = traceParams; this.startEndHandler = startEndHandler; this.clock = clock; this.hasBeenEnded = false; diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java index 7b03aecc5f..1de4b088fe 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java @@ -20,7 +20,10 @@ import com.google.instrumentation.internal.TestClock; import com.google.instrumentation.trace.Span.Options; import com.google.instrumentation.trace.SpanImpl.StartEndHandler; +import com.google.instrumentation.trace.TraceConfig.TraceParams; import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; import java.util.Random; import org.junit.Before; import org.junit.Rule; @@ -36,6 +39,7 @@ @RunWith(JUnit4.class) public class SpanImplTest { private static final String SPAN_NAME = "MySpanName"; + private static final String ANNOTATION_DESCRIPTION = "MyAnnotation"; private final Random random = new Random(1234); private final SpanContext spanContext = SpanContext.create( @@ -44,14 +48,17 @@ public class SpanImplTest { private final Timestamp timestamp = Timestamp.create(1234, 5678); private final TestClock testClock = TestClock.create(timestamp); private final TimestampConverter timestampConverter = TimestampConverter.now(testClock); - private EnumSet noRecordSpanOptions = EnumSet.noneOf(Options.class); - private EnumSet recordSpanOptions = EnumSet.of(Options.RECORD_EVENTS); + private final EnumSet noRecordSpanOptions = EnumSet.noneOf(Options.class); + private final EnumSet recordSpanOptions = EnumSet.of(Options.RECORD_EVENTS); + private final Map attributes = new HashMap(); @Mock private StartEndHandler startEndHandler; @Rule public final ExpectedException exception = ExpectedException.none(); @Before public void setUp() { MockitoAnnotations.initMocks(this); + attributes.put( + "MyStringAttributeKey", AttributeValue.stringAttributeValue("MyStringAttributeValue")); } @Test @@ -63,14 +70,48 @@ public void toSpanData_NoRecordEvents() { SPAN_NAME, parentSpanId, false, + TraceParams.DEFAULT, startEndHandler, timestampConverter, testClock); + // Check that adding trace events after Span#end() does not throw any exception. + span.addAnnotation(Annotation.fromDescription(ANNOTATION_DESCRIPTION)); + span.addAnnotation(ANNOTATION_DESCRIPTION, attributes); + span.addNetworkEvent(NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build()); + span.addLink(Link.fromSpanContext(spanContext, Link.Type.CHILD)); span.end(); exception.expect(IllegalStateException.class); span.toSpanData(); } + @Test + public void noEventsRecordedAfterEnd() { + SpanImpl span = + SpanImpl.startSpan( + spanContext, + recordSpanOptions, + SPAN_NAME, + parentSpanId, + false, + TraceParams.DEFAULT, + startEndHandler, + timestampConverter, + testClock); + span.end(); + // Check that adding trace events after Span#end() does not throw any exception. + span.addAnnotation(Annotation.fromDescription(ANNOTATION_DESCRIPTION)); + span.addAnnotation(ANNOTATION_DESCRIPTION, attributes); + span.addNetworkEvent(NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build()); + span.addLink(Link.fromSpanContext(spanContext, Link.Type.CHILD)); + SpanData spanData = span.toSpanData(); + assertThat(spanData.getStartTimestamp()).isEqualTo(timestamp); + assertThat(spanData.getAnnotations().getEvents()).isEmpty(); + assertThat(spanData.getNetworkEvents().getEvents()).isEmpty(); + assertThat(spanData.getLinks().getLinks()).isEmpty(); + assertThat(spanData.getStatus()).isEqualTo(Status.OK); + assertThat(spanData.getEndTimestamp()).isEqualTo(timestamp); + } + @Test public void toSpanData_ActiveSpan() { SpanImpl span = @@ -80,15 +121,45 @@ public void toSpanData_ActiveSpan() { SPAN_NAME, parentSpanId, true, + TraceParams.DEFAULT, startEndHandler, timestampConverter, testClock); Mockito.verify(startEndHandler, Mockito.times(1)).onStart(span); + testClock.advanceTime(Duration.create(0, 100)); + span.addAnnotation(Annotation.fromDescription(ANNOTATION_DESCRIPTION)); + testClock.advanceTime(Duration.create(0, 100)); + span.addAnnotation(ANNOTATION_DESCRIPTION, attributes); + testClock.advanceTime(Duration.create(0, 100)); + NetworkEvent networkEvent = + NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build(); + span.addNetworkEvent(networkEvent); + testClock.advanceTime(Duration.create(0, 100)); + Link link = Link.fromSpanContext(spanContext, Link.Type.CHILD); + span.addLink(link); SpanData spanData = span.toSpanData(); assertThat(spanData.getContext()).isEqualTo(spanContext); assertThat(spanData.getDisplayName()).isEqualTo(SPAN_NAME); assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); assertThat(spanData.getHasRemoteParent()).isTrue(); + assertThat(spanData.getAnnotations().getDroppedEventsCount()).isEqualTo(0); + assertThat(spanData.getAnnotations().getEvents().size()).isEqualTo(2); + assertThat(spanData.getAnnotations().getEvents().get(0).getTimestamp()) + .isEqualTo(timestamp.addNanos(100)); + assertThat(spanData.getAnnotations().getEvents().get(0).getEvent()) + .isEqualTo(Annotation.fromDescription(ANNOTATION_DESCRIPTION)); + assertThat(spanData.getAnnotations().getEvents().get(1).getTimestamp()) + .isEqualTo(timestamp.addNanos(200)); + assertThat(spanData.getAnnotations().getEvents().get(1).getEvent()) + .isEqualTo(Annotation.fromDescriptionAndAttributes(ANNOTATION_DESCRIPTION, attributes)); + assertThat(spanData.getNetworkEvents().getDroppedEventsCount()).isEqualTo(0); + assertThat(spanData.getNetworkEvents().getEvents().size()).isEqualTo(1); + assertThat(spanData.getNetworkEvents().getEvents().get(0).getTimestamp()) + .isEqualTo(timestamp.addNanos(300)); + assertThat(spanData.getNetworkEvents().getEvents().get(0).getEvent()).isEqualTo(networkEvent); + assertThat(spanData.getLinks().getDroppedLinksCount()).isEqualTo(0); + assertThat(spanData.getLinks().getLinks().size()).isEqualTo(1); + assertThat(spanData.getLinks().getLinks().get(0)).isEqualTo(link); assertThat(spanData.getStartTimestamp()).isEqualTo(timestamp); assertThat(spanData.getStatus()).isNull(); assertThat(spanData.getEndTimestamp()).isNull(); @@ -103,11 +174,22 @@ public void toSpanData_EndedSpan() { SPAN_NAME, parentSpanId, false, + TraceParams.DEFAULT, startEndHandler, timestampConverter, testClock); Mockito.verify(startEndHandler, Mockito.times(1)).onStart(span); - testClock.advanceTime(Duration.create(0, 7777)); + testClock.advanceTime(Duration.create(0, 100)); + span.addAnnotation(Annotation.fromDescription(ANNOTATION_DESCRIPTION)); + testClock.advanceTime(Duration.create(0, 100)); + span.addAnnotation(ANNOTATION_DESCRIPTION, attributes); + testClock.advanceTime(Duration.create(0, 100)); + NetworkEvent networkEvent = + NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build(); + span.addNetworkEvent(networkEvent); + Link link = Link.fromSpanContext(spanContext, Link.Type.CHILD); + span.addLink(link); + testClock.advanceTime(Duration.create(0, 100)); span.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build()); Mockito.verify(startEndHandler, Mockito.times(1)).onEnd(span); SpanData spanData = span.toSpanData(); @@ -115,8 +197,147 @@ public void toSpanData_EndedSpan() { assertThat(spanData.getDisplayName()).isEqualTo(SPAN_NAME); assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); assertThat(spanData.getHasRemoteParent()).isFalse(); + assertThat(spanData.getAnnotations().getDroppedEventsCount()).isEqualTo(0); + assertThat(spanData.getAnnotations().getEvents().size()).isEqualTo(2); + assertThat(spanData.getAnnotations().getEvents().get(0).getTimestamp()) + .isEqualTo(timestamp.addNanos(100)); + assertThat(spanData.getAnnotations().getEvents().get(0).getEvent()) + .isEqualTo(Annotation.fromDescription(ANNOTATION_DESCRIPTION)); + assertThat(spanData.getAnnotations().getEvents().get(1).getTimestamp()) + .isEqualTo(timestamp.addNanos(200)); + assertThat(spanData.getAnnotations().getEvents().get(1).getEvent()) + .isEqualTo(Annotation.fromDescriptionAndAttributes(ANNOTATION_DESCRIPTION, attributes)); + assertThat(spanData.getNetworkEvents().getDroppedEventsCount()).isEqualTo(0); + assertThat(spanData.getNetworkEvents().getEvents().size()).isEqualTo(1); + assertThat(spanData.getNetworkEvents().getEvents().get(0).getTimestamp()) + .isEqualTo(timestamp.addNanos(300)); + assertThat(spanData.getNetworkEvents().getEvents().get(0).getEvent()).isEqualTo(networkEvent); + assertThat(spanData.getLinks().getDroppedLinksCount()).isEqualTo(0); + assertThat(spanData.getLinks().getLinks().size()).isEqualTo(1); + assertThat(spanData.getLinks().getLinks().get(0)).isEqualTo(link); assertThat(spanData.getStartTimestamp()).isEqualTo(timestamp); assertThat(spanData.getStatus()).isEqualTo(Status.CANCELLED); - assertThat(spanData.getEndTimestamp()).isEqualTo(timestamp.addNanos(7777)); + assertThat(spanData.getEndTimestamp()).isEqualTo(timestamp.addNanos(400)); + } + + @Test + public void droppingAnnotations() { + final int maxNumberOfAnnotations = 8; + TraceParams traceParams = + TraceParams.DEFAULT.toBuilder().setMaxNumberOfAnnotations(maxNumberOfAnnotations).build(); + SpanImpl span = + SpanImpl.startSpan( + spanContext, + recordSpanOptions, + SPAN_NAME, + parentSpanId, + false, + traceParams, + startEndHandler, + timestampConverter, + testClock); + Annotation annotation = Annotation.fromDescription(ANNOTATION_DESCRIPTION); + for (int i = 0; i < 2 * maxNumberOfAnnotations; i++) { + span.addAnnotation(annotation); + testClock.advanceTime(Duration.create(0, 100)); + } + SpanData spanData = span.toSpanData(); + assertThat(spanData.getAnnotations().getDroppedEventsCount()).isEqualTo(maxNumberOfAnnotations); + assertThat(spanData.getAnnotations().getEvents().size()).isEqualTo(maxNumberOfAnnotations); + for (int i = 0; i < maxNumberOfAnnotations; i++) { + assertThat(spanData.getAnnotations().getEvents().get(i).getTimestamp()) + .isEqualTo(timestamp.addNanos(100 * (maxNumberOfAnnotations + i))); + assertThat(spanData.getAnnotations().getEvents().get(i).getEvent()).isEqualTo(annotation); + } + span.end(); + spanData = span.toSpanData(); + assertThat(spanData.getAnnotations().getDroppedEventsCount()).isEqualTo(maxNumberOfAnnotations); + assertThat(spanData.getAnnotations().getEvents().size()).isEqualTo(maxNumberOfAnnotations); + for (int i = 0; i < maxNumberOfAnnotations; i++) { + assertThat(spanData.getAnnotations().getEvents().get(i).getTimestamp()) + .isEqualTo(timestamp.addNanos(100 * (maxNumberOfAnnotations + i))); + assertThat(spanData.getAnnotations().getEvents().get(i).getEvent()).isEqualTo(annotation); + } + } + + @Test + public void droppingNetworkEvents() { + final int maxNumberOfNetworkEvents = 8; + TraceParams traceParams = + TraceParams.DEFAULT + .toBuilder() + .setMaxNumberOfNetworkEvents(maxNumberOfNetworkEvents) + .build(); + SpanImpl span = + SpanImpl.startSpan( + spanContext, + recordSpanOptions, + SPAN_NAME, + parentSpanId, + false, + traceParams, + startEndHandler, + timestampConverter, + testClock); + NetworkEvent networkEvent = + NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build(); + for (int i = 0; i < 2 * maxNumberOfNetworkEvents; i++) { + span.addNetworkEvent(networkEvent); + testClock.advanceTime(Duration.create(0, 100)); + } + SpanData spanData = span.toSpanData(); + assertThat(spanData.getNetworkEvents().getDroppedEventsCount()) + .isEqualTo(maxNumberOfNetworkEvents); + assertThat(spanData.getNetworkEvents().getEvents().size()).isEqualTo(maxNumberOfNetworkEvents); + for (int i = 0; i < maxNumberOfNetworkEvents; i++) { + assertThat(spanData.getNetworkEvents().getEvents().get(i).getTimestamp()) + .isEqualTo(timestamp.addNanos(100 * (maxNumberOfNetworkEvents + i))); + assertThat(spanData.getNetworkEvents().getEvents().get(i).getEvent()).isEqualTo(networkEvent); + } + span.end(); + spanData = span.toSpanData(); + assertThat(spanData.getNetworkEvents().getDroppedEventsCount()) + .isEqualTo(maxNumberOfNetworkEvents); + assertThat(spanData.getNetworkEvents().getEvents().size()).isEqualTo(maxNumberOfNetworkEvents); + for (int i = 0; i < maxNumberOfNetworkEvents; i++) { + assertThat(spanData.getNetworkEvents().getEvents().get(i).getTimestamp()) + .isEqualTo(timestamp.addNanos(100 * (maxNumberOfNetworkEvents + i))); + assertThat(spanData.getNetworkEvents().getEvents().get(i).getEvent()).isEqualTo(networkEvent); + } + } + + @Test + public void droppingLinks() { + final int maxNumberOfLinks = 8; + TraceParams traceParams = + TraceParams.DEFAULT.toBuilder().setMaxNumberOfLinks(maxNumberOfLinks).build(); + SpanImpl span = + SpanImpl.startSpan( + spanContext, + recordSpanOptions, + SPAN_NAME, + parentSpanId, + false, + traceParams, + startEndHandler, + timestampConverter, + testClock); + Link link = Link.fromSpanContext(spanContext, Link.Type.CHILD); + for (int i = 0; i < 2 * maxNumberOfLinks; i++) { + span.addLink(link); + } + SpanData spanData = span.toSpanData(); + assertThat(spanData.getLinks().getDroppedLinksCount()).isEqualTo(maxNumberOfLinks); + assertThat(spanData.getLinks().getLinks().size()).isEqualTo(maxNumberOfLinks); + for (int i = 0; i < maxNumberOfLinks; i++) { + assertThat(spanData.getLinks().getLinks().get(i)).isEqualTo(link); + } + span.end(); + spanData = span.toSpanData(); + assertThat(spanData.getLinks().getDroppedLinksCount()).isEqualTo(maxNumberOfLinks); + assertThat(spanData.getLinks().getLinks().size()).isEqualTo(maxNumberOfLinks); + for (int i = 0; i < maxNumberOfLinks; i++) { + assertThat(spanData.getLinks().getLinks().get(i)).isEqualTo(link); + } } } diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java index 22cd60be57..7a30d530c7 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java @@ -20,6 +20,7 @@ import com.google.instrumentation.common.SimpleEventQueue; import com.google.instrumentation.internal.MillisClock; import com.google.instrumentation.trace.Span.Options; +import com.google.instrumentation.trace.TraceConfig.TraceParams; import com.google.instrumentation.trace.TraceExporter.ServiceHandler; import java.util.ArrayList; import java.util.EnumSet; @@ -68,6 +69,7 @@ private final SpanImpl createSampledEndedSpan(String spanName) { spanName, null, false, + TraceParams.DEFAULT, traceExporter, null, MillisClock.getInstance()); @@ -83,6 +85,7 @@ private final SpanImpl createNotSampledEndedSpan(String spanName) { spanName, null, false, + TraceParams.DEFAULT, traceExporter, null, MillisClock.getInstance()); From 5a6e3454f63fcbdc598f5af10c7842d32bacfe26 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 12 May 2017 12:01:53 -0700 Subject: [PATCH 0075/1581] Rename gradle subprojects name to match the directories name. (#298) * Rename gradle subprojects name to match the directories name. Change the api jar name to match the maven artifact. Update gradle projects name in travis. --- .travis.yml | 4 ++-- all/build.gradle | 13 +++++-------- benchmarks/build.gradle | 6 +++--- build.gradle | 4 ++-- core/build.gradle | 4 ++++ core_impl/build.gradle | 4 ++-- core_impl_android/build.gradle | 4 ++-- core_impl_java/build.gradle | 4 ++-- examples/build.gradle | 6 +++--- settings.gradle | 28 ++++++++++++++-------------- 10 files changed, 39 insertions(+), 38 deletions(-) diff --git a/.travis.yml b/.travis.yml index 864e81357e..d7ae79caae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,7 +40,7 @@ script: ./gradlew clean assemble --stacktrace ; case "$TRAVIS_JDK_VERSION" in "oraclejdk8") - ./gradlew check :instrumentation-java-all:jacocoTestReport ;; + ./gradlew check :all:jacocoTestReport ;; "oraclejdk7") ./gradlew check ;; esac ;; @@ -51,7 +51,7 @@ script: after_success: - if \[ "$TASK" == "BUILD" \] && \[ "$TRAVIS_JDK_VERSION" == "oraclejdk8" \] && \[ "$TRAVIS_OS_NAME" = linux \]; then - ./gradlew :instrumentation-java-all:coveralls --stacktrace ; + ./gradlew :all:coveralls --stacktrace ; bash <(curl -s https://codecov.io/bash) ; fi diff --git a/all/build.gradle b/all/build.gradle index 143e4cb3e3..550b924c13 100644 --- a/all/build.gradle +++ b/all/build.gradle @@ -11,15 +11,12 @@ buildscript { } } -// TODO(sebright): Look into handling instrumentation-java-core-impl-java-7, -// instrumentation-java-core-impl-java-8, and -// instrumentation-java-core-impl-android. 'subprojects' currently doesn't -// include all directories, because Javadoc cannot handle multiple classes with -// the same name, such as StatsManagerImpl. +// TODO(bdrutu): core_impl_android subproject currently isn't included because Javadoc cannot +// handle multiple classes with the same name, such as StatsManagerImpl. def subprojects = [ - project(':instrumentation-java-core'), - project(':instrumentation-java-core-impl'), - project(':instrumentation-java-core-impl-java'), + project(':core'), + project(':core_impl'), + project(':core_impl_java'), ] for (subproject in rootProject.subprojects) { diff --git a/benchmarks/build.gradle b/benchmarks/build.gradle index b001f268b5..8b58bbf541 100644 --- a/benchmarks/build.gradle +++ b/benchmarks/build.gradle @@ -23,9 +23,9 @@ jmh { } dependencies { - compile project(':instrumentation-java-core'), - project(':instrumentation-java-core-impl') - project(':instrumentation-java-core-impl-java') + compile project(':core'), + project(':core_impl') + project(':core_impl_java') } compileJmhJava { diff --git a/build.gradle b/build.gradle index c423917f67..c1ea9c3286 100644 --- a/build.gradle +++ b/build.gradle @@ -215,7 +215,7 @@ subprojects { packaging 'jar' // Add a map with all the project.name -> artifactId when we // are going to upload more artifacts. - artifactId 'instrumentation-api' + artifactId jar.baseName description project.description url 'https://github.com/google/instrumentation-java' @@ -247,7 +247,7 @@ subprojects { } } // For the moment we upload only the artifact for the API - uploadArchives.onlyIf { name == 'instrumentation-java-core'} + uploadArchives.onlyIf { name == 'core'} // At a test failure, log the stack trace to the console so that we don't // have to open the HTML in a browser. diff --git a/core/build.gradle b/core/build.gradle index c7516a6771..ec1b7c5978 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -1,5 +1,9 @@ description = 'Instrumentation: API' +jar { + baseName = 'instrumentation-api' +} + dependencies { compile libraries.grpc_context, libraries.guava diff --git a/core_impl/build.gradle b/core_impl/build.gradle index d0f5564b8b..5040d69c35 100644 --- a/core_impl/build.gradle +++ b/core_impl/build.gradle @@ -1,14 +1,14 @@ description = 'Instrumentation Core Impl' dependencies { - compile project(':instrumentation-java-core'), + compile project(':core'), project(':shared'), libraries.auto_value, libraries.guava compileOnly libraries.auto_value - testCompile project(':instrumentation-java-core') + testCompile project(':core') signature "org.codehaus.mojo.signature:java16:+@signature" } diff --git a/core_impl_android/build.gradle b/core_impl_android/build.gradle index fc205157bc..17249dacee 100644 --- a/core_impl_android/build.gradle +++ b/core_impl_android/build.gradle @@ -1,8 +1,8 @@ description = 'Instrumentation Core Impl Android' dependencies { - compile project(':instrumentation-java-core'), - project(':instrumentation-java-core-impl') + compile project(':core'), + project(':core_impl') signature "net.sf.androidscents.signature:android-api-level-14:+@signature" } diff --git a/core_impl_java/build.gradle b/core_impl_java/build.gradle index 149fae40ee..a223ac6396 100644 --- a/core_impl_java/build.gradle +++ b/core_impl_java/build.gradle @@ -8,8 +8,8 @@ apply plugin: 'java' } dependencies { - compile project(':instrumentation-java-core'), - project(':instrumentation-java-core-impl'), + compile project(':core'), + project(':core_impl'), libraries.disruptor signature "org.codehaus.mojo.signature:java17:+@signature" diff --git a/examples/build.gradle b/examples/build.gradle index e69c088e52..30b305e9f8 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -6,9 +6,9 @@ tasks.withType(JavaCompile) { } dependencies { - compile project(':instrumentation-java-core'), - project(':instrumentation-java-core-impl'), - project(':instrumentation-java-core-impl-java'), + compile project(':core'), + project(':core_impl'), + project(':core_impl_java'), libraries.grpc_context } diff --git a/settings.gradle b/settings.gradle index d06d25bb3d..5b0bb48057 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,23 +1,23 @@ rootProject.name = "instrumentation-java" -include ":instrumentation-java-all" -include ":instrumentation-java-core" -include ":instrumentation-java-core-impl" -include ":instrumentation-java-core-impl-java" -include ":instrumentation-java-core-impl-android" +include ":all" +include ":core" +include ":core_impl" +include ":core_impl_java" +include ":core_impl_android" include ":shared" -project(':instrumentation-java-all').projectDir = "$rootDir/all" as File -project(':instrumentation-java-core').projectDir = "$rootDir/core" as File -project(':instrumentation-java-core-impl').projectDir = "$rootDir/core_impl" as File -project(':instrumentation-java-core-impl-java').projectDir = "$rootDir/core_impl_java" as File -project(':instrumentation-java-core-impl-android').projectDir = "$rootDir/core_impl_android" as File +project(':all').projectDir = "$rootDir/all" as File +project(':core').projectDir = "$rootDir/core" as File +project(':core_impl').projectDir = "$rootDir/core_impl" as File +project(':core_impl_java').projectDir = "$rootDir/core_impl_java" as File +project(':core_impl_android').projectDir = "$rootDir/core_impl_android" as File project(':shared').projectDir = "$rootDir/shared" as File // Java8 projects only if (JavaVersion.current().isJava8Compatible()) { - include ":instrumentation-examples" - include ":instrumentation-java-benchmarks" + include ":examples" + include ":benchmarks" - project(':instrumentation-examples').projectDir = "$rootDir/examples" as File - project(':instrumentation-java-benchmarks').projectDir = "$rootDir/benchmarks" as File + project(':examples').projectDir = "$rootDir/examples" as File + project(':benchmarks').projectDir = "$rootDir/benchmarks" as File } From 10dc8019eb68e31651efad9e929f8977986d1860 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 12 May 2017 16:50:38 -0700 Subject: [PATCH 0076/1581] Fix comments in the serialization/deseralization. (#302) --- .../google/instrumentation/stats/StatsContextFactoryImpl.java | 2 +- .../java/com/google/instrumentation/stats/StatsContextImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java index fe528875b8..149e8c12d4 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java @@ -32,7 +32,7 @@ final class StatsContextFactoryImpl extends StatsContextFactory { } /** - * Deserializes a {@link StatsContextImpl} from a serialized {@code CensusContextProto}. + * Deserializes a {@link StatsContextImpl} using the format defined in {@code StatsSerializer}.. * *

The encoded tags are of the form: {@code } */ diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java index d13cd97cd3..e18d0829cd 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java @@ -44,7 +44,7 @@ public StatsContextImpl record(MeasurementMap stats) { } /** - * Serializes a {@link StatsContextImpl} into {@code CensusContextProto} serialized format. + * Serializes a {@link StatsContextImpl} using the format defined in {@code StatsSerializer}. * *

The encoded tags are of the form: {@code } */ From ae13e874b6b9c39302b56502b24fe8110c1190ff Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 12 May 2017 17:03:15 -0700 Subject: [PATCH 0077/1581] Disable ArgumentParameterMismatch Error Prone warning, because it is too noisy. --- gradle/errorprone/experimental_warnings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/errorprone/experimental_warnings b/gradle/errorprone/experimental_warnings index fc304d3ac5..296a65b363 100644 --- a/gradle/errorprone/experimental_warnings +++ b/gradle/errorprone/experimental_warnings @@ -1,5 +1,5 @@ errorProneExperimentalWarnings = \ --Xep:ArgumentParameterMismatch:ERROR,\ +-Xep:ArgumentParameterMismatch:OFF,\ -Xep:AssertFalse:ERROR,\ -Xep:AssistedInjectAndInjectOnConstructors:ERROR,\ -Xep:BigDecimalLiteralDouble:ERROR,\ From 8cb090eca94f938fd714a7177937c328921a4d0e Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 12 May 2017 17:09:16 -0700 Subject: [PATCH 0078/1581] Add a class for stats testing utilities. --- .../stats/StatsContextImpl.java | 4 +- .../instrumentation/stats/StatsTestUtil.java | 135 ++++++++++++++++++ 2 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java index d13cd97cd3..37f8dd052e 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java @@ -68,7 +68,7 @@ public String toString() { return tags.toString(); } - private static final class Builder extends StatsContext.Builder { + public static final class Builder extends StatsContext.Builder { private final StatsManagerImplBase statsManager; private final HashMap tags; @@ -84,7 +84,7 @@ public Builder set(TagKey key, TagValue value) { } @Override - public StatsContext build() { + public StatsContextImpl build() { return new StatsContextImpl( statsManager, Collections.unmodifiableMap(new HashMap(tags))); } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java new file mode 100644 index 0000000000..ab254a65b0 --- /dev/null +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java @@ -0,0 +1,135 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import com.google.common.base.Function; +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; +import com.google.common.truth.Truth; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** Stats test utilities. */ +public final class StatsTestUtil { + + private StatsTestUtil() {} + + /** + * Creates a {@code StatsContextImpl} from a factory and a list of alternating tag keys and + * values. + * + * @param factory the factory used to produce the {@code StatsContextImpl}. + * @param tagKeysAndValues a list of alternating {@link TagKey}s and {@link TagValue}s. It must + * have an even length. + * @return a {@code StatsContextImpl} with the given keys and values. + */ + public static StatsContextImpl createContext( + StatsContextFactoryImpl factory, Object... tagKeysAndValues) { + StatsContextImpl.Builder builder = factory.getDefault().builder(); + for (Iterator i = Arrays.asList(tagKeysAndValues).iterator(); i.hasNext(); ) { + TagKey key = (TagKey) i.next(); + TagValue value = (TagValue) i.next(); + builder.set(key, value); + } + return builder.build(); + } + + /** + * Creates a {@code DistributionAggregation} by adding the given values to a new {@link + * MutableDistribution}. + * + * @param tags the {@code DistributionAggregation}'s tags. + * @param bucketBoundaries the bucket boundaries. + * @param values the values to add to the distribution. + * @return the new {@code DistributionAggregation} + */ + public static DistributionAggregation createDistributionAggregation( + List tags, BucketBoundaries bucketBoundaries, List values) { + MutableDistribution mdist = MutableDistribution.create(bucketBoundaries); + for (double value : values) { + mdist.add(value); + } + MutableDistribution.Range range = mdist.getRange(); + return DistributionAggregation.create( + mdist.getCount(), + mdist.getMean(), + mdist.getSum(), + DistributionAggregation.Range.create(range.getMin(), range.getMax()), + tags, + mdist.getBucketCounts()); + } + + /** + * Asserts that the two sets of {@code DistributionAggregation}s are equivalent, with a given + * tolerance. The tolerance is used when comparing the mean and sum of values. The order of the + * {@code DistributionAggregation}s has no effect. The expected parameter is last, because it is + * likely to be a larger expression. + * + * @param tolerance the tolerance used for {@code double} comparison. + * @param actual the actual test result. + * @param expected the expected value. + * @throws AssertionError if the {@code DistributionAggregation}s don't match. + */ + public static void assertDistributionAggregationsEquivalent( + double tolerance, + Collection actual, + Collection expected) { + Function> getTagsFunction = + new Function>() { + @Override + public List apply(DistributionAggregation agg) { + return agg.getTags(); + } + }; + Iterable> expectedTags = Iterables.transform(expected, getTagsFunction); + Iterable> actualTags = Iterables.transform(actual, getTagsFunction); + Truth.assertThat(actualTags).containsExactlyElementsIn(expectedTags); + for (DistributionAggregation expectedAgg : expected) { + DistributionAggregation actualAgg = + Iterables.find( + actual, + Predicates.compose(Predicates.equalTo(expectedAgg.getTags()), getTagsFunction)); + assertDistributionAggregationValuesEquivalent( + "DistributionAggregation tags=" + expectedAgg.getTags(), + tolerance, + expectedAgg, + actualAgg); + } + } + + private static void assertDistributionAggregationValuesEquivalent( + String msg, double tolerance, DistributionAggregation agg1, DistributionAggregation agg2) { + Truth.assertWithMessage(msg + " count").that(agg1.getCount()).isEqualTo(agg2.getCount()); + Truth.assertWithMessage(msg + " mean") + .that(agg1.getMean()) + .isWithin(tolerance) + .of(agg2.getMean()); + Truth.assertWithMessage(msg + " sum").that(agg1.getSum()).isWithin(tolerance).of(agg2.getSum()); + Truth.assertWithMessage(msg + " range").that(agg1.getRange()).isEqualTo(agg2.getRange()); + Truth.assertWithMessage(msg + " bucket counts") + .that(removeTrailingZeros(agg1.getBucketCounts())) + .isEqualTo(removeTrailingZeros(agg2.getBucketCounts())); + } + + private static List removeTrailingZeros(List longs) { + List truncated = new ArrayList(longs); + while (!truncated.isEmpty() && Iterables.getLast(truncated) == 0) { + truncated.remove(truncated.size() - 1); + } + return truncated; + } +} From 3b06591336e6ddffbf828cb7b770c59aee459454 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 12 May 2017 17:10:40 -0700 Subject: [PATCH 0079/1581] Support arbitrary distribution views. This commit also updates the unit tests: - Adds tests that weren't possible when only one view was supported - Updates the existing tests so that they don't depend on specific RPC view constants - Refactors the existing getView tests to use StatsTestUtil --- .../stats/MeasurementDescriptorToViewMap.java | 16 +- .../stats/StatsManagerImplBase.java | 9 +- .../instrumentation/stats/SupportedViews.java | 25 - .../instrumentation/stats/ViewManager.java | 12 +- .../MeasurementDescriptorToViewMapTest.java | 36 +- .../stats/StatsManagerImplTest.java | 550 ++++++++++++------ 6 files changed, 424 insertions(+), 224 deletions(-) delete mode 100644 core_impl/src/main/java/com/google/instrumentation/stats/SupportedViews.java diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java index 5534e82230..19ca1ec75e 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java @@ -92,22 +92,14 @@ synchronized void registerView(ViewDescriptor viewDescriptor, Clock clock) { // Records stats with a set of tags. synchronized void record(StatsContextImpl tags, MeasurementMap stats) { for (MeasurementValue mv : stats) { - if (mv.getMeasurement() - .getMeasurementDescriptorName() - .equals(SupportedViews.SUPPORTED_MEASUREMENT_DESCRIPTOR.getMeasurementDescriptorName())) { - recordSupportedMeasurement(tags, mv.getValue()); + Collection views = + mutableMap.get(mv.getMeasurement().getMeasurementDescriptorName()); + for (MutableView view : views) { + view.record(tags, mv.getValue()); } } } - private void recordSupportedMeasurement(StatsContextImpl tags, double value) { - MutableView view = getMutableView(SupportedViews.SUPPORTED_VIEW.getViewDescriptorName()); - if (view == null) { - throw new IllegalArgumentException("View not registered yet."); - } - view.record(tags, value); - } - private static final class CreateMutableDistributionViewFunction implements Function { private final Clock clock; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java index 30a883f18c..e4bf1a413a 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java @@ -38,10 +38,15 @@ public void registerView(ViewDescriptor viewDescriptor) { viewManager.registerView(viewDescriptor); } - // TODO(sebright): This method should take a ViewDescriptor.Name. + // TODO(sebright): Replace this method with the ViewDescriptor.Name version. @Override public View getView(ViewDescriptor viewDescriptor) { - return viewManager.getView(viewDescriptor.getViewDescriptorName()); + return getView(viewDescriptor.getViewDescriptorName()); + } + + // TODO(sebright): Expose this method. + View getView(ViewDescriptor.Name viewName) { + return viewManager.getView(viewName); } @Override diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/SupportedViews.java b/core_impl/src/main/java/com/google/instrumentation/stats/SupportedViews.java deleted file mode 100644 index e5e7bae30c..0000000000 --- a/core_impl/src/main/java/com/google/instrumentation/stats/SupportedViews.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.stats; - -/** - * Constants specifying the view that is supported in the initial stats implementation. - */ -class SupportedViews { - static final ViewDescriptor SUPPORTED_VIEW = RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW; - static final MeasurementDescriptor SUPPORTED_MEASUREMENT_DESCRIPTOR = - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY; - - private SupportedViews() {} -} diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java index 243313107f..6cb242c89b 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java @@ -15,6 +15,7 @@ import com.google.instrumentation.common.Clock; import com.google.instrumentation.common.EventQueue; +import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; /** Object that stores all views and stats. */ final class ViewManager { @@ -33,14 +34,11 @@ final class ViewManager { } void registerView(ViewDescriptor viewDescriptor) { - // We are using a preset measurement RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY - // and view RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW for this prototype. - // The prototype does not allow setting measurement descriptor entries dynamically for now. - // TODO(songya): remove the logic for checking the preset descriptor. - if (!viewDescriptor.equals(SupportedViews.SUPPORTED_VIEW)) { + // Only DistributionViews are supported currently. + // TODO(sebright): Remove this once all views are supported. + if (!(viewDescriptor instanceof DistributionViewDescriptor)) { throw new UnsupportedOperationException( - "The prototype will only support Distribution View " - + SupportedViews.SUPPORTED_VIEW.getName()); + "The prototype will only support distribution views."); } measurementDescriptorToViewMap.registerView(viewDescriptor, clock); } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java index c6e219c22d..1efc5949bd 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java @@ -14,14 +14,17 @@ package com.google.instrumentation.stats; import static com.google.common.truth.Truth.assertThat; -import static com.google.instrumentation.stats.RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW; import static org.junit.Assert.fail; import com.google.instrumentation.common.Function; import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.internal.TestClock; +import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; +import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; import com.google.instrumentation.stats.View.DistributionView; import com.google.instrumentation.stats.View.IntervalView; +import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; +import java.util.Arrays; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -29,23 +32,36 @@ /** Tests for {@link MeasurementDescriptorToViewMap}. */ @RunWith(JUnit4.class) public class MeasurementDescriptorToViewMapTest { - private final MeasurementDescriptorToViewMap measurementDescriptorToViewMap = - new MeasurementDescriptorToViewMap(); + + private static final MeasurementDescriptor MEASUREMENT_DESCRIPTOR = + MeasurementDescriptor.create( + "my measurement", + "measurement description", + MeasurementUnit.create(0, Arrays.asList(BasicUnit.BYTES))); + + private static final ViewDescriptor.Name VIEW_NAME = ViewDescriptor.Name.create("my view"); + + private static final ViewDescriptor VIEW_DESCRIPTOR = + DistributionViewDescriptor.create( + VIEW_NAME, + "view description", + MEASUREMENT_DESCRIPTOR, + DistributionAggregationDescriptor.create(), + Arrays.asList(TagKey.create("my key"))); @Test - public void testRegisterAndGetView() { + public void testRegisterAndGetDistributionView() { + MeasurementDescriptorToViewMap measurementDescriptorToViewMap = + new MeasurementDescriptorToViewMap(); TestClock clock = TestClock.create(Timestamp.create(10, 20)); - measurementDescriptorToViewMap.registerView( - RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW, clock); + measurementDescriptorToViewMap.registerView(VIEW_DESCRIPTOR, clock); clock.setTime(Timestamp.create(30, 40)); - View actual = - measurementDescriptorToViewMap.getView( - RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW.getViewDescriptorName(), clock); + View actual = measurementDescriptorToViewMap.getView(VIEW_NAME, clock); actual.match( new Function() { @Override public Void apply(DistributionView view) { - assertThat(view.getViewDescriptor()).isEqualTo(RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + assertThat(view.getViewDescriptor()).isEqualTo(VIEW_DESCRIPTOR); assertThat(view.getStart()).isEqualTo(Timestamp.create(10, 20)); assertThat(view.getEnd()).isEqualTo(Timestamp.create(30, 40)); assertThat(view.getDistributionAggregations()).isEmpty(); diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index f935124ff9..3e39e35cbf 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -14,243 +14,457 @@ package com.google.instrumentation.stats; import static com.google.common.truth.Truth.assertThat; +import static com.google.instrumentation.stats.StatsTestUtil.assertDistributionAggregationsEquivalent; +import static com.google.instrumentation.stats.StatsTestUtil.createContext; -import com.google.common.collect.ImmutableMap; +import com.google.instrumentation.common.Duration; import com.google.instrumentation.common.SimpleEventQueue; import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.internal.TestClock; +import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; +import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; import com.google.instrumentation.stats.View.DistributionView; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; -import java.util.ArrayList; +import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; import java.util.List; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link StatsManagerImplBase}. - */ +/** Tests for {@link StatsManagerImplBase}. */ @RunWith(JUnit4.class) public class StatsManagerImplTest { - @Rule - public final ExpectedException thrown = ExpectedException.none(); + @Rule public final ExpectedException thrown = ExpectedException.none(); + + private static final double TOLERANCE = 1e-6; + + private static final TagKey KEY = TagKey.create("KEY"); + + private static final TagValue VALUE = TagValue.create("VALUE"); + private static final TagValue VALUE2 = TagValue.create("VALUE2"); + + private static final MeasurementDescriptor.Name MEASUREMENT_NAME = + MeasurementDescriptor.Name.create("my measurement"); + + private static final MeasurementDescriptor.Name MEASUREMENT_NAME2 = + MeasurementDescriptor.Name.create("my measurement 2"); + + private static final MeasurementUnit MEASUREMENT_UNIT = + MeasurementUnit.create(-6, Arrays.asList(BasicUnit.SECONDS)); + + private static final String MEASUREMENT_DESCRIPTION = "measurement description"; + + private static final MeasurementDescriptor MEASUREMENT_DESCRIPTOR = + MeasurementDescriptor.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); + + private static final ViewDescriptor.Name VIEW_NAME = ViewDescriptor.Name.create("my view"); + private static final ViewDescriptor.Name VIEW_NAME2 = ViewDescriptor.Name.create("my view 2"); + + private static final String VIEW_DESCRIPTION = "view description"; + + private static final BucketBoundaries BUCKET_BOUNDARIES = + BucketBoundaries.create( + Arrays.asList( + 0.0, 0.2, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0)); + + private static final DistributionAggregationDescriptor DISTRIBUTION_AGGREGATION_DESCRIPTOR = + DistributionAggregationDescriptor.create(BUCKET_BOUNDARIES.getBoundaries()); - private static final double TOLERANCE = 1e-5; - private static final TagKey tagKey = RpcMeasurementConstants.RPC_CLIENT_METHOD; - private static final TagKey wrongTagKey = TagKey.create("Wrong Tag Key"); - private static final TagKey wrongTagKey2 = TagKey.create("Another wrong Tag Key"); - private static final TagValue tagValue1 = TagValue.create("some client method"); - private static final TagValue tagValue2 = TagValue.create("some other client method"); private final TestClock clock = TestClock.create(); + private final StatsManagerImplBase statsManager = new StatsManagerImplBase(new SimpleEventQueue(), clock); - private final StatsContextImpl oneTag = - new StatsContextImpl(statsManager, ImmutableMap.of(tagKey, tagValue1)); - private final StatsContextImpl anotherTag = - new StatsContextImpl(statsManager, ImmutableMap.of(tagKey, tagValue2)); - private final StatsContextImpl wrongTag = - new StatsContextImpl(statsManager, ImmutableMap.of(wrongTagKey, tagValue1)); - private final StatsContextImpl wrongTag2 = - new StatsContextImpl( - statsManager, ImmutableMap.of(wrongTagKey, tagValue1, wrongTagKey2, tagValue2)); + + private final StatsContextFactoryImpl factory = new StatsContextFactoryImpl(statsManager); @Test - public void testRegisterAndGetView() throws Exception { - statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - View actual = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - assertThat(actual.getViewDescriptor()).isEqualTo( - RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + public void testRegisterAndGetView() { + DistributionViewDescriptor viewDescr = + DistributionViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY)); + statsManager.registerView(viewDescr); + assertThat(statsManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(viewDescr); } @Test - public void testRegisterUnsupportedViewDescriptor() throws Exception { + public void preventRegisteringIntervalView() { + ViewDescriptor intervalView = + IntervalViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MEASUREMENT_DESCRIPTOR, + IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(1000))), + Arrays.asList(KEY)); thrown.expect(UnsupportedOperationException.class); - statsManager.registerView(RpcViewConstants.RPC_CLIENT_REQUEST_COUNT_VIEW); + statsManager.registerView(intervalView); } @Test - public void testRegisterViewDescriptorTwice() { - statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - View actual = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - assertThat(actual.getViewDescriptor()).isEqualTo( - RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + public void allowRegisteringSameViewDescriptorTwice() { + DistributionViewDescriptor viewDescr = + DistributionViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY)); + statsManager.registerView(viewDescr); + statsManager.registerView(viewDescr); + assertThat(statsManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(viewDescr); } - // TODO(sebright) Enable this test once we support more than one view. - @Ignore @Test public void preventRegisteringDifferentViewDescriptorWithSameName() { - statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + ViewDescriptor view1 = + DistributionViewDescriptor.create( + VIEW_NAME, + "View description.", + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY)); + statsManager.registerView(view1); ViewDescriptor view2 = - DistributionViewDescriptor.create( - "grpc.io/client/roundtrip_latency/distribution_cumulative", - "This is a different description.", - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, - DistributionAggregationDescriptor.create(RpcViewConstants.RPC_MILLIS_BUCKET_BOUNDARIES), - Arrays.asList(RpcMeasurementConstants.RPC_CLIENT_METHOD)); - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("A different view with the same name is already registered"); - statsManager.registerView(view2); + DistributionViewDescriptor.create( + VIEW_NAME, + "This is a different description.", + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY)); + try { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("A different view with the same name is already registered"); + statsManager.registerView(view2); + } finally { + assertThat(statsManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(view1); + } } @Test - public void testGetNonexistentView() throws Exception { + public void disallowGettingNonexistentView() { thrown.expect(IllegalArgumentException.class); - statsManager.getView(RpcViewConstants.RPC_CLIENT_REQUEST_COUNT_VIEW); + statsManager.getView(VIEW_NAME); } @Test public void testRecord() { + DistributionViewDescriptor viewDescr = + DistributionViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 2)); - statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - for (double val : Arrays.asList(10.0, 20.0, 30.0, 40.0)) { + statsManager.registerView(viewDescr); + for (double val : Arrays.asList(10.0, 20.0, 30.0, 40.0)) { statsManager.record( - oneTag, MeasurementMap.of(RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, val)); + createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, val)); } - clock.setTime(Timestamp.create(3, 4)); - DistributionView view = - (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - assertThat(view.getViewDescriptor()) - .isEqualTo(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + assertThat(view.getViewDescriptor()).isEqualTo(viewDescr); assertThat(view.getStart()).isEqualTo(Timestamp.create(1, 2)); assertThat(view.getEnd()).isEqualTo(Timestamp.create(3, 4)); - List distributionAggregations = view.getDistributionAggregations(); - assertThat(distributionAggregations).hasSize(1); - DistributionAggregation distributionAggregation = distributionAggregations.get(0); - verifyDistributionAggregation(distributionAggregation, 4, 100.0, 25.0, 10.0, 40.0, 1); - // Refer to RpcViewConstants.RPC_MILLIS_BUCKET_BOUNDARIES for bucket boundaries. - verifyBucketCounts(distributionAggregation.getBucketCounts(), 9, 12, 14, 15); - - List tags = distributionAggregation.getTags(); - assertThat(tags.get(0).getKey()).isEqualTo(tagKey); - assertThat(tags.get(0).getValue()).isEqualTo(tagValue1); + assertDistributionAggregationsEquivalent( + TOLERANCE, + view.getDistributionAggregations(), + Arrays.asList( + StatsTestUtil.createDistributionAggregation( + Arrays.asList(Tag.create(KEY, VALUE)), + BUCKET_BOUNDARIES, + Arrays.asList(10.0, 20.0, 30.0, 40.0)))); + } + + @Test + public void getViewDoesNotClearStats() { + DistributionViewDescriptor viewDescr = + DistributionViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY)); + clock.setTime(Timestamp.create(10, 0)); + statsManager.registerView(viewDescr); + statsManager.record( + createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.1)); + clock.setTime(Timestamp.create(11, 0)); + DistributionView view1 = (DistributionView) statsManager.getView(VIEW_NAME); + assertThat(view1.getStart()).isEqualTo(Timestamp.create(10, 0)); + assertThat(view1.getEnd()).isEqualTo(Timestamp.create(11, 0)); + assertDistributionAggregationsEquivalent( + TOLERANCE, + view1.getDistributionAggregations(), + Arrays.asList( + StatsTestUtil.createDistributionAggregation( + Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(0.1)))); + statsManager.record( + createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.2)); + clock.setTime(Timestamp.create(12, 0)); + DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME); + + // The second view should have the same start time as the first view, and it should include both + // recorded values: + assertThat(view2.getStart()).isEqualTo(Timestamp.create(10, 0)); + assertThat(view2.getEnd()).isEqualTo(Timestamp.create(12, 0)); + assertDistributionAggregationsEquivalent( + TOLERANCE, + view2.getDistributionAggregations(), + Arrays.asList( + StatsTestUtil.createDistributionAggregation( + Arrays.asList(Tag.create(KEY, VALUE)), + BUCKET_BOUNDARIES, + Arrays.asList(0.1, 0.2)))); } @Test public void testRecordMultipleTagValues() { - statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - statsManager.record(oneTag, MeasurementMap.of( - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10.0)); - statsManager.record(anotherTag, MeasurementMap.of( - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 30.0)); - statsManager.record(anotherTag, MeasurementMap.of( - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 50.0)); - - DistributionView view = - (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - List distributionAggregations = - new ArrayList(view.getDistributionAggregations()); - assertThat(distributionAggregations).hasSize(2); - // Sort distributionAggregations by count. - Collections.sort(distributionAggregations, new Comparator() { - @Override - public int compare(DistributionAggregation o1, DistributionAggregation o2) { - return Long.valueOf(o1.getCount()).compareTo(o2.getCount()); - } - }); - - DistributionAggregation distributionAggregation1 = distributionAggregations.get(0); - DistributionAggregation distributionAggregation2 = distributionAggregations.get(1); - - verifyDistributionAggregation(distributionAggregation1, 1, 10.0, 10.0, 10.0, 10.0, 1); - verifyDistributionAggregation(distributionAggregation2, 2, 80.0, 40.0, 30.0, 50.0, 1); - verifyBucketCounts(distributionAggregation1.getBucketCounts(), 9); - verifyBucketCounts(distributionAggregation2.getBucketCounts(), 14, 16); - assertThat(distributionAggregation1.getTags().get(0).getKey()).isEqualTo(tagKey); - assertThat(distributionAggregation1.getTags().get(0).getValue()).isEqualTo(tagValue1); - assertThat(distributionAggregation2.getTags().get(0).getKey()).isEqualTo(tagKey); - assertThat(distributionAggregation2.getTags().get(0).getValue()).isEqualTo(tagValue2); + statsManager.registerView( + DistributionViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY))); + statsManager.record( + createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); + statsManager.record( + createContext(factory, KEY, VALUE2), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 30.0)); + statsManager.record( + createContext(factory, KEY, VALUE2), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 50.0)); + DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + assertDistributionAggregationsEquivalent( + TOLERANCE, + view.getDistributionAggregations(), + Arrays.asList( + StatsTestUtil.createDistributionAggregation( + Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(10.0)), + StatsTestUtil.createDistributionAggregation( + Arrays.asList(Tag.create(KEY, VALUE2)), + BUCKET_BOUNDARIES, + Arrays.asList(30.0, 50.0)))); } - private static void verifyDistributionAggregation( - DistributionAggregation distributionAggregation, - int count, double sum, double mean, double min, double max, int tagsSize) { - assertThat(distributionAggregation.getCount()).isEqualTo(count); - assertThat(distributionAggregation.getSum()).isWithin(TOLERANCE).of(sum); - assertThat(distributionAggregation.getMean()).isWithin(TOLERANCE).of(mean); - assertThat(distributionAggregation.getRange().getMin()).isWithin(TOLERANCE).of(min); - assertThat(distributionAggregation.getRange().getMax()).isWithin(TOLERANCE).of(max); - assertThat(distributionAggregation.getTags().size()).isEqualTo(tagsSize); + @Test + public void allowRecordingWithoutRegisteringMatchingView() { + statsManager.record( + createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10)); } - private static final void verifyBucketCounts(List bucketCounts, int... nonZeroBuckets) { - // nonZeroBuckets must be ordered. - Arrays.sort(nonZeroBuckets); - int j = 0; - for (int i = 0; i < bucketCounts.size(); ++i) { - if (j < nonZeroBuckets.length && i == nonZeroBuckets[j]) { - assertThat(bucketCounts.get(i)).isNotEqualTo(0); - ++j; - } else { - assertThat(bucketCounts.get(i)).isEqualTo(0); - } - } + @Test + public void testRecordWithEmptyStatsContext() { + statsManager.registerView( + DistributionViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY))); + // DEFAULT doesn't have tags, but the view has tag key "KEY". + statsManager.record( + statsManager.getStatsContextFactory().getDefault(), + MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); + DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + assertDistributionAggregationsEquivalent( + TOLERANCE, + view.getDistributionAggregations(), + Arrays.asList( + StatsTestUtil.createDistributionAggregation( + // Tag is missing for associated measurementValues, should use default tag value + // "unknown/not set" + Arrays.asList(Tag.create(KEY, MutableView.UNKNOWN_TAG_VALUE)), + BUCKET_BOUNDARIES, + // Should record stats with default tag value: "KEY" : "unknown/not set". + Arrays.asList(10.0)))); } @Test - public void testRecordWithoutRegisteringView() { - thrown.expect(IllegalArgumentException.class); - statsManager.record(oneTag, MeasurementMap.of( - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10)); + public void testRecordWithNonExistentMeasurementDescriptor() { + statsManager.registerView( + DistributionViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MeasurementDescriptor.create(MEASUREMENT_NAME, "measurement", MEASUREMENT_UNIT), + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY))); + MeasurementDescriptor measure2 = + MeasurementDescriptor.create(MEASUREMENT_NAME2, "measurement", MEASUREMENT_UNIT); + statsManager.record(createContext(factory, KEY, VALUE), MeasurementMap.of(measure2, 10.0)); + DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + assertThat(view.getDistributionAggregations()).isEmpty(); } @Test - public void testRecordWithEmptyStatsContext() { - statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - // DEFAULT doesn't have tags. Should have TagKey "method" as defined in RpcViewConstants. - statsManager.record(statsManager.getStatsContextFactory().getDefault(), MeasurementMap.of( - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10.0)); - DistributionView view = - (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - assertThat(view.getDistributionAggregations()).hasSize(1); - DistributionAggregation distributionAggregation = view.getDistributionAggregations().get(0); - List tags = distributionAggregation.getTags(); - assertThat(tags.get(0).getKey()).isEqualTo(tagKey); - // Tag is missing for associated measurementValues, should use default tag value - // "unknown/not set". - assertThat(tags.get(0).getValue()).isEqualTo(MutableView.UNKNOWN_TAG_VALUE); - // Should record stats with default Tag: "method" : "unknown/not set". - verifyDistributionAggregation(distributionAggregation, 1, 10.0, 10.0, 10.0, 10.0, 1); + public void testRecordWithTagsThatDoNotMatchView() { + statsManager.registerView( + DistributionViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY))); + statsManager.record( + createContext(factory, TagKey.create("wrong key"), VALUE), + MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); + statsManager.record( + createContext(factory, TagKey.create("another wrong key"), VALUE), + MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 50.0)); + DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + assertDistributionAggregationsEquivalent( + TOLERANCE, + view.getDistributionAggregations(), + Arrays.asList( + StatsTestUtil.createDistributionAggregation( + // Won't record the unregistered tag key, will use default tag instead: + // "KEY" : "unknown/not set". + Arrays.asList(Tag.create(KEY, MutableView.UNKNOWN_TAG_VALUE)), + BUCKET_BOUNDARIES, + // Should record stats with default tag value: "KEY" : "unknown/not set". + Arrays.asList(10.0, 50.0)))); } @Test - public void testRecordNonExistentMeasurementDescriptor() { - statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - statsManager.record(oneTag, MeasurementMap.of( - RpcMeasurementConstants.RPC_SERVER_ERROR_COUNT, 10.0)); - DistributionView view = - (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - assertThat(view.getDistributionAggregations()).hasSize(0); + public void testViewWithMultipleTagKeys() { + TagKey key1 = TagKey.create("Key-1"); + TagKey key2 = TagKey.create("Key-2"); + statsManager.registerView( + DistributionViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(key1, key2))); + statsManager.record( + createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), + MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 1.1)); + statsManager.record( + createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v20")), + MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 2.2)); + statsManager.record( + createContext(factory, key1, TagValue.create("v2"), key2, TagValue.create("v10")), + MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 3.3)); + statsManager.record( + createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), + MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 4.4)); + DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + assertDistributionAggregationsEquivalent( + TOLERANCE, + view.getDistributionAggregations(), + Arrays.asList( + StatsTestUtil.createDistributionAggregation( + Arrays.asList( + Tag.create(key1, TagValue.create("v1")), + Tag.create(key2, TagValue.create("v10"))), + BUCKET_BOUNDARIES, + Arrays.asList(1.1, 4.4)), + StatsTestUtil.createDistributionAggregation( + Arrays.asList( + Tag.create(key1, TagValue.create("v1")), + Tag.create(key2, TagValue.create("v20"))), + BUCKET_BOUNDARIES, + Arrays.asList(2.2)), + StatsTestUtil.createDistributionAggregation( + Arrays.asList( + Tag.create(key1, TagValue.create("v2")), + Tag.create(key2, TagValue.create("v10"))), + BUCKET_BOUNDARIES, + Arrays.asList(3.3)))); } + @Test + public void testMultipleViewsSameMeasure() { + ViewDescriptor viewDescr1 = + DistributionViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY)); + ViewDescriptor viewDescr2 = + DistributionViewDescriptor.create( + VIEW_NAME2, + VIEW_DESCRIPTION, + MEASUREMENT_DESCRIPTOR, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY)); + clock.setTime(Timestamp.create(1, 1)); + statsManager.registerView(viewDescr1); + clock.setTime(Timestamp.create(2, 2)); + statsManager.registerView(viewDescr2); + statsManager.record( + createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 5.0)); + List expectedAggs = + Arrays.asList( + StatsTestUtil.createDistributionAggregation( + Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(5.0))); + clock.setTime(Timestamp.create(3, 3)); + DistributionView view1 = (DistributionView) statsManager.getView(VIEW_NAME); + clock.setTime(Timestamp.create(4, 4)); + DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME2); + assertThat(view1.getStart()).isEqualTo(Timestamp.create(1, 1)); + assertThat(view1.getEnd()).isEqualTo(Timestamp.create(3, 3)); + assertDistributionAggregationsEquivalent( + TOLERANCE, view1.getDistributionAggregations(), expectedAggs); + assertThat(view2.getStart()).isEqualTo(Timestamp.create(2, 2)); + assertThat(view2.getEnd()).isEqualTo(Timestamp.create(4, 4)); + assertDistributionAggregationsEquivalent( + TOLERANCE, view2.getDistributionAggregations(), expectedAggs); + } @Test - public void testRecordTagDoesNotMatchView() { - statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - statsManager.record(wrongTag, MeasurementMap.of( - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 10.0)); - statsManager.record(wrongTag2, MeasurementMap.of( - RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 50.0)); - DistributionView view = - (DistributionView) statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - - assertThat(view.getDistributionAggregations()).hasSize(1); - DistributionAggregation distributionAggregation = view.getDistributionAggregations().get(0); - List tags = distributionAggregation.getTags(); - // Won't record the unregistered tag key, will use default tag instead: - // "method" : "unknown/not set". - assertThat(tags.get(0).getKey()).isEqualTo(tagKey); - assertThat(tags.get(0).getValue()).isEqualTo(MutableView.UNKNOWN_TAG_VALUE); - // Should record stats with default Tag: "method" : "unknown/not set" - verifyDistributionAggregation(distributionAggregation, 2, 60.0, 30.0, 10.0, 50.0, 1); + public void testMultipleViewsDifferentMeasures() { + MeasurementDescriptor measureDescr1 = + MeasurementDescriptor.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); + MeasurementDescriptor measureDescr2 = + MeasurementDescriptor.create(MEASUREMENT_NAME2, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); + ViewDescriptor viewDescr1 = + DistributionViewDescriptor.create( + VIEW_NAME, + VIEW_DESCRIPTION, + measureDescr1, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY)); + ViewDescriptor viewDescr2 = + DistributionViewDescriptor.create( + VIEW_NAME2, + VIEW_DESCRIPTION, + measureDescr2, + DISTRIBUTION_AGGREGATION_DESCRIPTOR, + Arrays.asList(KEY)); + clock.setTime(Timestamp.create(1, 0)); + statsManager.registerView(viewDescr1); + clock.setTime(Timestamp.create(2, 0)); + statsManager.registerView(viewDescr2); + statsManager.record( + createContext(factory, KEY, VALUE), + MeasurementMap.of(measureDescr1, 1.1, measureDescr2, 2.2)); + clock.setTime(Timestamp.create(3, 0)); + DistributionView view1 = (DistributionView) statsManager.getView(VIEW_NAME); + clock.setTime(Timestamp.create(4, 0)); + DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME2); + assertThat(view1.getStart()).isEqualTo(Timestamp.create(1, 0)); + assertThat(view1.getEnd()).isEqualTo(Timestamp.create(3, 0)); + assertDistributionAggregationsEquivalent( + TOLERANCE, + view1.getDistributionAggregations(), + Arrays.asList( + StatsTestUtil.createDistributionAggregation( + Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(1.1)))); + assertThat(view2.getStart()).isEqualTo(Timestamp.create(2, 0)); + assertThat(view2.getEnd()).isEqualTo(Timestamp.create(4, 0)); + assertDistributionAggregationsEquivalent( + TOLERANCE, + view2.getDistributionAggregations(), + Arrays.asList( + StatsTestUtil.createDistributionAggregation( + Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(2.2)))); } } From f94b27558dfcfcd2a5f79b78bcdd67dd2aca3491 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Sat, 13 May 2017 15:07:49 -0700 Subject: [PATCH 0080/1581] Fix the examples application. (#300) --- core_impl/build.gradle | 1 - examples/build.gradle | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/core_impl/build.gradle b/core_impl/build.gradle index 5040d69c35..afb0513589 100644 --- a/core_impl/build.gradle +++ b/core_impl/build.gradle @@ -3,7 +3,6 @@ description = 'Instrumentation Core Impl' dependencies { compile project(':core'), project(':shared'), - libraries.auto_value, libraries.guava compileOnly libraries.auto_value diff --git a/examples/build.gradle b/examples/build.gradle index 30b305e9f8..47563924a9 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -18,28 +18,28 @@ apply plugin: 'application' startScripts.enabled = false task statsRunner(type: CreateStartScripts) { - mainClassName = 'com.google.instrumentation.trace.examples.StatsRunner' + mainClassName = 'com.google.instrumentation.examples.stats.StatsRunner' applicationName = 'StatsRunner' outputDir = new File(project.buildDir, 'tmp') classpath = jar.outputs.files + project.configurations.runtime } task multiSpansTracing(type: CreateStartScripts) { - mainClassName = 'com.google.instrumentation.trace.examples.MultiSpansTracing' + mainClassName = 'com.google.instrumentation.examples.trace.MultiSpansTracing' applicationName = 'MultiSpansTracing' outputDir = new File(project.buildDir, 'tmp') classpath = jar.outputs.files + project.configurations.runtime } task multiSpansScopedTracing(type: CreateStartScripts) { - mainClassName = 'com.google.instrumentation.trace.examples.MultiSpansScopedTracing' + mainClassName = 'com.google.instrumentation.examples.trace.MultiSpansScopedTracing' applicationName = 'MultiSpansScopedTracing' outputDir = new File(project.buildDir, 'tmp') classpath = jar.outputs.files + project.configurations.runtime } task multiSpansContextTracing(type: CreateStartScripts) { - mainClassName = 'com.google.instrumentation.trace.examples.MultiSpansContextTracing' + mainClassName = 'com.google.instrumentation.examples.trace.MultiSpansContextTracing' applicationName = 'MultiSpansContextTracing' outputDir = new File(project.buildDir, 'tmp') classpath = jar.outputs.files + project.configurations.runtime From 6099b21e4d584739af8961d262c61c05aa7a50bb Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Sat, 13 May 2017 15:08:49 -0700 Subject: [PATCH 0081/1581] Change the interface of Logging service to enforce that maximum one instance is registered at any moment. Change examples to use the logging service exporter. (#301) --- .../instrumentation/trace/TraceExporter.java | 22 +++++++-- .../trace/TraceExporterTest.java | 49 +++++++++++++++++++ .../trace/MultiSpansContextTracing.java | 2 + .../trace/MultiSpansScopedTracing.java | 2 + .../examples/trace/MultiSpansTracing.java | 2 + 5 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 core/src/test/java/com/google/instrumentation/trace/TraceExporterTest.java diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java index 7318b85459..967959e0f0 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java @@ -88,20 +88,32 @@ public abstract static class ServiceHandler { * // ... * } * } - * */ @ThreadSafe public static final class LoggingServiceHandler extends ServiceHandler { private static final Logger logger = Logger.getLogger(LoggingServiceHandler.class.getName()); + private static final String SERVICE_NAME = + "com.google.instrumentation.trace.LoggingServiceHandler"; private static final LoggingServiceHandler INSTANCE = new LoggingServiceHandler(); /** - * Returns the instance of the {@code LoggingServiceHandler}. + * Registers the {@code LoggingServiceHandler} to the {@code TraceExporter}. + * + * @param traceExporter the instance of the {@code TraceExporter} where this service is + * registered. + */ + public static void registerService(TraceExporter traceExporter) { + traceExporter.registerServiceHandler(SERVICE_NAME, INSTANCE); + } + + /** + * Unregisters the {@code LoggingServiceHandler} from the {@code TraceExporter}. * - * @return the instance of the {@code LoggingServiceHandler}. + * @param traceExporter the instance of the {@code TraceExporter} from where this service is + * unregistered. */ - public static LoggingServiceHandler getInstance() { - return INSTANCE; + public static void unregisterService(TraceExporter traceExporter) { + traceExporter.unregisterServiceHandler(SERVICE_NAME); } @Override diff --git a/core/src/test/java/com/google/instrumentation/trace/TraceExporterTest.java b/core/src/test/java/com/google/instrumentation/trace/TraceExporterTest.java new file mode 100644 index 0000000000..03adacf75f --- /dev/null +++ b/core/src/test/java/com/google/instrumentation/trace/TraceExporterTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; + +import com.google.instrumentation.trace.TraceExporter.LoggingServiceHandler; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link TraceExporter}. */ +@RunWith(JUnit4.class) +public class TraceExporterTest { + @Mock private TraceExporter traceExporter; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void registerUnregisterLoggingService() { + LoggingServiceHandler.registerService(traceExporter); + verify(traceExporter) + .registerServiceHandler( + eq("com.google.instrumentation.trace.LoggingServiceHandler"), + any(LoggingServiceHandler.class)); + LoggingServiceHandler.unregisterService(traceExporter); + verify(traceExporter) + .unregisterServiceHandler(eq("com.google.instrumentation.trace.LoggingServiceHandler")); + } +} diff --git a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansContextTracing.java b/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansContextTracing.java index d00c1869c1..c83b11d96e 100644 --- a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansContextTracing.java +++ b/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansContextTracing.java @@ -15,6 +15,7 @@ import com.google.instrumentation.common.NonThrowingCloseable; import com.google.instrumentation.trace.Span; +import com.google.instrumentation.trace.TraceExporter; import com.google.instrumentation.trace.Tracer; import com.google.instrumentation.trace.Tracing; @@ -47,6 +48,7 @@ private static void doWork() { /** Main method. */ public static void main(String[] args) { + TraceExporter.LoggingServiceHandler.registerService(Tracing.getTraceExporter()); Span span = tracer.spanBuilder("MyRootSpan").becomeRoot().startSpan(); try (NonThrowingCloseable ws = tracer.withSpan(span)) { doWork(); diff --git a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansScopedTracing.java b/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansScopedTracing.java index 25279f2113..be7672d7a5 100644 --- a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansScopedTracing.java +++ b/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansScopedTracing.java @@ -15,6 +15,7 @@ import com.google.instrumentation.common.NonThrowingCloseable; import com.google.instrumentation.trace.Span; +import com.google.instrumentation.trace.TraceExporter; import com.google.instrumentation.trace.Tracer; import com.google.instrumentation.trace.Tracing; @@ -45,6 +46,7 @@ private static void doWork() { /** Main method. */ public static void main(String[] args) { + TraceExporter.LoggingServiceHandler.registerService(Tracing.getTraceExporter()); try (NonThrowingCloseable ss = tracer.spanBuilder("MyRootSpan").becomeRoot().startScopedSpan()) { doWork(); diff --git a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansTracing.java b/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansTracing.java index b3c3dbcd57..5268a7974a 100644 --- a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansTracing.java +++ b/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansTracing.java @@ -14,6 +14,7 @@ package com.google.instrumentation.examples.trace; import com.google.instrumentation.trace.Span; +import com.google.instrumentation.trace.TraceExporter; import com.google.instrumentation.trace.Tracer; import com.google.instrumentation.trace.Tracing; @@ -34,6 +35,7 @@ private static void doWork() { /** Main method. */ public static void main(String[] args) { + TraceExporter.LoggingServiceHandler.registerService(Tracing.getTraceExporter()); doWork(); } } From 3000ae25d066daa478d6cb068acc4d51da284b83 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Sun, 14 May 2017 16:03:41 -0700 Subject: [PATCH 0082/1581] Limit visibility of some classes. --- .../google/instrumentation/stats/StatsContextImpl.java | 2 +- .../com/google/instrumentation/stats/StatsTestUtil.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java index 37f8dd052e..6b93e89d89 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java @@ -68,7 +68,7 @@ public String toString() { return tags.toString(); } - public static final class Builder extends StatsContext.Builder { + static final class Builder extends StatsContext.Builder { private final StatsManagerImplBase statsManager; private final HashMap tags; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java index ab254a65b0..090a136bb8 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java @@ -24,7 +24,7 @@ import java.util.List; /** Stats test utilities. */ -public final class StatsTestUtil { +final class StatsTestUtil { private StatsTestUtil() {} @@ -37,7 +37,7 @@ private StatsTestUtil() {} * have an even length. * @return a {@code StatsContextImpl} with the given keys and values. */ - public static StatsContextImpl createContext( + static StatsContextImpl createContext( StatsContextFactoryImpl factory, Object... tagKeysAndValues) { StatsContextImpl.Builder builder = factory.getDefault().builder(); for (Iterator i = Arrays.asList(tagKeysAndValues).iterator(); i.hasNext(); ) { @@ -57,7 +57,7 @@ public static StatsContextImpl createContext( * @param values the values to add to the distribution. * @return the new {@code DistributionAggregation} */ - public static DistributionAggregation createDistributionAggregation( + static DistributionAggregation createDistributionAggregation( List tags, BucketBoundaries bucketBoundaries, List values) { MutableDistribution mdist = MutableDistribution.create(bucketBoundaries); for (double value : values) { @@ -84,7 +84,7 @@ public static DistributionAggregation createDistributionAggregation( * @param expected the expected value. * @throws AssertionError if the {@code DistributionAggregation}s don't match. */ - public static void assertDistributionAggregationsEquivalent( + static void assertDistributionAggregationsEquivalent( double tolerance, Collection actual, Collection expected) { From d39e0d43ca2281ff0ea45c455736c958c1c0865e Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Sun, 14 May 2017 16:11:10 -0700 Subject: [PATCH 0083/1581] Refactor testing util to not use Object type. --- .../instrumentation/stats/StatsTestUtil.java | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java index 090a136bb8..a89e1c3de0 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java @@ -18,9 +18,7 @@ import com.google.common.collect.Iterables; import com.google.common.truth.Truth; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.Iterator; import java.util.List; /** Stats test utilities. */ @@ -28,22 +26,28 @@ final class StatsTestUtil { private StatsTestUtil() {} + static StatsContextImpl createContext( + StatsContextFactoryImpl factory, TagKey key, TagValue value) { + return createContext(factory, Tag.create(key, value)); + } + + static StatsContextImpl createContext( + StatsContextFactoryImpl factory, TagKey key1, TagValue value1, TagKey key2, TagValue value2) { + return createContext(factory, Tag.create(key1, value1), Tag.create(key2, value2)); + } + /** - * Creates a {@code StatsContextImpl} from a factory and a list of alternating tag keys and - * values. + * Creates a {@code StatsContextImpl} from a factory and a list tags. * * @param factory the factory used to produce the {@code StatsContextImpl}. - * @param tagKeysAndValues a list of alternating {@link TagKey}s and {@link TagValue}s. It must - * have an even length. - * @return a {@code StatsContextImpl} with the given keys and values. + * @param tags a list of tags to add to the {@code StatsContextImpl}. + * @return a {@code StatsContextImpl} with the given tags. */ - static StatsContextImpl createContext( - StatsContextFactoryImpl factory, Object... tagKeysAndValues) { + private static StatsContextImpl createContext( + StatsContextFactoryImpl factory, Tag... tags) { StatsContextImpl.Builder builder = factory.getDefault().builder(); - for (Iterator i = Arrays.asList(tagKeysAndValues).iterator(); i.hasNext(); ) { - TagKey key = (TagKey) i.next(); - TagValue value = (TagValue) i.next(); - builder.set(key, value); + for (Tag tag : tags) { + builder.set(tag.getKey(), tag.getValue()); } return builder.build(); } From ac7723063e35f8e1dd6c1000a48ff0b836bb77af Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Sun, 14 May 2017 16:47:02 -0700 Subject: [PATCH 0084/1581] Create variables for reused StatsContextImpls. --- .../instrumentation/stats/StatsManagerImplTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 3e39e35cbf..352ef0c27a 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -164,9 +164,9 @@ public void testRecord() { Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 2)); statsManager.registerView(viewDescr); + StatsContextImpl tags = createContext(factory, KEY, VALUE); for (double val : Arrays.asList(10.0, 20.0, 30.0, 40.0)) { - statsManager.record( - createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, val)); + statsManager.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, val)); } clock.setTime(Timestamp.create(3, 4)); DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); @@ -194,8 +194,9 @@ public void getViewDoesNotClearStats() { Arrays.asList(KEY)); clock.setTime(Timestamp.create(10, 0)); statsManager.registerView(viewDescr); + StatsContextImpl tags = createContext(factory, KEY, VALUE); statsManager.record( - createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.1)); + tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.1)); clock.setTime(Timestamp.create(11, 0)); DistributionView view1 = (DistributionView) statsManager.getView(VIEW_NAME); assertThat(view1.getStart()).isEqualTo(Timestamp.create(10, 0)); @@ -207,7 +208,7 @@ public void getViewDoesNotClearStats() { StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(0.1)))); statsManager.record( - createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.2)); + tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.2)); clock.setTime(Timestamp.create(12, 0)); DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME); From 7099d0119d56859ea61f54e1daa84d6532cc9e96 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Sun, 14 May 2017 17:02:34 -0700 Subject: [PATCH 0085/1581] Add a comment to explain a test. --- .../com/google/instrumentation/stats/StatsManagerImplTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 352ef0c27a..fc69b27cc0 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -254,6 +254,8 @@ public void testRecordMultipleTagValues() { Arrays.asList(30.0, 50.0)))); } + // This test checks that StatsManager.record(...) does not throw an exception when no views are + // registered. @Test public void allowRecordingWithoutRegisteringMatchingView() { statsManager.record( From a107a286d18559109bdd3e4b9f2f66d87702a76b Mon Sep 17 00:00:00 2001 From: Yang Song Date: Mon, 15 May 2017 11:22:03 -0700 Subject: [PATCH 0086/1581] Implement minimal functionality for StatsContext to interact with gRPC Context. (#299) * Implement the minimal functionality for StatsContext to interact with gRPC Context. * Mark StatsContext as Immutable. --- .../instrumentation/stats/ContextUtils.java | 83 +++++++++++++++++++ .../instrumentation/stats/StatsContext.java | 2 + .../stats/ContextUtilsTest.java | 78 +++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 core/src/main/java/com/google/instrumentation/stats/ContextUtils.java create mode 100644 core/src/test/java/com/google/instrumentation/stats/ContextUtilsTest.java diff --git a/core/src/main/java/com/google/instrumentation/stats/ContextUtils.java b/core/src/main/java/com/google/instrumentation/stats/ContextUtils.java new file mode 100644 index 0000000000..b0f7e6c549 --- /dev/null +++ b/core/src/main/java/com/google/instrumentation/stats/ContextUtils.java @@ -0,0 +1,83 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import com.google.instrumentation.common.NonThrowingCloseable; +import io.grpc.Context; + +/** + * Util methods/functionality to interact with the {@link io.grpc.Context}. + * + *

Users must interact with the current Context via the public APIs in {@link + * StatsContextFactory} and avoid usages of the {@link #STATS_CONTEXT_KEY} directly. + */ +public final class ContextUtils { + + /** + * The {@link io.grpc.Context.Key} used to interact with {@link io.grpc.Context}. + */ + // TODO(songya): Discourage the usage of STATS_CONTEXT_KEY for normal users if needed. + public static final Context.Key STATS_CONTEXT_KEY = Context.key( + "instrumentation-stats-key"); + + // Static class. + private ContextUtils() { + } + + /** + * Returns The {@link StatsContext} from the current context. + * + * @return The {@code StatsContext} from the current context. + */ + static StatsContext getCurrentStatsContext() { + return STATS_CONTEXT_KEY.get(Context.current()); + } + + /** + * Enters the scope of code where the given {@link StatsContext} is in the current context, and + * returns an object that represents that scope. The scope is exited when the returned object + * is closed. + * + *

Supports try-with-resource idiom. + * + * @param statsContext The {@code StatsContext} to be set to the current context. + * @return An object that defines a scope where the given {@code StatsContext} is set to the + * current context. + */ + static NonThrowingCloseable withStatsContext(StatsContext statsContext) { + return new WithStatsContext(statsContext, STATS_CONTEXT_KEY); + } + + // Supports try-with-resources idiom. + private static final class WithStatsContext implements NonThrowingCloseable { + + private final Context origContext; + + /** + * Constructs a new {@link WithStatsContext}. + * + * @param statsContext is the {@code StatsContext} to be added to the current {@code Context}. + * @param contextKey is the {@code Context.Key} used to set/get {@code StatsContext} from the + * {@code Context}. + */ + private WithStatsContext(StatsContext statsContext, Context.Key contextKey) { + origContext = Context.current().withValue(contextKey, statsContext).attach(); + } + + @Override + public void close() { + Context.current().detach(origContext); + } + } +} diff --git a/core/src/main/java/com/google/instrumentation/stats/StatsContext.java b/core/src/main/java/com/google/instrumentation/stats/StatsContext.java index 0a9f96744c..8858299136 100644 --- a/core/src/main/java/com/google/instrumentation/stats/StatsContext.java +++ b/core/src/main/java/com/google/instrumentation/stats/StatsContext.java @@ -15,10 +15,12 @@ import java.io.IOException; import java.io.OutputStream; +import javax.annotation.concurrent.Immutable; /** * An immutable context for stats operations. */ +@Immutable public abstract class StatsContext { /** * Returns a builder based on this {@link StatsContext}. diff --git a/core/src/test/java/com/google/instrumentation/stats/ContextUtilsTest.java b/core/src/test/java/com/google/instrumentation/stats/ContextUtilsTest.java new file mode 100644 index 0000000000..a8a77be7b9 --- /dev/null +++ b/core/src/test/java/com/google/instrumentation/stats/ContextUtilsTest.java @@ -0,0 +1,78 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.stats; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.instrumentation.common.NonThrowingCloseable; +import io.grpc.Context; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Unit tests for {@link ContextUtils}. + */ +@RunWith(JUnit4.class) +public class ContextUtilsTest { + + @Mock + private StatsContext statsContext; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testGetCurrentStatsContext_WhenNoContext() { + assertThat(ContextUtils.getCurrentStatsContext()).isNull(); + } + + @Test + public void testWithStatsContext() { + assertThat(ContextUtils.getCurrentStatsContext()).isNull(); + NonThrowingCloseable scopedStatsCtx = ContextUtils.withStatsContext(statsContext); + try { + assertThat(ContextUtils.getCurrentStatsContext()).isSameAs(statsContext); + } finally { + scopedStatsCtx.close(); + } + assertThat(ContextUtils.getCurrentStatsContext()).isNull(); + } + + @Test + public void testWithStatsContextUsingWrap() { + Runnable runnable; + NonThrowingCloseable scopedStatsCtx = ContextUtils.withStatsContext(statsContext); + try { + assertThat(ContextUtils.getCurrentStatsContext()).isSameAs(statsContext); + runnable = Context.current().wrap( + new Runnable() { + @Override + public void run() { + assertThat(ContextUtils.getCurrentStatsContext()).isSameAs(statsContext); + } + }); + } finally { + scopedStatsCtx.close(); + } + assertThat(ContextUtils.getCurrentStatsContext()).isNull(); + // When we run the runnable we will have the statsContext in the current Context. + runnable.run(); + } +} From 9497ba0dcafdf4521b2767aad2006319e9de538f Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 15 May 2017 12:02:49 -0700 Subject: [PATCH 0087/1581] Add helper methods for creating ViewDescriptors in StatsManagerImplTest. --- .../stats/StatsManagerImplTest.java | 78 +++++++------------ 1 file changed, 30 insertions(+), 48 deletions(-) diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index fc69b27cc0..4e4986dcad 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -81,15 +81,22 @@ public class StatsManagerImplTest { private final StatsContextFactoryImpl factory = new StatsContextFactoryImpl(statsManager); + private static DistributionViewDescriptor createDistributionViewDescriptor() { + return createDistributionViewDescriptor( + VIEW_NAME, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); + } + + private static DistributionViewDescriptor createDistributionViewDescriptor( + ViewDescriptor.Name name, + MeasurementDescriptor measureDescr, + DistributionAggregationDescriptor aggDescr, + List keys) { + return DistributionViewDescriptor.create(name, VIEW_DESCRIPTION, measureDescr, aggDescr, keys); + } + @Test public void testRegisterAndGetView() { - DistributionViewDescriptor viewDescr = - DistributionViewDescriptor.create( - VIEW_NAME, - VIEW_DESCRIPTION, - MEASUREMENT_DESCRIPTOR, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY)); + DistributionViewDescriptor viewDescr = createDistributionViewDescriptor(); statsManager.registerView(viewDescr); assertThat(statsManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(viewDescr); } @@ -109,13 +116,7 @@ public void preventRegisteringIntervalView() { @Test public void allowRegisteringSameViewDescriptorTwice() { - DistributionViewDescriptor viewDescr = - DistributionViewDescriptor.create( - VIEW_NAME, - VIEW_DESCRIPTION, - MEASUREMENT_DESCRIPTOR, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY)); + DistributionViewDescriptor viewDescr = createDistributionViewDescriptor(); statsManager.registerView(viewDescr); statsManager.registerView(viewDescr); assertThat(statsManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(viewDescr); @@ -156,9 +157,8 @@ public void disallowGettingNonexistentView() { @Test public void testRecord() { DistributionViewDescriptor viewDescr = - DistributionViewDescriptor.create( + createDistributionViewDescriptor( VIEW_NAME, - VIEW_DESCRIPTION, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); @@ -186,17 +186,15 @@ public void testRecord() { @Test public void getViewDoesNotClearStats() { DistributionViewDescriptor viewDescr = - DistributionViewDescriptor.create( + createDistributionViewDescriptor( VIEW_NAME, - VIEW_DESCRIPTION, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(10, 0)); statsManager.registerView(viewDescr); StatsContextImpl tags = createContext(factory, KEY, VALUE); - statsManager.record( - tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.1)); + statsManager.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.1)); clock.setTime(Timestamp.create(11, 0)); DistributionView view1 = (DistributionView) statsManager.getView(VIEW_NAME); assertThat(view1.getStart()).isEqualTo(Timestamp.create(10, 0)); @@ -207,8 +205,7 @@ public void getViewDoesNotClearStats() { Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(0.1)))); - statsManager.record( - tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.2)); + statsManager.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.2)); clock.setTime(Timestamp.create(12, 0)); DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME); @@ -229,9 +226,8 @@ public void getViewDoesNotClearStats() { @Test public void testRecordMultipleTagValues() { statsManager.registerView( - DistributionViewDescriptor.create( + createDistributionViewDescriptor( VIEW_NAME, - VIEW_DESCRIPTION, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); @@ -265,9 +261,8 @@ public void allowRecordingWithoutRegisteringMatchingView() { @Test public void testRecordWithEmptyStatsContext() { statsManager.registerView( - DistributionViewDescriptor.create( + createDistributionViewDescriptor( VIEW_NAME, - VIEW_DESCRIPTION, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); @@ -292,9 +287,8 @@ public void testRecordWithEmptyStatsContext() { @Test public void testRecordWithNonExistentMeasurementDescriptor() { statsManager.registerView( - DistributionViewDescriptor.create( + createDistributionViewDescriptor( VIEW_NAME, - VIEW_DESCRIPTION, MeasurementDescriptor.create(MEASUREMENT_NAME, "measurement", MEASUREMENT_UNIT), DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); @@ -308,9 +302,8 @@ public void testRecordWithNonExistentMeasurementDescriptor() { @Test public void testRecordWithTagsThatDoNotMatchView() { statsManager.registerView( - DistributionViewDescriptor.create( + createDistributionViewDescriptor( VIEW_NAME, - VIEW_DESCRIPTION, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); @@ -339,9 +332,8 @@ public void testViewWithMultipleTagKeys() { TagKey key1 = TagKey.create("Key-1"); TagKey key2 = TagKey.create("Key-2"); statsManager.registerView( - DistributionViewDescriptor.create( + createDistributionViewDescriptor( VIEW_NAME, - VIEW_DESCRIPTION, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(key1, key2))); @@ -385,16 +377,14 @@ public void testViewWithMultipleTagKeys() { @Test public void testMultipleViewsSameMeasure() { ViewDescriptor viewDescr1 = - DistributionViewDescriptor.create( + createDistributionViewDescriptor( VIEW_NAME, - VIEW_DESCRIPTION, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); ViewDescriptor viewDescr2 = - DistributionViewDescriptor.create( + createDistributionViewDescriptor( VIEW_NAME2, - VIEW_DESCRIPTION, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); @@ -429,19 +419,11 @@ public void testMultipleViewsDifferentMeasures() { MeasurementDescriptor measureDescr2 = MeasurementDescriptor.create(MEASUREMENT_NAME2, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); ViewDescriptor viewDescr1 = - DistributionViewDescriptor.create( - VIEW_NAME, - VIEW_DESCRIPTION, - measureDescr1, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY)); + createDistributionViewDescriptor( + VIEW_NAME, measureDescr1, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); ViewDescriptor viewDescr2 = - DistributionViewDescriptor.create( - VIEW_NAME2, - VIEW_DESCRIPTION, - measureDescr2, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY)); + createDistributionViewDescriptor( + VIEW_NAME2, measureDescr2, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); statsManager.registerView(viewDescr1); clock.setTime(Timestamp.create(2, 0)); From abd833019d9c5b9a6047171b673055bc5b20c75c Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 15 May 2017 12:07:15 -0700 Subject: [PATCH 0088/1581] Rename fields to improve readability. --- .../stats/StatsManagerImplTest.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 4e4986dcad..093f0da0a7 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -45,12 +45,12 @@ public class StatsManagerImplTest { private static final TagKey KEY = TagKey.create("KEY"); private static final TagValue VALUE = TagValue.create("VALUE"); - private static final TagValue VALUE2 = TagValue.create("VALUE2"); + private static final TagValue VALUE_2 = TagValue.create("VALUE_2"); private static final MeasurementDescriptor.Name MEASUREMENT_NAME = MeasurementDescriptor.Name.create("my measurement"); - private static final MeasurementDescriptor.Name MEASUREMENT_NAME2 = + private static final MeasurementDescriptor.Name MEASUREMENT_NAME_2 = MeasurementDescriptor.Name.create("my measurement 2"); private static final MeasurementUnit MEASUREMENT_UNIT = @@ -62,7 +62,7 @@ public class StatsManagerImplTest { MeasurementDescriptor.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); private static final ViewDescriptor.Name VIEW_NAME = ViewDescriptor.Name.create("my view"); - private static final ViewDescriptor.Name VIEW_NAME2 = ViewDescriptor.Name.create("my view 2"); + private static final ViewDescriptor.Name VIEW_NAME_2 = ViewDescriptor.Name.create("my view 2"); private static final String VIEW_DESCRIPTION = "view description"; @@ -234,9 +234,9 @@ public void testRecordMultipleTagValues() { statsManager.record( createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); statsManager.record( - createContext(factory, KEY, VALUE2), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 30.0)); + createContext(factory, KEY, VALUE_2), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 30.0)); statsManager.record( - createContext(factory, KEY, VALUE2), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 50.0)); + createContext(factory, KEY, VALUE_2), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 50.0)); DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( TOLERANCE, @@ -245,7 +245,7 @@ public void testRecordMultipleTagValues() { StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(10.0)), StatsTestUtil.createDistributionAggregation( - Arrays.asList(Tag.create(KEY, VALUE2)), + Arrays.asList(Tag.create(KEY, VALUE_2)), BUCKET_BOUNDARIES, Arrays.asList(30.0, 50.0)))); } @@ -293,7 +293,7 @@ public void testRecordWithNonExistentMeasurementDescriptor() { DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); MeasurementDescriptor measure2 = - MeasurementDescriptor.create(MEASUREMENT_NAME2, "measurement", MEASUREMENT_UNIT); + MeasurementDescriptor.create(MEASUREMENT_NAME_2, "measurement", MEASUREMENT_UNIT); statsManager.record(createContext(factory, KEY, VALUE), MeasurementMap.of(measure2, 10.0)); DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); assertThat(view.getDistributionAggregations()).isEmpty(); @@ -384,7 +384,7 @@ public void testMultipleViewsSameMeasure() { Arrays.asList(KEY)); ViewDescriptor viewDescr2 = createDistributionViewDescriptor( - VIEW_NAME2, + VIEW_NAME_2, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); @@ -401,7 +401,7 @@ public void testMultipleViewsSameMeasure() { clock.setTime(Timestamp.create(3, 3)); DistributionView view1 = (DistributionView) statsManager.getView(VIEW_NAME); clock.setTime(Timestamp.create(4, 4)); - DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME2); + DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME_2); assertThat(view1.getStart()).isEqualTo(Timestamp.create(1, 1)); assertThat(view1.getEnd()).isEqualTo(Timestamp.create(3, 3)); assertDistributionAggregationsEquivalent( @@ -417,13 +417,13 @@ public void testMultipleViewsDifferentMeasures() { MeasurementDescriptor measureDescr1 = MeasurementDescriptor.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); MeasurementDescriptor measureDescr2 = - MeasurementDescriptor.create(MEASUREMENT_NAME2, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); + MeasurementDescriptor.create(MEASUREMENT_NAME_2, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); ViewDescriptor viewDescr1 = createDistributionViewDescriptor( VIEW_NAME, measureDescr1, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); ViewDescriptor viewDescr2 = createDistributionViewDescriptor( - VIEW_NAME2, measureDescr2, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); + VIEW_NAME_2, measureDescr2, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); statsManager.registerView(viewDescr1); clock.setTime(Timestamp.create(2, 0)); @@ -434,7 +434,7 @@ public void testMultipleViewsDifferentMeasures() { clock.setTime(Timestamp.create(3, 0)); DistributionView view1 = (DistributionView) statsManager.getView(VIEW_NAME); clock.setTime(Timestamp.create(4, 0)); - DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME2); + DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME_2); assertThat(view1.getStart()).isEqualTo(Timestamp.create(1, 0)); assertThat(view1.getEnd()).isEqualTo(Timestamp.create(3, 0)); assertDistributionAggregationsEquivalent( From d76f9c85622abb0ab7a83a3e79961ce2e67f7635 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 15 May 2017 12:27:20 -0700 Subject: [PATCH 0089/1581] Add helper method to compare DistributionAggregations with a default tolerance. --- .../stats/StatsManagerImplTest.java | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 093f0da0a7..9d03b0fe14 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -14,7 +14,6 @@ package com.google.instrumentation.stats; import static com.google.common.truth.Truth.assertThat; -import static com.google.instrumentation.stats.StatsTestUtil.assertDistributionAggregationsEquivalent; import static com.google.instrumentation.stats.StatsTestUtil.createContext; import com.google.instrumentation.common.Duration; @@ -27,6 +26,7 @@ import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Arrays; +import java.util.Collection; import java.util.List; import org.junit.Rule; import org.junit.Test; @@ -40,8 +40,6 @@ public class StatsManagerImplTest { @Rule public final ExpectedException thrown = ExpectedException.none(); - private static final double TOLERANCE = 1e-6; - private static final TagKey KEY = TagKey.create("KEY"); private static final TagValue VALUE = TagValue.create("VALUE"); @@ -174,7 +172,6 @@ public void testRecord() { assertThat(view.getStart()).isEqualTo(Timestamp.create(1, 2)); assertThat(view.getEnd()).isEqualTo(Timestamp.create(3, 4)); assertDistributionAggregationsEquivalent( - TOLERANCE, view.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( @@ -200,7 +197,6 @@ public void getViewDoesNotClearStats() { assertThat(view1.getStart()).isEqualTo(Timestamp.create(10, 0)); assertThat(view1.getEnd()).isEqualTo(Timestamp.create(11, 0)); assertDistributionAggregationsEquivalent( - TOLERANCE, view1.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( @@ -214,7 +210,6 @@ public void getViewDoesNotClearStats() { assertThat(view2.getStart()).isEqualTo(Timestamp.create(10, 0)); assertThat(view2.getEnd()).isEqualTo(Timestamp.create(12, 0)); assertDistributionAggregationsEquivalent( - TOLERANCE, view2.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( @@ -239,7 +234,6 @@ public void testRecordMultipleTagValues() { createContext(factory, KEY, VALUE_2), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 50.0)); DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( - TOLERANCE, view.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( @@ -272,7 +266,6 @@ public void testRecordWithEmptyStatsContext() { MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( - TOLERANCE, view.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( @@ -315,7 +308,6 @@ public void testRecordWithTagsThatDoNotMatchView() { MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 50.0)); DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( - TOLERANCE, view.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( @@ -351,7 +343,6 @@ public void testViewWithMultipleTagKeys() { MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 4.4)); DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( - TOLERANCE, view.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( @@ -404,12 +395,10 @@ public void testMultipleViewsSameMeasure() { DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME_2); assertThat(view1.getStart()).isEqualTo(Timestamp.create(1, 1)); assertThat(view1.getEnd()).isEqualTo(Timestamp.create(3, 3)); - assertDistributionAggregationsEquivalent( - TOLERANCE, view1.getDistributionAggregations(), expectedAggs); + assertDistributionAggregationsEquivalent(view1.getDistributionAggregations(), expectedAggs); assertThat(view2.getStart()).isEqualTo(Timestamp.create(2, 2)); assertThat(view2.getEnd()).isEqualTo(Timestamp.create(4, 4)); - assertDistributionAggregationsEquivalent( - TOLERANCE, view2.getDistributionAggregations(), expectedAggs); + assertDistributionAggregationsEquivalent(view2.getDistributionAggregations(), expectedAggs); } @Test @@ -438,7 +427,6 @@ public void testMultipleViewsDifferentMeasures() { assertThat(view1.getStart()).isEqualTo(Timestamp.create(1, 0)); assertThat(view1.getEnd()).isEqualTo(Timestamp.create(3, 0)); assertDistributionAggregationsEquivalent( - TOLERANCE, view1.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( @@ -446,10 +434,16 @@ public void testMultipleViewsDifferentMeasures() { assertThat(view2.getStart()).isEqualTo(Timestamp.create(2, 0)); assertThat(view2.getEnd()).isEqualTo(Timestamp.create(4, 0)); assertDistributionAggregationsEquivalent( - TOLERANCE, view2.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(2.2)))); } + + // TODO(sebright) Consider making this helper method work with larger ranges of double values and + // moving it to StatsTestUtil. + private static void assertDistributionAggregationsEquivalent( + Collection actual, Collection expected) { + StatsTestUtil.assertDistributionAggregationsEquivalent(1e-6, actual, expected); + } } From 8ec67cf9c391101bdf3c5e1de49794e2ccde9d68 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 15 May 2017 14:54:01 -0700 Subject: [PATCH 0090/1581] Add benchmarks for start/end span and record trace events. (#297) --- benchmarks/build.gradle | 9 ++ ...ordTraceEventsNonSampledSpanBenchmark.java | 83 ++++++++++++ ...RecordTraceEventsSampledSpanBenchmark.java | 83 ++++++++++++ .../trace/StartEndSpanBenchmark.java | 127 ++++++++++++++++++ 4 files changed, 302 insertions(+) create mode 100644 benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsNonSampledSpanBenchmark.java create mode 100644 benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsSampledSpanBenchmark.java create mode 100644 benchmarks/src/jmh/java/com/google/instrumentation/trace/StartEndSpanBenchmark.java diff --git a/benchmarks/build.gradle b/benchmarks/build.gradle index 8b58bbf541..3c20fd0cb1 100644 --- a/benchmarks/build.gradle +++ b/benchmarks/build.gradle @@ -32,5 +32,14 @@ compileJmhJava { options.compilerArgs = compileJava.options.compilerArgs } + +// Generate html report for findbugsJmh. +findbugsJmh { + reports { + xml.enabled = false + html.enabled = true + } +} + // Disable checkstyle if not java8. checkstyleJmh.enabled = JavaVersion.current().isJava8Compatible() \ No newline at end of file diff --git a/benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsNonSampledSpanBenchmark.java b/benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsNonSampledSpanBenchmark.java new file mode 100644 index 0000000000..ad9a66b5c0 --- /dev/null +++ b/benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsNonSampledSpanBenchmark.java @@ -0,0 +1,83 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import java.util.HashMap; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; + +/** Benchmarks for {@link SpanImpl} to record trace events. */ +@State(Scope.Benchmark) +public class RecordTraceEventsNonSampledSpanBenchmark { + private static final Tracer tracer = Tracing.getTracer(); + private static final String SPAN_NAME = "MySpanName"; + private static final String ANNOTATION_DESCRIPTION = "MyAnnotation"; + private static final String ATTRIBUTE_KEY = "MyAttributeKey"; + private static final String ATTRIBUTE_VALUE = "MyAttributeValue"; + private Span linkedSpan = + tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + private Span span = + tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + + /** TearDown method. */ + @TearDown + public void doTearDown() { + span.end(); + linkedSpan.end(); + } + + /** This benchmark attempts to measure performance of adding an attribute to the span. */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span addAttributes() { + HashMap attributes = new HashMap(); + attributes.put(ATTRIBUTE_KEY, AttributeValue.stringAttributeValue(ATTRIBUTE_VALUE)); + span.addAttributes(attributes); + return span; + } + + /** This benchmark attempts to measure performance of adding an annotation to the span. */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span addAnnotation() { + span.addAnnotation(ANNOTATION_DESCRIPTION); + return span; + } + + /** This benchmark attempts to measure performance of adding a network event to the span. */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span addNetworkEvent() { + span.addNetworkEvent(NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build()); + return span; + } + + /** This benchmark attempts to measure performance of adding a link to the span. */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span addLink() { + span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Link.Type.PARENT)); + return span; + } +} diff --git a/benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsSampledSpanBenchmark.java b/benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsSampledSpanBenchmark.java new file mode 100644 index 0000000000..e20af6ea90 --- /dev/null +++ b/benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsSampledSpanBenchmark.java @@ -0,0 +1,83 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import java.util.HashMap; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; + +/** Benchmarks for {@link SpanImpl} to record trace events. */ +@State(Scope.Benchmark) +public class RecordTraceEventsSampledSpanBenchmark { + private static final Tracer tracer = Tracing.getTracer(); + private static final String SPAN_NAME = "MySpanName"; + private static final String ANNOTATION_DESCRIPTION = "MyAnnotation"; + private static final String ATTRIBUTE_KEY = "MyAttributeKey"; + private static final String ATTRIBUTE_VALUE = "MyAttributeValue"; + private Span linkedSpan = + tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.alwaysSample()).startSpan(); + private Span span = + tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.alwaysSample()).startSpan(); + + /** TearDown method. */ + @TearDown + public void doTearDown() { + span.end(); + linkedSpan.end(); + } + + /** This benchmark attempts to measure performance of adding an attribute to the span. */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span addAttributes() { + HashMap attributes = new HashMap(); + attributes.put(ATTRIBUTE_KEY, AttributeValue.stringAttributeValue(ATTRIBUTE_VALUE)); + span.addAttributes(attributes); + return span; + } + + /** This benchmark attempts to measure performance of adding an annotation to the span. */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span addAnnotation() { + span.addAnnotation(ANNOTATION_DESCRIPTION); + return span; + } + + /** This benchmark attempts to measure performance of adding a network event to the span. */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span addNetworkEvent() { + span.addNetworkEvent(NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build()); + return span; + } + + /** This benchmark attempts to measure performance of adding a link to the span. */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span addLink() { + span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Link.Type.PARENT)); + return span; + } +} diff --git a/benchmarks/src/jmh/java/com/google/instrumentation/trace/StartEndSpanBenchmark.java b/benchmarks/src/jmh/java/com/google/instrumentation/trace/StartEndSpanBenchmark.java new file mode 100644 index 0000000000..ee15ad014f --- /dev/null +++ b/benchmarks/src/jmh/java/com/google/instrumentation/trace/StartEndSpanBenchmark.java @@ -0,0 +1,127 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.trace; + +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; + +/** Benchmarks for {@link SpanFactoryImpl} and {@link SpanImpl}. */ +@State(Scope.Benchmark) +public class StartEndSpanBenchmark { + private static final Tracer tracer = Tracing.getTracer(); + private static final String SPAN_NAME = "MySpanName"; + private Span rootSpan = + tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + + @TearDown + public void doTearDown() { + rootSpan.end(); + } + + /** + * This benchmark attempts to measure performance of start/end for a non-sampled root {@code + * Span}. + */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span startEndNonSampledRootSpan() { + Span span = + tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + span.end(); + return span; + } + + /** + * This benchmark attempts to measure performance of start/end for a root {@code Span} with record + * events option. + */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span startEndRecordEventsRootSpan() { + Span span = + tracer + .spanBuilder(SPAN_NAME) + .becomeRoot() + .setSampler(Samplers.neverSample()) + .setRecordEvents(true) + .startSpan(); + span.end(); + return span; + } + + /** + * This benchmark attempts to measure performance of start/end for a sampled root {@code Span}. + */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span startEndSampledRootSpan() { + Span span = tracer.spanBuilder(SPAN_NAME).setSampler(Samplers.alwaysSample()).startSpan(); + span.end(); + return span; + } + + /** + * This benchmark attempts to measure performance of start/end for a non-sampled child {@code + * Span}. + */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span startEndNonSampledChildSpan() { + Span span = + tracer.spanBuilder(rootSpan, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); + span.end(); + return span; + } + + /** + * This benchmark attempts to measure performance of start/end for a child {@code Span} with + * record events option. + */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span startEndRecordEventsChildSpan() { + Span span = + tracer + .spanBuilder(rootSpan, SPAN_NAME) + .setSampler(Samplers.neverSample()) + .setRecordEvents(true) + .startSpan(); + span.end(); + return span; + } + + /** + * This benchmark attempts to measure performance of start/end for a sampled child {@code Span}. + */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public Span startEndSampledChildSpan() { + Span span = + tracer.spanBuilder(rootSpan, SPAN_NAME).setSampler(Samplers.alwaysSample()).startSpan(); + span.end(); + return span; + } +} From 688ce216c964cd03a67e44ee29d7985c13db1c54 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Tue, 16 May 2017 10:45:33 -0700 Subject: [PATCH 0091/1581] Add getCurrentStatsContext() and withStatsContext() API to StatsContextFactory. (#305) * Add getCurrentStatsContext() and withStatsContext() API to StatsContextFactory. * Return default StatsContext instead of null when no context. * Fix a typo in Tracer documentation. --- .../stats/StatsContextFactory.java | 66 +++++++++++++++++++ .../google/instrumentation/trace/Tracer.java | 8 +-- .../stats/StatsContextFactoryTest.java | 65 +++++++++++++++++- 3 files changed, 134 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/StatsContextFactory.java b/core/src/main/java/com/google/instrumentation/stats/StatsContextFactory.java index 5956c841a3..238d122f47 100644 --- a/core/src/main/java/com/google/instrumentation/stats/StatsContextFactory.java +++ b/core/src/main/java/com/google/instrumentation/stats/StatsContextFactory.java @@ -13,6 +13,9 @@ package com.google.instrumentation.stats; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.instrumentation.common.NonThrowingCloseable; import java.io.IOException; import java.io.InputStream; @@ -20,6 +23,7 @@ * Factory class for {@link StatsContext}. */ public abstract class StatsContextFactory { + /** * Creates a {@link StatsContext} from the given on-the-wire encoded representation. * @@ -35,4 +39,66 @@ public abstract class StatsContextFactory { * Returns the default {@link StatsContext}. */ public abstract StatsContext getDefault(); + + /** + * Get current StatsContext from current gRPC Context. + * + * @return the current {@code StatsContext} from {@code io.grpc.Context}, or the default + * {@code StatsContext} if there's no {@code StatsContext} associated with current + * {@code io.grpc.Context}. + */ + public final StatsContext getCurrentStatsContext() { + StatsContext statsContext = ContextUtils.getCurrentStatsContext(); + return statsContext != null ? statsContext : getDefault(); + } + + /** + * Enters the scope of code where the given {@link StatsContext} is in the current Context, and + * returns an object that represents that scope. The scope is exited when the returned object is + * closed. + * + *

Supports try-with-resource idiom. + * + *

Example of usage: + * + *

{@code
+   * private final StatsContextFactory statsCtxFactory =
+   *     checkNotNull(Stats.getStatsContextFactory(), "statsCtxFactory");
+   * void doWork() {
+   *   // Construct a new StatsContext with required tags to be set into current context.
+   *   StatsContext statsCtx = statsCtxFactory.getCurrentStatsContext().with(tagKey, tagValue);
+   *   try (NonThrowingCloseable scopedStatsCtx = statsCtxFactory.withStatsContext(statsCtx)) {
+   *     doSomeOtherWork();  // Here "scopedStatsCtx" is the current StatsContext.
+   *   }
+   * }
+   * }
+ * + *

Prior to Java SE 7, you can use a finally block to ensure that a resource is closed + * regardless of whether the try statement completes normally or abruptly. + * + *

Example of usage prior to Java SE7: + * + *

{@code
+   * private final StatsContextFactory statsCtxFactory =
+   *     checkNotNull(Stats.getStatsContextFactory(), "statsCtxFactory");
+   * void doWork() {
+   *   // Construct a new StatsContext with required tags to be set into current context.
+   *   StatsContext statsCtx = statsCtxFactory.getCurrentStatsContext().with(tagKey, tagValue);
+   *   NonThrowingCloseable scopedStatsCtx = statsCtxFactory.withStatsContext(statsCtx);
+   *   try {
+   *     doSomeOtherWork();  // Here "scopedStatsCtx" is the current StatsContext.
+   *   } finally {
+   *     scopedStatsCtx.close();
+   *   }
+   * }
+   * }
+ * + * @param statsContext The {@link StatsContext} to be set to the current Context. + * @return an object that defines a scope where the given {@link StatsContext} will be set to the + * current Context. + * @throws NullPointerException if statsContext is null. + */ + public final NonThrowingCloseable withStatsContext(StatsContext statsContext) { + return ContextUtils.withStatsContext(checkNotNull(statsContext, "statsContext")); + } } diff --git a/core/src/main/java/com/google/instrumentation/trace/Tracer.java b/core/src/main/java/com/google/instrumentation/trace/Tracer.java index 386d2dec85..2c1ccfc66d 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Tracer.java +++ b/core/src/main/java/com/google/instrumentation/trace/Tracer.java @@ -105,9 +105,9 @@ public final Span getCurrentSpan() { * *
{@code
    * private static Tracer tracer = Tracing.getTracer();
-   * void doWork {
+   * void doWork() {
    *   // Create a Span as a child of the current Span.
-   *   Span span = tracer.startSpan("my span");
+   *   Span span = tracer.spanBuilder("my span").startSpan();
    *   try (NonThrowingCloseable ws = tracer.withSpan(span)) {
    *     tracer.getCurrentSpan().addAnnotation("my annotation");
    *     doSomeOtherWork();  // Here "span" is the current Span.
@@ -123,9 +123,9 @@ public final Span getCurrentSpan() {
    *
    * 
{@code
    * private static Tracer tracer = Tracing.getTracer();
-   * void doWork {
+   * void doWork() {
    *   // Create a Span as a child of the current Span.
-   *   Span span = tracer.startSpan("my span");
+   *   Span span = tracer.spanBuilder("my span").startSpan();
    *   NonThrowingCloseable ws = tracer.withSpan(span);
    *   try {
    *     tracer.getCurrentSpan().addAnnotation("my annotation");
diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java
index 884bcddf83..97115fccad 100644
--- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java
+++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java
@@ -15,9 +15,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import com.google.instrumentation.common.NonThrowingCloseable;
 import com.google.instrumentation.common.SimpleEventQueue;
 import com.google.instrumentation.internal.TestClock;
 import com.google.io.base.VarInt;
+import io.grpc.Context;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -41,6 +43,9 @@ public class StatsContextFactoryTest {
       new StatsManagerImplBase(new SimpleEventQueue(), TestClock.create());
   private final StatsContextFactory factory = new StatsContextFactoryImpl(statsManager);
   private final HashMap sampleTags = new HashMap();
+  private final StatsContext defaultCtx = factory.getDefault();
+  private final StatsContext statsContext = factory.getDefault()
+      .with(TagKey.create(KEY), TagValue.create(VALUE_STRING));
 
   public StatsContextFactoryTest() {
     sampleTags.put(
@@ -131,8 +136,66 @@ public void testDeserializeWrongVersionId() throws Exception {
     testDeserialize(new ByteArrayInputStream(new byte[]{(byte) (StatsSerializer.VERSION_ID + 1)}));
   }
 
+  @Test
+  public void testGetDefaultForCurrentStatsContextWhenNotSet() {
+    assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx);
+  }
+
+  @Test
+  public void testGetCurrentStatsContext() {
+    assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx);
+    Context origContext = Context.current().withValue(
+        ContextUtils.STATS_CONTEXT_KEY, statsContext)
+        .attach();
+    // Make sure context is detached even if test fails.
+    try {
+      assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext);
+    } finally {
+      Context.current().detach(origContext);
+    }
+    assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx);
+  }
+
+  @Test(expected = NullPointerException.class)
+  public void testWithNullStatsContext() {
+    factory.withStatsContext(null);
+  }
+
+  @Test
+  public void testWithStatsContext() {
+    assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx);
+    NonThrowingCloseable scopedStatsCtx = factory.withStatsContext(statsContext);
+    try {
+      assertThat(factory.getCurrentStatsContext()).isEqualTo(statsContext);
+    } finally {
+      scopedStatsCtx.close();
+    }
+    assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx);
+  }
+
+  @Test
+  public void testWithStatsContextUsingWrap() {
+    Runnable runnable;
+    NonThrowingCloseable scopedStatsCtx = factory.withStatsContext(statsContext);
+    try {
+      assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext);
+      runnable = Context.current().wrap(
+          new Runnable() {
+            @Override
+            public void run() {
+              assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext);
+            }
+          });
+    } finally {
+      scopedStatsCtx.close();
+    }
+    assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx);
+    // When we run the runnable we will have the statsContext in the current Context.
+    runnable.run();
+  }
+
   private StatsContext testDeserialize(InputStream inputStream)
-      throws IOException, IOException {
+      throws IOException {
     return factory.deserialize(inputStream);
   }
 

From 2b6b1e87d82c7277cb5e4b76a18a62c3d048931b Mon Sep 17 00:00:00 2001
From: Bogdan Drutu 
Date: Tue, 16 May 2017 10:50:30 -0700
Subject: [PATCH 0092/1581] Add implementation for Span#addAttributes. (#303)

---
 .../instrumentation/trace/SpanImpl.java       |  93 ++++++++++---
 .../instrumentation/trace/SpanImplTest.java   | 124 +++++++++++++++++-
 2 files changed, 200 insertions(+), 17 deletions(-)

diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java
index 96fced49b5..4ba7f0d442 100644
--- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java
+++ b/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java
@@ -23,6 +23,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
@@ -54,13 +55,16 @@ final class SpanImpl extends Span {
   // The start time of the span. Set when the span is created iff the RECORD_EVENTS options is
   // set, otherwise 0.
   private final long startNanoTime;
-  // List of the recorded annotations.
+  // Set of recorded attributes. DO NOT CALL any other method that change the ordering of events.
+  @GuardedBy("this")
+  private AttributesWithCapacity attributes;
+  // List of recorded annotations.
   @GuardedBy("this")
   private TraceEvents> annotations;
-  // List of the recorded network events.
+  // List of recorded network events.
   @GuardedBy("this")
   private TraceEvents> networkEvents;
-  // List of the recorded links.
+  // List of recorded links.
   @GuardedBy("this")
   private TraceEvents links;
   // The status of the span. Set when the span is ended iff the RECORD_EVENTS options is set.
@@ -136,7 +140,10 @@ SpanData toSpanData() {
         getOptions().contains(Options.RECORD_EVENTS),
         "Getting SpanData for a Span without RECORD_EVENTS option.");
     synchronized (this) {
-      // TODO(bdrutu): Set the attributes in the SpanData when add the support for them.
+      SpanData.Attributes attributesSpanData =
+          attributes == null
+              ? SpanData.Attributes.create(Collections.emptyMap(), 0)
+              : SpanData.Attributes.create(attributes, attributes.getNumberOfDroppedAttributes());
       SpanData.TimedEvents annotationsSpanData =
           createTimedEvents(annotations, timestampConverter);
       SpanData.TimedEvents networkEventsSpanData =
@@ -144,14 +151,15 @@ SpanData toSpanData() {
       SpanData.Links linksSpanData =
           links == null
               ? SpanData.Links.create(Collections.emptyList(), 0)
-              : SpanData.Links.create(new ArrayList(links.events), links.getDroppedEvents());
+              : SpanData.Links.create(
+                  new ArrayList(links.events), links.getNumberOfDroppedEvents());
       return SpanData.create(
           getContext(),
           parentSpanId,
           hasRemoteParent,
           name,
           timestampConverter.convertNanoTime(startNanoTime),
-          SpanData.Attributes.create(Collections.emptyMap(), 0),
+          attributesSpanData,
           annotationsSpanData,
           networkEventsSpanData,
           linksSpanData,
@@ -162,7 +170,16 @@ SpanData toSpanData() {
 
   @Override
   public void addAttributes(Map attributes) {
-    // TODO(bdrutu): Implement this.
+    if (!getOptions().contains(Options.RECORD_EVENTS)) {
+      return;
+    }
+    synchronized (this) {
+      if (hasBeenEnded) {
+        logger.log(Level.FINE, "Calling addAttributes() on an ended Span.");
+        return;
+      }
+      getInitializedAttributes().addAttributes(attributes);
+    }
   }
 
   @Override
@@ -172,7 +189,7 @@ public void addAnnotation(String description, Map attrib
     }
     synchronized (this) {
       if (hasBeenEnded) {
-        logger.log(Level.FINE, "Calling end() on an ended Span.");
+        logger.log(Level.FINE, "Calling addAnnotation() on an ended Span.");
         return;
       }
       getInitializedAnnotations()
@@ -190,7 +207,7 @@ public void addAnnotation(Annotation annotation) {
     }
     synchronized (this) {
       if (hasBeenEnded) {
-        logger.log(Level.FINE, "Calling end() on an ended Span.");
+        logger.log(Level.FINE, "Calling addAnnotation() on an ended Span.");
         return;
       }
       getInitializedAnnotations()
@@ -207,7 +224,7 @@ public void addNetworkEvent(NetworkEvent networkEvent) {
     }
     synchronized (this) {
       if (hasBeenEnded) {
-        logger.log(Level.FINE, "Calling end() on an ended Span.");
+        logger.log(Level.FINE, "Calling addNetworkEvent() on an ended Span.");
         return;
       }
       getInitializedNetworkEvents()
@@ -224,7 +241,7 @@ public void addLink(Link link) {
     }
     synchronized (this) {
       if (hasBeenEnded) {
-        logger.log(Level.FINE, "Calling end() on an ended Span.");
+        logger.log(Level.FINE, "Calling addLink() on an ended Span.");
         return;
       }
       getInitializedLinks().addEvent(checkNotNull(link, "link"));
@@ -248,6 +265,14 @@ public void end(EndSpanOptions options) {
     }
   }
 
+  @GuardedBy("this")
+  private AttributesWithCapacity getInitializedAttributes() {
+    if (attributes == null) {
+      attributes = new AttributesWithCapacity(traceParams.getMaxNumberOfAttributes());
+    }
+    return attributes;
+  }
+
   @GuardedBy("this")
   private TraceEvents> getInitializedAnnotations() {
     if (annotations == null) {
@@ -284,7 +309,7 @@ private static  SpanData.TimedEvents createTimedEvents(
     for (EventWithNanoTime networkEvent : events.events) {
       eventsList.add(networkEvent.toSpanDataTimedEvent(timestampConverter));
     }
-    return SpanData.TimedEvents.create(eventsList, events.getDroppedEvents());
+    return SpanData.TimedEvents.create(eventsList, events.getNumberOfDroppedEvents());
   }
 
   /**
@@ -303,12 +328,48 @@ interface StartEndHandler {
     void onEnd(SpanImpl span);
   }
 
+  // A map implementation with a fixed capacity that drops events when the map gets full. Eviction
+  // is based on the access order.
+  private static final class AttributesWithCapacity extends LinkedHashMap {
+    private final int capacity;
+    private int totalRecordedAttributes = 0;
+    // Here because -Werror complains about this: [serial] serializable class AttributesWithCapacity
+    // has no definition of serialVersionUID. This class shouldn't be serialized.
+    private static final long serialVersionUID = 42L;
+
+    private AttributesWithCapacity(int capacity) {
+      // Capacity of the map is capacity + 1 to avoid resizing because removeEldestEntry is invoked
+      // by put and putAll after inserting a new entry into the map. The loadFactor is set to 1
+      // to avoid resizing because. The accessOrder is set to true.
+      super(capacity + 1, 1, true);
+      this.capacity = capacity;
+    }
+
+    // Users must call this method instead of put or putAll to keep count of the total number of
+    // entries inserted.
+    private void addAttributes(Map attributes) {
+      totalRecordedAttributes += attributes.size();
+      putAll(attributes);
+    }
+
+    private int getNumberOfDroppedAttributes() {
+      return totalRecordedAttributes - size();
+    }
+
+    // It is called after each put or putAll call in order to determine if the eldest inserted
+    // entry should be removed or not.
+    @Override
+    protected boolean removeEldestEntry(Map.Entry eldest) {
+      return size() > this.capacity;
+    }
+  }
+
   private static final class TraceEvents {
-    private int totalRecordedevents = 0;
+    private int totalRecordedEvents = 0;
     private final EvictingQueue events;
 
-    private int getDroppedEvents() {
-      return totalRecordedevents - events.size();
+    private int getNumberOfDroppedEvents() {
+      return totalRecordedEvents - events.size();
     }
 
     TraceEvents(int maxNumEvents) {
@@ -316,7 +377,7 @@ private int getDroppedEvents() {
     }
 
     void addEvent(T event) {
-      totalRecordedevents++;
+      totalRecordedEvents++;
       events.add(event);
     }
   }
diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java
index 1de4b088fe..3f24c862d9 100644
--- a/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java
+++ b/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java
@@ -59,6 +59,8 @@ public void setUp() {
     MockitoAnnotations.initMocks(this);
     attributes.put(
         "MyStringAttributeKey", AttributeValue.stringAttributeValue("MyStringAttributeValue"));
+    attributes.put("MyLongAttributeKey", AttributeValue.longAttributeValue(123L));
+    attributes.put("MyBooleanAttributeKey", AttributeValue.booleanAttributeValue(false));
   }
 
   @Test
@@ -75,6 +77,7 @@ public void toSpanData_NoRecordEvents() {
             timestampConverter,
             testClock);
     // Check that adding trace events after Span#end() does not throw any exception.
+    span.addAttributes(attributes);
     span.addAnnotation(Annotation.fromDescription(ANNOTATION_DESCRIPTION));
     span.addAnnotation(ANNOTATION_DESCRIPTION, attributes);
     span.addNetworkEvent(NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build());
@@ -98,13 +101,16 @@ public void noEventsRecordedAfterEnd() {
             timestampConverter,
             testClock);
     span.end();
-    // Check that adding trace events after Span#end() does not throw any exception.
+    // Check that adding trace events after Span#end() does not throw any exception and are not
+    // recorded.
+    span.addAttributes(attributes);
     span.addAnnotation(Annotation.fromDescription(ANNOTATION_DESCRIPTION));
     span.addAnnotation(ANNOTATION_DESCRIPTION, attributes);
     span.addNetworkEvent(NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build());
     span.addLink(Link.fromSpanContext(spanContext, Link.Type.CHILD));
     SpanData spanData = span.toSpanData();
     assertThat(spanData.getStartTimestamp()).isEqualTo(timestamp);
+    assertThat(spanData.getAttributes().getAttributeMap()).isEmpty();
     assertThat(spanData.getAnnotations().getEvents()).isEmpty();
     assertThat(spanData.getNetworkEvents().getEvents()).isEmpty();
     assertThat(spanData.getLinks().getLinks()).isEmpty();
@@ -126,6 +132,7 @@ public void toSpanData_ActiveSpan() {
             timestampConverter,
             testClock);
     Mockito.verify(startEndHandler, Mockito.times(1)).onStart(span);
+    span.addAttributes(attributes);
     testClock.advanceTime(Duration.create(0, 100));
     span.addAnnotation(Annotation.fromDescription(ANNOTATION_DESCRIPTION));
     testClock.advanceTime(Duration.create(0, 100));
@@ -142,6 +149,8 @@ public void toSpanData_ActiveSpan() {
     assertThat(spanData.getDisplayName()).isEqualTo(SPAN_NAME);
     assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId);
     assertThat(spanData.getHasRemoteParent()).isTrue();
+    assertThat(spanData.getAttributes().getDroppedAttributesCount()).isEqualTo(0);
+    assertThat(spanData.getAttributes().getAttributeMap()).isEqualTo(attributes);
     assertThat(spanData.getAnnotations().getDroppedEventsCount()).isEqualTo(0);
     assertThat(spanData.getAnnotations().getEvents().size()).isEqualTo(2);
     assertThat(spanData.getAnnotations().getEvents().get(0).getTimestamp())
@@ -179,6 +188,7 @@ public void toSpanData_EndedSpan() {
             timestampConverter,
             testClock);
     Mockito.verify(startEndHandler, Mockito.times(1)).onStart(span);
+    span.addAttributes(attributes);
     testClock.advanceTime(Duration.create(0, 100));
     span.addAnnotation(Annotation.fromDescription(ANNOTATION_DESCRIPTION));
     testClock.advanceTime(Duration.create(0, 100));
@@ -197,6 +207,8 @@ public void toSpanData_EndedSpan() {
     assertThat(spanData.getDisplayName()).isEqualTo(SPAN_NAME);
     assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId);
     assertThat(spanData.getHasRemoteParent()).isFalse();
+    assertThat(spanData.getAttributes().getDroppedAttributesCount()).isEqualTo(0);
+    assertThat(spanData.getAttributes().getAttributeMap()).isEqualTo(attributes);
     assertThat(spanData.getAnnotations().getDroppedEventsCount()).isEqualTo(0);
     assertThat(spanData.getAnnotations().getEvents().size()).isEqualTo(2);
     assertThat(spanData.getAnnotations().getEvents().get(0).getTimestamp())
@@ -220,6 +232,116 @@ public void toSpanData_EndedSpan() {
     assertThat(spanData.getEndTimestamp()).isEqualTo(timestamp.addNanos(400));
   }
 
+  @Test
+  public void droppingAttributes() {
+    final int maxNumberOfAttributes = 8;
+    TraceParams traceParams =
+        TraceParams.DEFAULT.toBuilder().setMaxNumberOfAttributes(maxNumberOfAttributes).build();
+    SpanImpl span =
+        SpanImpl.startSpan(
+            spanContext,
+            recordSpanOptions,
+            SPAN_NAME,
+            parentSpanId,
+            false,
+            traceParams,
+            startEndHandler,
+            timestampConverter,
+            testClock);
+    for (int i = 0; i < 2 * maxNumberOfAttributes; i++) {
+      Map attributes = new HashMap();
+      attributes.put("MyStringAttributeKey" + i, AttributeValue.longAttributeValue(i));
+      span.addAttributes(attributes);
+    }
+    SpanData spanData = span.toSpanData();
+    assertThat(spanData.getAttributes().getDroppedAttributesCount())
+        .isEqualTo(maxNumberOfAttributes);
+    assertThat(spanData.getAttributes().getAttributeMap().size()).isEqualTo(maxNumberOfAttributes);
+    for (int i = 0; i < maxNumberOfAttributes; i++) {
+      assertThat(
+              spanData
+                  .getAttributes()
+                  .getAttributeMap()
+                  .get("MyStringAttributeKey" + (i + maxNumberOfAttributes)))
+          .isEqualTo(AttributeValue.longAttributeValue(i + maxNumberOfAttributes));
+    }
+    span.end();
+    spanData = span.toSpanData();
+    assertThat(spanData.getAttributes().getDroppedAttributesCount())
+        .isEqualTo(maxNumberOfAttributes);
+    assertThat(spanData.getAttributes().getAttributeMap().size()).isEqualTo(maxNumberOfAttributes);
+    for (int i = 0; i < maxNumberOfAttributes; i++) {
+      assertThat(
+              spanData
+                  .getAttributes()
+                  .getAttributeMap()
+                  .get("MyStringAttributeKey" + (i + maxNumberOfAttributes)))
+          .isEqualTo(AttributeValue.longAttributeValue(i + maxNumberOfAttributes));
+    }
+  }
+
+  @Test
+  public void droppingAndAddingAttributes() {
+    final int maxNumberOfAttributes = 8;
+    TraceParams traceParams =
+        TraceParams.DEFAULT.toBuilder().setMaxNumberOfAttributes(maxNumberOfAttributes).build();
+    SpanImpl span =
+        SpanImpl.startSpan(
+            spanContext,
+            recordSpanOptions,
+            SPAN_NAME,
+            parentSpanId,
+            false,
+            traceParams,
+            startEndHandler,
+            timestampConverter,
+            testClock);
+    for (int i = 0; i < 2 * maxNumberOfAttributes; i++) {
+      Map attributes = new HashMap();
+      attributes.put("MyStringAttributeKey" + i, AttributeValue.longAttributeValue(i));
+      span.addAttributes(attributes);
+    }
+    SpanData spanData = span.toSpanData();
+    assertThat(spanData.getAttributes().getDroppedAttributesCount())
+        .isEqualTo(maxNumberOfAttributes);
+    assertThat(spanData.getAttributes().getAttributeMap().size()).isEqualTo(maxNumberOfAttributes);
+    for (int i = 0; i < maxNumberOfAttributes; i++) {
+      assertThat(
+          spanData
+              .getAttributes()
+              .getAttributeMap()
+              .get("MyStringAttributeKey" + (i + maxNumberOfAttributes)))
+          .isEqualTo(AttributeValue.longAttributeValue(i + maxNumberOfAttributes));
+    }
+    for (int i = 0; i < maxNumberOfAttributes / 2; i++) {
+      Map attributes = new HashMap();
+      attributes.put("MyStringAttributeKey" + i, AttributeValue.longAttributeValue(i));
+      span.addAttributes(attributes);
+    }
+    spanData = span.toSpanData();
+    assertThat(spanData.getAttributes().getDroppedAttributesCount())
+        .isEqualTo(maxNumberOfAttributes * 3 / 2);
+    assertThat(spanData.getAttributes().getAttributeMap().size()).isEqualTo(maxNumberOfAttributes);
+    // Test that we still have in the attributes map the latest maxNumberOfAttributes / 2 entries.
+    for (int i = 0; i < maxNumberOfAttributes / 2; i++) {
+      assertThat(
+          spanData
+              .getAttributes()
+              .getAttributeMap()
+              .get("MyStringAttributeKey" + (i + maxNumberOfAttributes * 3 / 2)))
+          .isEqualTo(AttributeValue.longAttributeValue(i + maxNumberOfAttributes * 3 / 2));
+    }
+    // Test that we have the newest re-added initial entries.
+    for (int i = 0; i < maxNumberOfAttributes / 2; i++) {
+      assertThat(
+          spanData
+              .getAttributes()
+              .getAttributeMap()
+              .get("MyStringAttributeKey" + i))
+          .isEqualTo(AttributeValue.longAttributeValue(i));
+    }
+  }
+
   @Test
   public void droppingAnnotations() {
     final int maxNumberOfAnnotations = 8;

From 0a34c32b05cce05dffaba2e947cb0581d0a1df5b Mon Sep 17 00:00:00 2001
From: Yang Song 
Date: Tue, 16 May 2017 12:01:38 -0700
Subject: [PATCH 0093/1581] Fix a few style issues. (#307)

* Fix a few style issues.

* Update check for doubles.
---
 .../instrumentation/trace/TraceConfig.java    |  3 +++
 .../stats/DistributionAggregationTest.java    | 22 ++++++++++---------
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java b/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java
index d7b97dbf09..34b64b3605 100644
--- a/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java
+++ b/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java
@@ -125,6 +125,9 @@ private static Builder builder() {
      */
     public abstract Builder toBuilder();
 
+    /**
+     * A {@code Builder} class for {@link TraceParams}.
+     */
     @AutoValue.Builder
     public abstract static class Builder {
 
diff --git a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java b/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java
index 633de2bb99..572412a2cc 100644
--- a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java
+++ b/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java
@@ -15,9 +15,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import com.google.instrumentation.stats.DistributionAggregation.Range;
-
 import com.google.common.testing.EqualsTester;
+import com.google.instrumentation.stats.DistributionAggregation.Range;
 import java.util.Arrays;
 import java.util.List;
 import org.junit.Test;
@@ -29,16 +28,19 @@
  */
 @RunWith(JUnit4.class)
 public final class DistributionAggregationTest {
+
+  private static final double TOLERANCE = 1e-6;
+
   @Test
   public void testDistributionAggregationWithOutBuckets() {
     DistributionAggregation aggr = DistributionAggregation.create(10, 5.0, 30.0,
         Range.create(1.0, 5.0), TAGS);
 
     assertThat(aggr.getCount()).isEqualTo(10);
-    assertThat(aggr.getMean()).isEqualTo(5.0);
-    assertThat(aggr.getSum()).isEqualTo(30.0);
-    assertThat(aggr.getRange().getMin()).isEqualTo(1.0);
-    assertThat(aggr.getRange().getMax()).isEqualTo(5.0);
+    assertThat(aggr.getMean()).isWithin(TOLERANCE).of(5.0);
+    assertThat(aggr.getSum()).isWithin(TOLERANCE).of(30.0);
+    assertThat(aggr.getRange().getMin()).isWithin(TOLERANCE).of(1.0);
+    assertThat(aggr.getRange().getMax()).isWithin(TOLERANCE).of(5.0);
     assertThat(aggr.getTags()).hasSize(TAGS.size());
     for (int i = 0; i < aggr.getTags().size(); i++) {
       assertThat(aggr.getTags().get(i)).isEqualTo(TAGS.get(i));
@@ -53,10 +55,10 @@ public void testDistributionAggregationWithBuckets() {
         Range.create(1.0, 5.0), TAGS, buckets);
 
     assertThat(aggr.getCount()).isEqualTo(10);
-    assertThat(aggr.getMean()).isEqualTo(5.0);
-    assertThat(aggr.getSum()).isEqualTo(30.0);
-    assertThat(aggr.getRange().getMin()).isEqualTo(1.0);
-    assertThat(aggr.getRange().getMax()).isEqualTo(5.0);
+    assertThat(aggr.getMean()).isWithin(TOLERANCE).of(5.0);
+    assertThat(aggr.getSum()).isWithin(TOLERANCE).of(30.0);
+    assertThat(aggr.getRange().getMin()).isWithin(TOLERANCE).of(1.0);
+    assertThat(aggr.getRange().getMax()).isWithin(TOLERANCE).of(5.0);
     assertThat(aggr.getBucketCounts()).isNotNull();
     assertThat(aggr.getBucketCounts()).hasSize(buckets.size());
     assertThat(aggr.getTags()).hasSize(TAGS.size());

From 156006623a8269f378b842a6a402af10ed72d4e9 Mon Sep 17 00:00:00 2001
From: Bogdan Drutu 
Date: Tue, 16 May 2017 22:36:29 -0700
Subject: [PATCH 0094/1581] Move VarInt to core_impl and change the package
 name. (#308)

* Move VarInt to core_impl and change the package name.
* Suppress warnings in VarInt.java.
---
 checkstyle.xml                                                 | 2 ++
 core_impl/build.gradle                                         | 1 -
 .../main/java/com/google/instrumentation/internal}/VarInt.java | 3 ++-
 .../java/com/google/instrumentation/stats/StatsSerializer.java | 2 +-
 .../google/instrumentation/stats/StatsContextFactoryTest.java  | 2 +-
 .../com/google/instrumentation/stats/StatsContextTest.java     | 2 +-
 settings.gradle                                                | 2 --
 shared/build.gradle                                            | 1 -
 8 files changed, 7 insertions(+), 8 deletions(-)
 rename {shared/src/main/java/com/google/io/base => core_impl/src/main/java/com/google/instrumentation/internal}/VarInt.java (99%)
 delete mode 100644 shared/build.gradle

diff --git a/checkstyle.xml b/checkstyle.xml
index 45f054897c..72ad2fa50e 100644
--- a/checkstyle.xml
+++ b/checkstyle.xml
@@ -215,5 +215,7 @@
             
         
         
+        
     
+    
 
diff --git a/core_impl/build.gradle b/core_impl/build.gradle
index afb0513589..558c091853 100644
--- a/core_impl/build.gradle
+++ b/core_impl/build.gradle
@@ -2,7 +2,6 @@ description = 'Instrumentation Core Impl'
 
 dependencies {
     compile project(':core'),
-            project(':shared'),
             libraries.guava
 
     compileOnly libraries.auto_value
diff --git a/shared/src/main/java/com/google/io/base/VarInt.java b/core_impl/src/main/java/com/google/instrumentation/internal/VarInt.java
similarity index 99%
rename from shared/src/main/java/com/google/io/base/VarInt.java
rename to core_impl/src/main/java/com/google/instrumentation/internal/VarInt.java
index a2d0ed044e..d3d85bf327 100644
--- a/shared/src/main/java/com/google/io/base/VarInt.java
+++ b/core_impl/src/main/java/com/google/instrumentation/internal/VarInt.java
@@ -11,7 +11,7 @@
  * limitations under the License.
  */
 
-package com.google.io.base;
+package com.google.instrumentation.internal;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -22,6 +22,7 @@
  * Common methods to encode and decode varints and varlongs into ByteBuffers and
  * arrays.
  */
+// CHECKSTYLE:OFF
 public class VarInt {
 
   /**
diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java
index ffd7ea741c..108c961cb6 100644
--- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java
+++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java
@@ -15,7 +15,7 @@
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.io.ByteStreams;
-import com.google.io.base.VarInt;
+import com.google.instrumentation.internal.VarInt;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java
index 97115fccad..217695a2e0 100644
--- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java
+++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java
@@ -18,7 +18,7 @@
 import com.google.instrumentation.common.NonThrowingCloseable;
 import com.google.instrumentation.common.SimpleEventQueue;
 import com.google.instrumentation.internal.TestClock;
-import com.google.io.base.VarInt;
+import com.google.instrumentation.internal.VarInt;
 import io.grpc.Context;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java
index a54f786ab0..7d963b1280 100644
--- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java
+++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java
@@ -23,7 +23,7 @@
 import com.google.instrumentation.internal.TestClock;
 import com.google.instrumentation.stats.View.DistributionView;
 import com.google.instrumentation.stats.View.IntervalView;
-import com.google.io.base.VarInt;
+import com.google.instrumentation.internal.VarInt;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
diff --git a/settings.gradle b/settings.gradle
index 5b0bb48057..f826e9315d 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -4,14 +4,12 @@ include ":core"
 include ":core_impl"
 include ":core_impl_java"
 include ":core_impl_android"
-include ":shared"
 
 project(':all').projectDir = "$rootDir/all" as File
 project(':core').projectDir = "$rootDir/core" as File
 project(':core_impl').projectDir = "$rootDir/core_impl" as File
 project(':core_impl_java').projectDir = "$rootDir/core_impl_java" as File
 project(':core_impl_android').projectDir = "$rootDir/core_impl_android" as File
-project(':shared').projectDir = "$rootDir/shared" as File
 
 // Java8 projects only
 if (JavaVersion.current().isJava8Compatible()) {
diff --git a/shared/build.gradle b/shared/build.gradle
deleted file mode 100644
index d50d137113..0000000000
--- a/shared/build.gradle
+++ /dev/null
@@ -1 +0,0 @@
-description = 'Shared'

From f443b1a4eb88e5ad0f6d4d4f6ee9fb3e4290f54e Mon Sep 17 00:00:00 2001
From: Bogdan Drutu 
Date: Tue, 16 May 2017 22:42:40 -0700
Subject: [PATCH 0095/1581] Add check for the license header. (#309)

---
 checkstyle.license                                  | 12 ++++++++++++
 checkstyle.xml                                      |  8 ++++++++
 .../common/NonThrowingCloseable.java                | 13 +++++++++++++
 3 files changed, 33 insertions(+)
 create mode 100644 checkstyle.license

diff --git a/checkstyle.license b/checkstyle.license
new file mode 100644
index 0000000000..9b26608508
--- /dev/null
+++ b/checkstyle.license
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2017, Google Inc.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
diff --git a/checkstyle.xml b/checkstyle.xml
index 72ad2fa50e..f6bb91c36c 100644
--- a/checkstyle.xml
+++ b/checkstyle.xml
@@ -20,6 +20,14 @@
 
     
 
+
+    
+        
+        
+        
+        
+    
+
     
     
     
diff --git a/core/src/main/java/com/google/instrumentation/common/NonThrowingCloseable.java b/core/src/main/java/com/google/instrumentation/common/NonThrowingCloseable.java
index 46ac71a561..d00572bc96 100644
--- a/core/src/main/java/com/google/instrumentation/common/NonThrowingCloseable.java
+++ b/core/src/main/java/com/google/instrumentation/common/NonThrowingCloseable.java
@@ -1,3 +1,16 @@
+/*
+ * Copyright 2017, Google Inc.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.google.instrumentation.common;
 
 import java.io.Closeable;

From 000d158b33c60a0020bf3c314ae1ddd3d24cb595 Mon Sep 17 00:00:00 2001
From: Stefan Schmidt 
Date: Wed, 17 May 2017 18:48:23 +0200
Subject: [PATCH 0096/1581] No longer override projectDirs now that the gradle
 subproject names match the directory names.

---
 settings.gradle | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/settings.gradle b/settings.gradle
index f826e9315d..e7881b0f19 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -5,12 +5,6 @@ include ":core_impl"
 include ":core_impl_java"
 include ":core_impl_android"
 
-project(':all').projectDir = "$rootDir/all" as File
-project(':core').projectDir = "$rootDir/core" as File
-project(':core_impl').projectDir = "$rootDir/core_impl" as File
-project(':core_impl_java').projectDir = "$rootDir/core_impl_java" as File
-project(':core_impl_android').projectDir = "$rootDir/core_impl_android" as File
-
 // Java8 projects only
 if (JavaVersion.current().isJava8Compatible()) {
     include ":examples"

From 50dba332725e72a63bf8c2df2fedde4e38e94c43 Mon Sep 17 00:00:00 2001
From: Yang Song 
Date: Wed, 17 May 2017 10:15:26 -0700
Subject: [PATCH 0097/1581] Fix a style issue. (#310)

* Fix a style issue.

* Revert changes on DistributionAggregationTest.
---
 .../stats/DistributionAggregationTest.java     | 18 ++++++++----------
 .../stats/StatsContextTest.java                |  2 +-
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java b/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java
index 572412a2cc..6094adfcb4 100644
--- a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java
+++ b/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java
@@ -29,18 +29,16 @@
 @RunWith(JUnit4.class)
 public final class DistributionAggregationTest {
 
-  private static final double TOLERANCE = 1e-6;
-
   @Test
   public void testDistributionAggregationWithOutBuckets() {
     DistributionAggregation aggr = DistributionAggregation.create(10, 5.0, 30.0,
         Range.create(1.0, 5.0), TAGS);
 
     assertThat(aggr.getCount()).isEqualTo(10);
-    assertThat(aggr.getMean()).isWithin(TOLERANCE).of(5.0);
-    assertThat(aggr.getSum()).isWithin(TOLERANCE).of(30.0);
-    assertThat(aggr.getRange().getMin()).isWithin(TOLERANCE).of(1.0);
-    assertThat(aggr.getRange().getMax()).isWithin(TOLERANCE).of(5.0);
+    assertThat(aggr.getMean()).isEqualTo(5.0);
+    assertThat(aggr.getSum()).isEqualTo(30.0);
+    assertThat(aggr.getRange().getMin()).isEqualTo(1.0);
+    assertThat(aggr.getRange().getMax()).isEqualTo(5.0);
     assertThat(aggr.getTags()).hasSize(TAGS.size());
     for (int i = 0; i < aggr.getTags().size(); i++) {
       assertThat(aggr.getTags().get(i)).isEqualTo(TAGS.get(i));
@@ -55,10 +53,10 @@ public void testDistributionAggregationWithBuckets() {
         Range.create(1.0, 5.0), TAGS, buckets);
 
     assertThat(aggr.getCount()).isEqualTo(10);
-    assertThat(aggr.getMean()).isWithin(TOLERANCE).of(5.0);
-    assertThat(aggr.getSum()).isWithin(TOLERANCE).of(30.0);
-    assertThat(aggr.getRange().getMin()).isWithin(TOLERANCE).of(1.0);
-    assertThat(aggr.getRange().getMax()).isWithin(TOLERANCE).of(5.0);
+    assertThat(aggr.getMean()).isEqualTo(5.0);
+    assertThat(aggr.getSum()).isEqualTo(30.0);
+    assertThat(aggr.getRange().getMin()).isEqualTo(1.0);
+    assertThat(aggr.getRange().getMax()).isEqualTo(5.0);
     assertThat(aggr.getBucketCounts()).isNotNull();
     assertThat(aggr.getBucketCounts()).hasSize(buckets.size());
     assertThat(aggr.getTags()).hasSize(TAGS.size());
diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java
index 7d963b1280..818e328c29 100644
--- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java
+++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java
@@ -21,9 +21,9 @@
 import com.google.instrumentation.common.Function;
 import com.google.instrumentation.common.SimpleEventQueue;
 import com.google.instrumentation.internal.TestClock;
+import com.google.instrumentation.internal.VarInt;
 import com.google.instrumentation.stats.View.DistributionView;
 import com.google.instrumentation.stats.View.IntervalView;
-import com.google.instrumentation.internal.VarInt;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;

From a2527ab2b5735f925fca489e2a759b7b94c4779e Mon Sep 17 00:00:00 2001
From: Yang Song 
Date: Wed, 17 May 2017 10:20:02 -0700
Subject: [PATCH 0098/1581] Remove deprecated TimestampFactory. (#312)

---
 .../common/TimestampFactory.java              | 37 -------------------
 .../common/TimestampFactoryTest.java          | 29 ---------------
 2 files changed, 66 deletions(-)
 delete mode 100644 core/src/main/java/com/google/instrumentation/common/TimestampFactory.java
 delete mode 100644 core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java

diff --git a/core/src/main/java/com/google/instrumentation/common/TimestampFactory.java b/core/src/main/java/com/google/instrumentation/common/TimestampFactory.java
deleted file mode 100644
index 78d354d79d..0000000000
--- a/core/src/main/java/com/google/instrumentation/common/TimestampFactory.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2017, Google Inc.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *     http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.instrumentation.common;
-
-import com.google.instrumentation.internal.MillisClock;
-
-/**
- * Factory for {@link Timestamp}. See {@link #now} for how to use this class.
- *
- * @deprecated Use {@link Clock} instead.
- */
-@Deprecated
-public final class TimestampFactory {
-  private static final Clock CLOCK = MillisClock.getInstance();
-
-  private TimestampFactory() {}
-
-  /**
-   * Obtains the current instant from the system clock.
-   *
-   * @return the current instant using the system clock, not null.
-   */
-  public static Timestamp now() {
-    return CLOCK.now();
-  }
-}
diff --git a/core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java b/core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java
deleted file mode 100644
index 1b4cc9e64e..0000000000
--- a/core/src/test/java/com/google/instrumentation/common/TimestampFactoryTest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.google.instrumentation.common;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Unit tests for {@link TimestampFactory}. */
-@SuppressWarnings("javadoc")
-@RunWith(JUnit4.class)
-public class TimestampFactoryTest {
-  private static final int NUM_NANOS_PER_MILLI = 1000 * 1000;
-
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @Test
-  @SuppressWarnings("deprecation")
-  public void millisGranularity() {
-    for (int i = 0; i < 1000000; i++) {
-      Timestamp now = TimestampFactory.now();
-      assertThat(now.getSeconds()).isGreaterThan(0L);
-      assertThat(now.getNanos() % NUM_NANOS_PER_MILLI).isEqualTo(0);
-    }
-  }
-}

From a3fc8e3d4b852a322e67d7136d7ce99990495d7b Mon Sep 17 00:00:00 2001
From: Yang Song 
Date: Wed, 17 May 2017 11:20:17 -0700
Subject: [PATCH 0099/1581] Add a missing @RunWith. (#313)

---
 .../com/google/instrumentation/stats/RpcViewConstantsTest.java | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/core/src/test/java/com/google/instrumentation/stats/RpcViewConstantsTest.java b/core/src/test/java/com/google/instrumentation/stats/RpcViewConstantsTest.java
index 01c4951f78..e79b6b6a27 100644
--- a/core/src/test/java/com/google/instrumentation/stats/RpcViewConstantsTest.java
+++ b/core/src/test/java/com/google/instrumentation/stats/RpcViewConstantsTest.java
@@ -16,10 +16,13 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
 
 /**
  * Test for {@link RpcViewConstants}.
  */
+@RunWith(JUnit4.class)
 public final class RpcViewConstantsTest {
 
   @Test

From 94eb7ffa3fe11af3c303bc3e95e1cce627361068 Mon Sep 17 00:00:00 2001
From: Kristen Kozak 
Date: Wed, 17 May 2017 10:45:52 -0700
Subject: [PATCH 0100/1581] Disable Checkstyle's MissingSwitchDefault warning.

This rule conflicts with Error Prone's exhaustiveness checking.  When all enum
cases are handled in a switch block, Error Prone doesn't allow a "default" case,
but Checkstyle always requires a "default" case.
---
 checkstyle.xml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/checkstyle.xml b/checkstyle.xml
index 45f054897c..e400f5e2dd 100644
--- a/checkstyle.xml
+++ b/checkstyle.xml
@@ -76,7 +76,8 @@
         
         
         
-        
+        
+	    
         
         
         

From a3ff8f60b2c1dda898ecae05b655acd339ae06a8 Mon Sep 17 00:00:00 2001
From: Kristen Kozak 
Date: Wed, 3 May 2017 11:36:06 -0700
Subject: [PATCH 0101/1581] Start adding a "tags" package.

This commit adds TagKey and TagSet.  The classes are not used yet.
---
 .../google/instrumentation/tags/TagKey.java   |  88 +++++++++
 .../google/instrumentation/tags/TagSet.java   | 177 +++++++++++++++++
 .../instrumentation/tags/TagKeyTest.java      |  63 ++++++
 .../internal/logging/Logger.java              |  28 +++
 .../internal/logging/TestLogger.java          |  82 ++++++++
 .../instrumentation/tags/TagSetImpl.java      | 179 +++++++++++++++++
 .../instrumentation/tags/TagSetTest.java      | 185 ++++++++++++++++++
 7 files changed, 802 insertions(+)
 create mode 100644 core/src/main/java/com/google/instrumentation/tags/TagKey.java
 create mode 100644 core/src/main/java/com/google/instrumentation/tags/TagSet.java
 create mode 100644 core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java
 create mode 100644 core_impl/src/main/java/com/google/instrumentation/internal/logging/Logger.java
 create mode 100644 core_impl/src/main/java/com/google/instrumentation/internal/logging/TestLogger.java
 create mode 100644 core_impl/src/main/java/com/google/instrumentation/tags/TagSetImpl.java
 create mode 100644 core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java

diff --git a/core/src/main/java/com/google/instrumentation/tags/TagKey.java b/core/src/main/java/com/google/instrumentation/tags/TagKey.java
new file mode 100644
index 0000000000..ea6b051879
--- /dev/null
+++ b/core/src/main/java/com/google/instrumentation/tags/TagKey.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2017, Google Inc.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.instrumentation.tags;
+
+import static com.google.instrumentation.tags.TagKey.TagType.TAG_BOOL;
+import static com.google.instrumentation.tags.TagKey.TagType.TAG_INT;
+import static com.google.instrumentation.tags.TagKey.TagType.TAG_STRING;
+
+import com.google.auto.value.AutoValue;
+import com.google.instrumentation.internal.StringUtil;
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * Tag key.
+ *
+ * @param  The type of value that can be paired with this {@code TagKey}.
+ */
+@Immutable
+@AutoValue
+public abstract class TagKey {
+  /** The maximum length for a tag key name. */
+  public static final int MAX_LENGTH = StringUtil.MAX_LENGTH;
+
+  enum TagType {
+    TAG_STRING,
+    TAG_INT,
+    TAG_BOOL
+  }
+
+  TagKey() {}
+
+  /**
+   * Constructs a {@code TagKey} from the given string. The string will be sanitized such
+   * that:
+   *
+   * 
    + *
  1. length is restricted to {@link #MAX_LENGTH}, strings longer than that will be truncated. + *
  2. characters are restricted to printable ascii characters, non-printable characters will be + * replaced by an underscore '_'. + *
+ */ + public static TagKey createString(String key) { + return new AutoValue_TagKey(StringUtil.sanitize(key), TAG_STRING); + } + + /** + * Constructs a {@code TagKey} from the given string. The string will be sanitized such + * that: + * + *
    + *
  1. length is restricted to {@link #MAX_LENGTH}, strings longer than that will be truncated. + *
  2. characters are restricted to printable ascii characters, non-printable characters will be + * replaced by an underscore '_'. + *
+ */ + public static TagKey createInt(String key) { + return new AutoValue_TagKey(StringUtil.sanitize(key), TAG_INT); + } + + /** + * Constructs a {@code TagKey} from the given string. The string will be sanitized such + * that: + * + *
    + *
  1. length is restricted to {@link #MAX_LENGTH}, strings longer than that will be truncated. + *
  2. characters are restricted to printable ascii characters, non-printable characters will be + * replaced by an underscore '_'. + *
+ */ + public static TagKey createBoolean(String key) { + return new AutoValue_TagKey(StringUtil.sanitize(key), TAG_BOOL); + } + + abstract String getName(); + + abstract TagType getTagType(); +} diff --git a/core/src/main/java/com/google/instrumentation/tags/TagSet.java b/core/src/main/java/com/google/instrumentation/tags/TagSet.java new file mode 100644 index 0000000000..c9f1682bab --- /dev/null +++ b/core/src/main/java/com/google/instrumentation/tags/TagSet.java @@ -0,0 +1,177 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.tags; + +import com.google.instrumentation.internal.StringUtil; +import javax.annotation.Nullable; + +/** A set of tags. */ +public abstract class TagSet { + /** The maximum length for a string tag value. */ + public static final int MAX_STRING_LENGTH = StringUtil.MAX_LENGTH; + + /** + * Determines whether a key is present. + * + * @param key the key to look up. + * @return {@code true} if the key is present. + */ + public abstract boolean tagKeyExists(TagKey key); + + // TODO(sebright): Which is better, the generic "get" method or three specialized "get" methods? + // Should these methods take defaults or throw exceptions to handle missing keys? + + /** + * Gets a value of type {@code String}. + * + * @param key the key to look up. + * @return the tag value, or {@code null} if the key isn't present. + */ + @Nullable + public abstract String getStringTagValue(TagKey key); + + /** + * Gets a value of type {@code long}. + * + * @param key the key to look up. + * @param defaultValue the value to return if the key is not preset. + * @return the tag value, or the default value if the key is not present. + */ + public abstract long getIntTagValue(TagKey key, long defaultValue); + + /** + * Gets a value of type {@code boolean}. + * + * @param key the key to look up. + * @param defaultValue the value to return if the key is not preset. + * @return the tag value, or the default value if the key is not present. + */ + public abstract boolean getBooleanTagValue(TagKey key, boolean defaultValue); + + /** + * Gets a value of any type. + * + * @param key the key to look up. + * @return the tag value, or {@code null} if the key isn't present. + */ + @Nullable + public abstract T getTagValue(TagKey key); + + /** + * Returns a builder based on this {@code TagSet}. + * + * @return a builder based on this {@code TagSet}. + */ + public abstract Builder toBuilder(); + + /** Builder for the {@link TagSet} class. */ + public abstract static class Builder { + + /** + * Adds the key/value pair if the key is not present. If the key is present, it logs an error. + * + * @param key the key to look up. + * @param value the value to insert for the given key. + * @return this + */ + public abstract Builder insert(TagKey key, String value); + + /** + * Adds the key/value pair if the key is not present. If the key is present, it logs an error. + * + * @param key the key to look up. + * @param value the value to insert for the given key. + * @return this + */ + public abstract Builder insert(TagKey key, long value); + + /** + * Adds the key/value pair if the key is not present. If the key is present, it logs an error. + * + * @param key the key to look up. + * @param value the value to insert for the given key. + * @return this + */ + public abstract Builder insert(TagKey key, boolean value); + + /** + * Adds the key/value pair regardless of whether the key is present. + * + * @param key the key to look up. + * @param value the value to set for the given key. + * @return this + */ + public abstract Builder set(TagKey key, String value); + + /** + * Adds the key/value pair regardless of whether the key is present. + * + * @param key the key to look up. + * @param value the value to set for the given key. + * @return this + */ + public abstract Builder set(TagKey key, long value); + + /** + * Adds the key/value pair regardless of whether the key is present. + * + * @param key the key to look up. + * @param value the value to set for the given key. + * @return this + */ + public abstract Builder set(TagKey key, boolean value); + + /** + * Adds the key/value pair only if the key is already present. + * + * @param key the key to look up. + * @param value the value to update for the given key. + * @return this + */ + public abstract Builder update(TagKey key, String value); + + /** + * Adds the key/value pair only if the key is already present. + * + * @param key the key to look up. + * @param value the value to update for the given key. + * @return this + */ + public abstract Builder update(TagKey key, long value); + + /** + * Adds the key/value pair only if the key is already present. + * + * @param key the key to look up. + * @param value the value to update for the given key. + * @return this + */ + public abstract Builder update(TagKey key, boolean value); + + /** + * Removes the key if it exists. + * + * @param key the key to look up. + * @return this + */ + public abstract Builder clear(TagKey key); + + /** + * Creates a {@code TagSet} from this builder. + * + * @return a {@code TagSet} with the same tags as this builder. + */ + public abstract TagSet build(); + } +} diff --git a/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java b/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java new file mode 100644 index 0000000000..4bdbb91985 --- /dev/null +++ b/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import com.google.instrumentation.internal.StringUtil; +import java.util.Arrays; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link TagKey} */ +@RunWith(JUnit4.class) +public final class TagKeyTest { + + @Test + public void testGetName() { + assertThat(TagKey.createString("foo").getName()).isEqualTo("foo"); + } + + @Test + public void testKeyMaxLength() { + char[] key = new char[TagKey.MAX_LENGTH]; + char[] truncKey = new char[TagKey.MAX_LENGTH + 10]; + Arrays.fill(key, 'k'); + Arrays.fill(truncKey, 'k'); + assertThat(TagKey.createString(new String(truncKey)).getName()).isEqualTo(new String(key)); + } + + @Test + public void testKeyBadChar() { + String key = "\2ab\3cd"; + assertThat(TagKey.createString(key).getName()) + .isEqualTo( + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + + "ab" + + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + + "cd"); + } + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup(TagKey.createString("foo"), TagKey.createString("foo")) + .addEqualityGroup(TagKey.createInt("foo")) + .addEqualityGroup(TagKey.createBoolean("foo")) + .addEqualityGroup(TagKey.createString("bar")) + .testEquals(); + } +} diff --git a/core_impl/src/main/java/com/google/instrumentation/internal/logging/Logger.java b/core_impl/src/main/java/com/google/instrumentation/internal/logging/Logger.java new file mode 100644 index 0000000000..8133b96439 --- /dev/null +++ b/core_impl/src/main/java/com/google/instrumentation/internal/logging/Logger.java @@ -0,0 +1,28 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.internal.logging; + +import java.util.logging.Level; + +/** Logging interface that can be used for testing log messages. */ +public interface Logger { + + /** + * Log the given message at the given level. + * + * @param level the logging level. + * @param message the message to log. + */ + void log(Level level, String message); +} diff --git a/core_impl/src/main/java/com/google/instrumentation/internal/logging/TestLogger.java b/core_impl/src/main/java/com/google/instrumentation/internal/logging/TestLogger.java new file mode 100644 index 0000000000..779e8c027e --- /dev/null +++ b/core_impl/src/main/java/com/google/instrumentation/internal/logging/TestLogger.java @@ -0,0 +1,82 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.internal.logging; + +import com.google.auto.value.AutoValue; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import javax.annotation.concurrent.GuardedBy; +import javax.annotation.concurrent.Immutable; +import javax.annotation.concurrent.ThreadSafe; + +/** + * A {@code Logger} that stores all of its log messages in memory and can be used for testing + * logging. + */ +@ThreadSafe +public final class TestLogger implements Logger { + + @GuardedBy("this") + private final List messages = new ArrayList(); + + @Override + public synchronized void log(Level level, String message) { + messages.add(LogRecord.create(level, message)); + } + + /** + * Returns a snapshot of all messages logged so far. + * + * @return a list of all log messages. + */ + public synchronized List getMessages() { + return new ArrayList(messages); + } + + /** + * A stored log record. + */ + @Immutable + @AutoValue + public abstract static class LogRecord { + + LogRecord() {} + + /** + * Creates a {@code LogRecord}. + * + * @param level the logging level. + * @param message the log message. + * @return a {@code LogRecord}. + */ + public static LogRecord create(Level level, String message) { + return new AutoValue_TestLogger_LogRecord(level, message); + } + + /** + * Returns the logging level of the message. + * + * @return the logging level of the message. + */ + public abstract Level getLevel(); + + /** + * Returns the logged message. + * + * @return the logged message. + */ + public abstract String getMessage(); + } +} diff --git a/core_impl/src/main/java/com/google/instrumentation/tags/TagSetImpl.java b/core_impl/src/main/java/com/google/instrumentation/tags/TagSetImpl.java new file mode 100644 index 0000000000..583a4d9225 --- /dev/null +++ b/core_impl/src/main/java/com/google/instrumentation/tags/TagSetImpl.java @@ -0,0 +1,179 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.tags; + +import com.google.common.base.Preconditions; +import com.google.instrumentation.internal.StringUtil; +import com.google.instrumentation.internal.logging.Logger; +import com.google.instrumentation.tags.TagKey.TagType; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import javax.annotation.Nullable; + +/** A set of tags. */ +// The class is immutable, except for the logger. +public final class TagSetImpl extends TagSet { + + private final Logger logger; + + // The types of the TagKey and value must match for each entry. + private final Map, Object> tags; + + TagSetImpl(Logger logger, Map, Object> tags) { + this.logger = logger; + this.tags = tags; + } + + Map, Object> getTags() { + return tags; + } + + @Override + public boolean tagKeyExists(TagKey key) { + return tags.containsKey(key); + } + + @Nullable + @Override + public String getStringTagValue(TagKey key) { + return (String) tags.get(key); + } + + @Override + public long getIntTagValue(TagKey key, long defaultValue) { + Long value = (Long) tags.get(key); + return value == null ? defaultValue : value; + } + + @Override + public boolean getBooleanTagValue(TagKey key, boolean defaultValue) { + Boolean value = (Boolean) tags.get(key); + return value == null ? defaultValue : value; + } + + @Override + public T getTagValue(TagKey key) { + // An unchecked cast is okay, because we validate the values when they are inserted. + @SuppressWarnings("unchecked") + T value = (T) tags.get(key); + return value; + } + + @Override + public Builder toBuilder() { + return new Builder(logger, getTags()); + } + + public static final class Builder extends TagSet.Builder { + private final Logger logger; + private final Map, Object> tags; + + private Builder(Logger logger, Map, Object> tags) { + this.logger = logger; + this.tags = new HashMap, Object>(tags); + } + + Builder(Logger logger) { + this.logger = logger; + this.tags = new HashMap, Object>(); + } + + @Override + public Builder insert(TagKey key, String value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); + return insertInternal(key, StringUtil.sanitize(value)); + } + + @Override + public Builder insert(TagKey key, long value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); + return insertInternal(key, value); + } + + @Override + public Builder insert(TagKey key, boolean value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); + return insertInternal(key, value); + } + + private Builder insertInternal(TagKey key, TagValueT value) { + if (!tags.containsKey(key)) { + tags.put(key, value); + } else { + logger.log(Level.WARNING, "Tag key already exists: " + key); + } + return this; + } + + @Override + public Builder set(TagKey key, String value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); + return setInternal(key, StringUtil.sanitize(value)); + } + + @Override + public Builder set(TagKey key, long value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); + return setInternal(key, value); + } + + @Override + public Builder set(TagKey key, boolean value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); + return setInternal(key, value); + } + + private Builder setInternal(TagKey key, TagValueT value) { + tags.put(key, value); + return this; + } + + @Override + public Builder update(TagKey key, String value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); + return updateInternal(key, StringUtil.sanitize(value)); + } + + @Override + public Builder update(TagKey key, long value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); + return updateInternal(key, value); + } + + @Override + public Builder update(TagKey key, boolean value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); + return updateInternal(key, value); + } + + private Builder updateInternal(TagKey key, TagValueT value) { + if (tags.containsKey(key)) { + tags.put(key, value); + } + return this; + } + + @Override + public Builder clear(TagKey key) { + tags.remove(key); + return this; + } + + @Override + public TagSetImpl build() { + return new TagSetImpl(logger, new HashMap, Object>(tags)); + } + } +} diff --git a/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java b/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java new file mode 100644 index 0000000000..a762c6d4ad --- /dev/null +++ b/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java @@ -0,0 +1,185 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableMap; +import com.google.instrumentation.internal.StringUtil; +import com.google.instrumentation.internal.logging.TestLogger; +import com.google.instrumentation.internal.logging.TestLogger.LogRecord; +import java.util.Arrays; +import java.util.logging.Level; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link TagSet}. */ +// TODO(sebright): Add more tests once the API is finalized. +@RunWith(JUnit4.class) +public class TagSetTest { + + private static final TagKey KS1 = TagKey.createString("k1"); + private static final TagKey KS2 = TagKey.createString("k2"); + private static final TagKey KI = TagKey.createInt("k2"); + private static final TagKey KB = TagKey.createBoolean("k3"); + + private final TestLogger tagSetLogger = new TestLogger(); + + @Test + public void applyTagChangesInOrder() { + assertThat(newBuilder().set(KS1, "v1").set(KS1, "v2").build().getTags()) + .containsExactly(KS1, "v2"); + } + + @Test + public void testInsert() { + TagSetImpl tags = singletonTagSet(KS1, "v1"); + assertThat(tags.toBuilder().insert(KS2, "v2").build().getTags()) + .containsExactly(KS1, "v1", KS2, "v2"); + assertThat(tagSetLogger.getMessages()).isEmpty(); + } + + @Test + public void testInsertExistingTag() { + TagSetImpl tags = singletonTagSet(KS1, "v1"); + assertThat(tagSetLogger.getMessages()).isEmpty(); + assertThat(tags.toBuilder().insert(KS1, "v2").build().getTags()).containsExactly(KS1, "v1"); + assertThat(tagSetLogger.getMessages()) + .containsExactly(LogRecord.create(Level.WARNING, "Tag key already exists: " + KS1)); + } + + @Test + public void testSet() { + TagSetImpl tags = singletonTagSet(KS1, "v1"); + assertThat(tags.toBuilder().set(KS1, "v2").build().getTags()).containsExactly(KS1, "v2"); + assertThat(tags.toBuilder().set(KS2, "v2").build().getTags()) + .containsExactly(KS1, "v1", KS2, "v2"); + assertThat(tagSetLogger.getMessages()).isEmpty(); + } + + @Test + public void testUpdate() { + TagSetImpl tags = singletonTagSet(KS1, "v1"); + assertThat(tags.toBuilder().update(KS1, "v2").build().getTags()).containsExactly(KS1, "v2"); + assertThat(tags.toBuilder().update(KS2, "v2").build().getTags()).containsExactly(KS1, "v1"); + assertThat(tagSetLogger.getMessages()).isEmpty(); + } + + @Test + public void testClear() { + TagSetImpl tags = singletonTagSet(KS1, "v1"); + assertThat(tags.toBuilder().clear(KS1).build().getTags()).isEmpty(); + assertThat(tags.toBuilder().clear(KS2).build().getTags()).containsExactly(KS1, "v1"); + assertThat(tagSetLogger.getMessages()).isEmpty(); + } + + @Test + public void testGenericGetTag() { + TagSetImpl tags = newBuilder().set(KS1, "my string").set(KB, true).set(KI, 100).build(); + assertThat(tags.getTagValue(KS1)).isEqualTo("my string"); + assertThat(tags.getTagValue(KB)).isEqualTo(true); + assertThat(tags.getTagValue(KI)).isEqualTo(100); + assertThat(tags.getTagValue(TagKey.createString("unknown"))).isNull(); + } + + @Test + public void testSpecializedGetTag() { + TagSetImpl tags = newBuilder().set(KS1, "my string").set(KB, true).set(KI, 100).build(); + assertThat(tags.getStringTagValue(KS1)).isEqualTo("my string"); + assertThat(tags.getTagValue(TagKey.createString("unknown"))).isNull(); + assertThat(tags.getBooleanTagValue(KB, false)).isEqualTo(true); + assertThat(tags.getBooleanTagValue(TagKey.createBoolean("unknown"), false)).isFalse(); + assertThat(tags.getIntTagValue(KI, 0)).isEqualTo(100); + assertThat(tags.getIntTagValue(TagKey.createInt("unknown"), -1)).isEqualTo(-1); + } + + @Test + public void testValueMaxLength() { + char[] chars = new char[TagSet.MAX_STRING_LENGTH]; + char[] truncChars = new char[TagSet.MAX_STRING_LENGTH + 10]; + Arrays.fill(chars, 'v'); + Arrays.fill(truncChars, 'v'); + String value = new String(chars); + String truncValue = new String(chars); + TagKey key1 = TagKey.createString("K1"); + TagKey key2 = TagKey.createString("K2"); + TagKey key3 = TagKey.createString("K3"); + assertThat( + newBuilder() + .insert(key1, value) + .set(key2, value) + .set(key3, "") // allow next line to update existing value + .update(key3, value) + .build() + .getTags()) + .containsExactly(key1, truncValue, key2, truncValue, key3, truncValue); + } + + @Test + public void testValueBadChar() { + String value = "\2ab\3cd"; + TagKey key1 = TagKey.createString("K1"); + TagKey key2 = TagKey.createString("K2"); + TagKey key3 = TagKey.createString("K3"); + String expected = + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + + "ab" + + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + + "cd"; + assertThat( + newBuilder() + .insert(key1, value) + .set(key2, value) + .set(key3, "") // allow next line to update existing value + .update(key3, value) + .build() + .getTags()) + .containsExactly(key1, expected, key2, expected, key3, expected); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + private final TagKey badIntKey = (TagKey) TagKey.createString("Key"); + + @Test(expected = IllegalArgumentException.class) + public void disallowInsertingWrongTypeOfKey() { + newBuilder().insert(badIntKey, 123); + } + + @Test(expected = IllegalArgumentException.class) + public void disallowSettingWrongTypeOfKey() { + newBuilder().set(badIntKey, 123); + } + + @Test(expected = IllegalArgumentException.class) + public void disallowUpdatingWrongTypeOfKey() { + newBuilder().update(badIntKey, 123); + } + + // This is only allowed because we cannot prevent it. + @Test + public void allowCallingGetWithWrongTypeOfKey() { + TagSet tags = newBuilder().set(TagKey.createString("Key"), "string").build(); + Object value = tags.getTagValue(badIntKey); + assertThat(value).isEqualTo("string"); + } + + private TagSetImpl.Builder newBuilder() { + return new TagSetImpl.Builder(tagSetLogger); + } + + private TagSetImpl singletonTagSet(TagKey key, TagValueT value) { + return new TagSetImpl(tagSetLogger, ImmutableMap., Object>of(key, value)); + } +} From 4c78ae049c19bf21151d0b70c2f8d3967d4ff21b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 3 May 2017 17:05:27 -0700 Subject: [PATCH 0102/1581] Reword Javadocs for TagSet "get" methods. --- .../main/java/com/google/instrumentation/tags/TagSet.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagSet.java b/core/src/main/java/com/google/instrumentation/tags/TagSet.java index c9f1682bab..17955b0f5f 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagSet.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagSet.java @@ -33,7 +33,7 @@ public abstract class TagSet { // Should these methods take defaults or throw exceptions to handle missing keys? /** - * Gets a value of type {@code String}. + * Looks up a value of type {@code String}. * * @param key the key to look up. * @return the tag value, or {@code null} if the key isn't present. @@ -42,7 +42,7 @@ public abstract class TagSet { public abstract String getStringTagValue(TagKey key); /** - * Gets a value of type {@code long}. + * Looks up a value of type {@code long}. * * @param key the key to look up. * @param defaultValue the value to return if the key is not preset. @@ -51,7 +51,7 @@ public abstract class TagSet { public abstract long getIntTagValue(TagKey key, long defaultValue); /** - * Gets a value of type {@code boolean}. + * Looks up a value of type {@code boolean}. * * @param key the key to look up. * @param defaultValue the value to return if the key is not preset. @@ -60,7 +60,7 @@ public abstract class TagSet { public abstract boolean getBooleanTagValue(TagKey key, boolean defaultValue); /** - * Gets a value of any type. + * Looks up a value of any type. * * @param key the key to look up. * @return the tag value, or {@code null} if the key isn't present. From ba29c61456f13d198e9a161593a5e45e90eabc80 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 3 May 2017 17:24:18 -0700 Subject: [PATCH 0103/1581] Expand TagKey and TagSet Javadocs. --- .../main/java/com/google/instrumentation/tags/TagKey.java | 5 +++-- .../main/java/com/google/instrumentation/tags/TagSet.java | 8 +++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagKey.java b/core/src/main/java/com/google/instrumentation/tags/TagKey.java index ea6b051879..5787863cc2 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagKey.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagKey.java @@ -22,9 +22,10 @@ import javax.annotation.concurrent.Immutable; /** - * Tag key. + * A key to a value stored in a {@link TagSet}. * - * @param The type of value that can be paired with this {@code TagKey}. + * @param The type of value that can be paired with this {@code TagKey}. {@code TagKey}s + * can only be instantiated with types {@code String}, {@code Long}, and {@code Boolean}. */ @Immutable @AutoValue diff --git a/core/src/main/java/com/google/instrumentation/tags/TagSet.java b/core/src/main/java/com/google/instrumentation/tags/TagSet.java index 17955b0f5f..7b4f38915d 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagSet.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagSet.java @@ -16,7 +16,13 @@ import com.google.instrumentation.internal.StringUtil; import javax.annotation.Nullable; -/** A set of tags. */ +/** + * A set of key-value pairs that can be used to label anything that is associated with a specific + * operation. + * + *

For example, {@code TagSet}s can be used to label stats, log messages, or debugging + * information. + */ public abstract class TagSet { /** The maximum length for a string tag value. */ public static final int MAX_STRING_LENGTH = StringUtil.MAX_LENGTH; From 56be09f5d9fce830cee7337504d75f95754a7ad7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 3 May 2017 18:13:31 -0700 Subject: [PATCH 0104/1581] Add another TODO. --- .../main/java/com/google/instrumentation/tags/TagSet.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagSet.java b/core/src/main/java/com/google/instrumentation/tags/TagSet.java index 7b4f38915d..f81775da2c 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagSet.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagSet.java @@ -36,7 +36,9 @@ public abstract class TagSet { public abstract boolean tagKeyExists(TagKey key); // TODO(sebright): Which is better, the generic "get" method or three specialized "get" methods? - // Should these methods take defaults or throw exceptions to handle missing keys? + // The specialized "get" methods can return primitives, which could be less expensive. + + // TODO(sebright): Should these methods take defaults or throw exceptions to handle missing keys? /** * Looks up a value of type {@code String}. @@ -84,6 +86,9 @@ public abstract class TagSet { /** Builder for the {@link TagSet} class. */ public abstract static class Builder { + // TODO(sebright): Which is better, generic "insert", "set", and "update" methods, or these + // specialized methods that can take primitives? + /** * Adds the key/value pair if the key is not present. If the key is present, it logs an error. * From 4078ee9cacfd084773bb8c2bfffa76de7dd84341 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 9 May 2017 18:14:47 -0700 Subject: [PATCH 0105/1581] Remove generic TagSet "get" method and default arguments to specialized "get" methods. --- .../google/instrumentation/tags/TagSet.java | 34 ++++------------ .../instrumentation/tags/TagSetImpl.java | 28 ++++++------- .../instrumentation/tags/TagSetTest.java | 39 ++++++++----------- 3 files changed, 39 insertions(+), 62 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagSet.java b/core/src/main/java/com/google/instrumentation/tags/TagSet.java index f81775da2c..f23e7cc800 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagSet.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagSet.java @@ -14,7 +14,6 @@ package com.google.instrumentation.tags; import com.google.instrumentation.internal.StringUtil; -import javax.annotation.Nullable; /** * A set of key-value pairs that can be used to label anything that is associated with a specific @@ -35,46 +34,32 @@ public abstract class TagSet { */ public abstract boolean tagKeyExists(TagKey key); - // TODO(sebright): Which is better, the generic "get" method or three specialized "get" methods? - // The specialized "get" methods can return primitives, which could be less expensive. - - // TODO(sebright): Should these methods take defaults or throw exceptions to handle missing keys? - /** * Looks up a value of type {@code String}. * * @param key the key to look up. - * @return the tag value, or {@code null} if the key isn't present. + * @return the tag value associated with the given key. + * @throws IllegalArgumentException if the key doesn't exist. */ - @Nullable public abstract String getStringTagValue(TagKey key); /** * Looks up a value of type {@code long}. * * @param key the key to look up. - * @param defaultValue the value to return if the key is not preset. - * @return the tag value, or the default value if the key is not present. + * @return the tag value associated with the given key. + * @throws IllegalArgumentException if the key doesn't exist. */ - public abstract long getIntTagValue(TagKey key, long defaultValue); + public abstract long getIntTagValue(TagKey key); /** * Looks up a value of type {@code boolean}. * * @param key the key to look up. - * @param defaultValue the value to return if the key is not preset. - * @return the tag value, or the default value if the key is not present. - */ - public abstract boolean getBooleanTagValue(TagKey key, boolean defaultValue); - - /** - * Looks up a value of any type. - * - * @param key the key to look up. - * @return the tag value, or {@code null} if the key isn't present. + * @return the tag value associated with the given key. + * @throws IllegalArgumentException if the key doesn't exist. */ - @Nullable - public abstract T getTagValue(TagKey key); + public abstract boolean getBooleanTagValue(TagKey key); /** * Returns a builder based on this {@code TagSet}. @@ -86,9 +71,6 @@ public abstract class TagSet { /** Builder for the {@link TagSet} class. */ public abstract static class Builder { - // TODO(sebright): Which is better, generic "insert", "set", and "update" methods, or these - // specialized methods that can take primitives? - /** * Adds the key/value pair if the key is not present. If the key is present, it logs an error. * diff --git a/core_impl/src/main/java/com/google/instrumentation/tags/TagSetImpl.java b/core_impl/src/main/java/com/google/instrumentation/tags/TagSetImpl.java index 583a4d9225..a8cf791e76 100644 --- a/core_impl/src/main/java/com/google/instrumentation/tags/TagSetImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/tags/TagSetImpl.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.Map; import java.util.logging.Level; -import javax.annotation.Nullable; /** A set of tags. */ // The class is immutable, except for the logger. @@ -45,29 +44,30 @@ public boolean tagKeyExists(TagKey key) { return tags.containsKey(key); } - @Nullable @Override public String getStringTagValue(TagKey key) { - return (String) tags.get(key); + String value = (String) tags.get(key); + if (value == null) { + throw new IllegalArgumentException("key " + key + " does not exist."); + } + return value; } @Override - public long getIntTagValue(TagKey key, long defaultValue) { + public long getIntTagValue(TagKey key) { Long value = (Long) tags.get(key); - return value == null ? defaultValue : value; + if (value == null) { + throw new IllegalArgumentException("key " + key + " does not exist."); + } + return value; } @Override - public boolean getBooleanTagValue(TagKey key, boolean defaultValue) { + public boolean getBooleanTagValue(TagKey key) { Boolean value = (Boolean) tags.get(key); - return value == null ? defaultValue : value; - } - - @Override - public T getTagValue(TagKey key) { - // An unchecked cast is okay, because we validate the values when they are inserted. - @SuppressWarnings("unchecked") - T value = (T) tags.get(key); + if (value == null) { + throw new IllegalArgumentException("key " + key + " does not exist."); + } return value; } diff --git a/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java b/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java index a762c6d4ad..6ac11cff78 100644 --- a/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java @@ -86,23 +86,26 @@ public void testClear() { } @Test - public void testGenericGetTag() { + public void testGetTag() { TagSetImpl tags = newBuilder().set(KS1, "my string").set(KB, true).set(KI, 100).build(); - assertThat(tags.getTagValue(KS1)).isEqualTo("my string"); - assertThat(tags.getTagValue(KB)).isEqualTo(true); - assertThat(tags.getTagValue(KI)).isEqualTo(100); - assertThat(tags.getTagValue(TagKey.createString("unknown"))).isNull(); + assertThat(tags.getStringTagValue(KS1)).isEqualTo("my string"); + assertThat(tags.getBooleanTagValue(KB)).isEqualTo(true); + assertThat(tags.getIntTagValue(KI)).isEqualTo(100); } - @Test - public void testSpecializedGetTag() { - TagSetImpl tags = newBuilder().set(KS1, "my string").set(KB, true).set(KI, 100).build(); - assertThat(tags.getStringTagValue(KS1)).isEqualTo("my string"); - assertThat(tags.getTagValue(TagKey.createString("unknown"))).isNull(); - assertThat(tags.getBooleanTagValue(KB, false)).isEqualTo(true); - assertThat(tags.getBooleanTagValue(TagKey.createBoolean("unknown"), false)).isFalse(); - assertThat(tags.getIntTagValue(KI, 0)).isEqualTo(100); - assertThat(tags.getIntTagValue(TagKey.createInt("unknown"), -1)).isEqualTo(-1); + @Test(expected = IllegalArgumentException.class) + public void testGetTagWithNonexistentString() { + newBuilder().build().getStringTagValue(TagKey.createString("unknown")); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetTagWithNonexistentInt() { + newBuilder().build().getIntTagValue(TagKey.createInt("unknown")); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetTagWithNonexistentBoolean() { + newBuilder().build().getBooleanTagValue(TagKey.createBoolean("unknown")); } @Test @@ -167,14 +170,6 @@ public void disallowUpdatingWrongTypeOfKey() { newBuilder().update(badIntKey, 123); } - // This is only allowed because we cannot prevent it. - @Test - public void allowCallingGetWithWrongTypeOfKey() { - TagSet tags = newBuilder().set(TagKey.createString("Key"), "string").build(); - Object value = tags.getTagValue(badIntKey); - assertThat(value).isEqualTo("string"); - } - private TagSetImpl.Builder newBuilder() { return new TagSetImpl.Builder(tagSetLogger); } From 0497bf7bc3d8a4dcd6cf34902d7493cc4e1cb21c Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 11 May 2017 11:21:02 -0700 Subject: [PATCH 0106/1581] Add a test for inserting multiple TagKeys with the same name but different types. --- .../google/instrumentation/tags/TagSetTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java b/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java index 6ac11cff78..268a03a0f5 100644 --- a/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java @@ -43,6 +43,21 @@ public void applyTagChangesInOrder() { .containsExactly(KS1, "v2"); } + @Test + public void allowMutlipleKeysWithSameNameButDifferentTypes() { + TagKey stringKey = TagKey.createString("key"); + TagKey intKey = TagKey.createInt("key"); + TagKey booleanKey = TagKey.createBoolean("key"); + assertThat( + newBuilder() + .set(stringKey, "value") + .set(intKey, 123) + .set(booleanKey, true) + .build() + .getTags()) + .containsExactly(stringKey, "value", intKey, 123L, booleanKey, true); + } + @Test public void testInsert() { TagSetImpl tags = singletonTagSet(KS1, "v1"); From b1aef3e7a0f01ce969f558d454952f33ed8ae2bd Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 11 May 2017 11:37:37 -0700 Subject: [PATCH 0107/1581] Rename TagSet to TagMap. --- .../google/instrumentation/tags/TagKey.java | 2 +- .../tags/{TagSet.java => TagMap.java} | 18 +++++------ .../tags/{TagSetImpl.java => TagMapImpl.java} | 10 +++---- .../tags/{TagSetTest.java => TagMapTest.java} | 30 +++++++++---------- 4 files changed, 30 insertions(+), 30 deletions(-) rename core/src/main/java/com/google/instrumentation/tags/{TagSet.java => TagMap.java} (90%) rename core_impl/src/main/java/com/google/instrumentation/tags/{TagSetImpl.java => TagMapImpl.java} (95%) rename core_impl/src/test/java/com/google/instrumentation/tags/{TagSetTest.java => TagMapTest.java} (89%) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagKey.java b/core/src/main/java/com/google/instrumentation/tags/TagKey.java index 5787863cc2..f0fb5c62a2 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagKey.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagKey.java @@ -22,7 +22,7 @@ import javax.annotation.concurrent.Immutable; /** - * A key to a value stored in a {@link TagSet}. + * A key to a value stored in a {@link TagMap}. * * @param The type of value that can be paired with this {@code TagKey}. {@code TagKey}s * can only be instantiated with types {@code String}, {@code Long}, and {@code Boolean}. diff --git a/core/src/main/java/com/google/instrumentation/tags/TagSet.java b/core/src/main/java/com/google/instrumentation/tags/TagMap.java similarity index 90% rename from core/src/main/java/com/google/instrumentation/tags/TagSet.java rename to core/src/main/java/com/google/instrumentation/tags/TagMap.java index f23e7cc800..654d546e81 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagSet.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagMap.java @@ -16,13 +16,13 @@ import com.google.instrumentation.internal.StringUtil; /** - * A set of key-value pairs that can be used to label anything that is associated with a specific + * A map from keys to values that can be used to label anything that is associated with a specific * operation. * - *

For example, {@code TagSet}s can be used to label stats, log messages, or debugging + *

For example, {@code TagMap}s can be used to label stats, log messages, or debugging * information. */ -public abstract class TagSet { +public abstract class TagMap { /** The maximum length for a string tag value. */ public static final int MAX_STRING_LENGTH = StringUtil.MAX_LENGTH; @@ -62,13 +62,13 @@ public abstract class TagSet { public abstract boolean getBooleanTagValue(TagKey key); /** - * Returns a builder based on this {@code TagSet}. + * Returns a builder based on this {@code TagMap}. * - * @return a builder based on this {@code TagSet}. + * @return a builder based on this {@code TagMap}. */ public abstract Builder toBuilder(); - /** Builder for the {@link TagSet} class. */ + /** Builder for the {@link TagMap} class. */ public abstract static class Builder { /** @@ -161,10 +161,10 @@ public abstract static class Builder { public abstract Builder clear(TagKey key); /** - * Creates a {@code TagSet} from this builder. + * Creates a {@code TagMap} from this builder. * - * @return a {@code TagSet} with the same tags as this builder. + * @return a {@code TagMap} with the same tags as this builder. */ - public abstract TagSet build(); + public abstract TagMap build(); } } diff --git a/core_impl/src/main/java/com/google/instrumentation/tags/TagSetImpl.java b/core_impl/src/main/java/com/google/instrumentation/tags/TagMapImpl.java similarity index 95% rename from core_impl/src/main/java/com/google/instrumentation/tags/TagSetImpl.java rename to core_impl/src/main/java/com/google/instrumentation/tags/TagMapImpl.java index a8cf791e76..6348412bc4 100644 --- a/core_impl/src/main/java/com/google/instrumentation/tags/TagSetImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/tags/TagMapImpl.java @@ -23,14 +23,14 @@ /** A set of tags. */ // The class is immutable, except for the logger. -public final class TagSetImpl extends TagSet { +public final class TagMapImpl extends TagMap { private final Logger logger; // The types of the TagKey and value must match for each entry. private final Map, Object> tags; - TagSetImpl(Logger logger, Map, Object> tags) { + TagMapImpl(Logger logger, Map, Object> tags) { this.logger = logger; this.tags = tags; } @@ -76,7 +76,7 @@ public Builder toBuilder() { return new Builder(logger, getTags()); } - public static final class Builder extends TagSet.Builder { + public static final class Builder extends TagMap.Builder { private final Logger logger; private final Map, Object> tags; @@ -172,8 +172,8 @@ public Builder clear(TagKey key) { } @Override - public TagSetImpl build() { - return new TagSetImpl(logger, new HashMap, Object>(tags)); + public TagMapImpl build() { + return new TagMapImpl(logger, new HashMap, Object>(tags)); } } } diff --git a/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java b/core_impl/src/test/java/com/google/instrumentation/tags/TagMapTest.java similarity index 89% rename from core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java rename to core_impl/src/test/java/com/google/instrumentation/tags/TagMapTest.java index 268a03a0f5..3cfece7635 100644 --- a/core_impl/src/test/java/com/google/instrumentation/tags/TagSetTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/tags/TagMapTest.java @@ -25,10 +25,10 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link TagSet}. */ +/** Tests for {@link TagMap}. */ // TODO(sebright): Add more tests once the API is finalized. @RunWith(JUnit4.class) -public class TagSetTest { +public class TagMapTest { private static final TagKey KS1 = TagKey.createString("k1"); private static final TagKey KS2 = TagKey.createString("k2"); @@ -38,7 +38,7 @@ public class TagSetTest { private final TestLogger tagSetLogger = new TestLogger(); @Test - public void applyTagChangesInOrder() { + public void applyBuilderOperationsInOrder() { assertThat(newBuilder().set(KS1, "v1").set(KS1, "v2").build().getTags()) .containsExactly(KS1, "v2"); } @@ -60,7 +60,7 @@ public void allowMutlipleKeysWithSameNameButDifferentTypes() { @Test public void testInsert() { - TagSetImpl tags = singletonTagSet(KS1, "v1"); + TagMapImpl tags = singletonTagMap(KS1, "v1"); assertThat(tags.toBuilder().insert(KS2, "v2").build().getTags()) .containsExactly(KS1, "v1", KS2, "v2"); assertThat(tagSetLogger.getMessages()).isEmpty(); @@ -68,7 +68,7 @@ public void testInsert() { @Test public void testInsertExistingTag() { - TagSetImpl tags = singletonTagSet(KS1, "v1"); + TagMapImpl tags = singletonTagMap(KS1, "v1"); assertThat(tagSetLogger.getMessages()).isEmpty(); assertThat(tags.toBuilder().insert(KS1, "v2").build().getTags()).containsExactly(KS1, "v1"); assertThat(tagSetLogger.getMessages()) @@ -77,7 +77,7 @@ public void testInsertExistingTag() { @Test public void testSet() { - TagSetImpl tags = singletonTagSet(KS1, "v1"); + TagMapImpl tags = singletonTagMap(KS1, "v1"); assertThat(tags.toBuilder().set(KS1, "v2").build().getTags()).containsExactly(KS1, "v2"); assertThat(tags.toBuilder().set(KS2, "v2").build().getTags()) .containsExactly(KS1, "v1", KS2, "v2"); @@ -86,7 +86,7 @@ public void testSet() { @Test public void testUpdate() { - TagSetImpl tags = singletonTagSet(KS1, "v1"); + TagMapImpl tags = singletonTagMap(KS1, "v1"); assertThat(tags.toBuilder().update(KS1, "v2").build().getTags()).containsExactly(KS1, "v2"); assertThat(tags.toBuilder().update(KS2, "v2").build().getTags()).containsExactly(KS1, "v1"); assertThat(tagSetLogger.getMessages()).isEmpty(); @@ -94,7 +94,7 @@ public void testUpdate() { @Test public void testClear() { - TagSetImpl tags = singletonTagSet(KS1, "v1"); + TagMapImpl tags = singletonTagMap(KS1, "v1"); assertThat(tags.toBuilder().clear(KS1).build().getTags()).isEmpty(); assertThat(tags.toBuilder().clear(KS2).build().getTags()).containsExactly(KS1, "v1"); assertThat(tagSetLogger.getMessages()).isEmpty(); @@ -102,7 +102,7 @@ public void testClear() { @Test public void testGetTag() { - TagSetImpl tags = newBuilder().set(KS1, "my string").set(KB, true).set(KI, 100).build(); + TagMapImpl tags = newBuilder().set(KS1, "my string").set(KB, true).set(KI, 100).build(); assertThat(tags.getStringTagValue(KS1)).isEqualTo("my string"); assertThat(tags.getBooleanTagValue(KB)).isEqualTo(true); assertThat(tags.getIntTagValue(KI)).isEqualTo(100); @@ -125,8 +125,8 @@ public void testGetTagWithNonexistentBoolean() { @Test public void testValueMaxLength() { - char[] chars = new char[TagSet.MAX_STRING_LENGTH]; - char[] truncChars = new char[TagSet.MAX_STRING_LENGTH + 10]; + char[] chars = new char[TagMap.MAX_STRING_LENGTH]; + char[] truncChars = new char[TagMap.MAX_STRING_LENGTH + 10]; Arrays.fill(chars, 'v'); Arrays.fill(truncChars, 'v'); String value = new String(chars); @@ -185,11 +185,11 @@ public void disallowUpdatingWrongTypeOfKey() { newBuilder().update(badIntKey, 123); } - private TagSetImpl.Builder newBuilder() { - return new TagSetImpl.Builder(tagSetLogger); + private TagMapImpl.Builder newBuilder() { + return new TagMapImpl.Builder(tagSetLogger); } - private TagSetImpl singletonTagSet(TagKey key, TagValueT value) { - return new TagSetImpl(tagSetLogger, ImmutableMap., Object>of(key, value)); + private TagMapImpl singletonTagMap(TagKey key, TagValueT value) { + return new TagMapImpl(tagSetLogger, ImmutableMap., Object>of(key, value)); } } From 57cf908a634853f717e6aeebb638d5edacfcc343 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 16 May 2017 18:29:38 -0700 Subject: [PATCH 0108/1581] Throw IllegalArgumentException when TagKey factory methods receive invalid Strings. --- .../instrumentation/internal/StringUtil.java | 14 +++- .../google/instrumentation/tags/TagKey.java | 79 ++++++++++++++----- .../instrumentation/tags/TagKeyTest.java | 40 ++++++++-- .../instrumentation/tags/TagMapTest.java | 10 +-- 4 files changed, 109 insertions(+), 34 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/internal/StringUtil.java b/core/src/main/java/com/google/instrumentation/internal/StringUtil.java index c3fb4a7e8a..201d306696 100644 --- a/core/src/main/java/com/google/instrumentation/internal/StringUtil.java +++ b/core/src/main/java/com/google/instrumentation/internal/StringUtil.java @@ -22,7 +22,8 @@ public final class StringUtil { public static final char UNPRINTABLE_CHAR_SUBSTITUTE = '_'; /** - * Replaces non-printable characters with underscores and truncates to {@link + * Transforms the given {@code String} into a valid tag key, tag value, or metric name. This + * method replaces non-printable characters with underscores and truncates to {@link * StringUtil#MAX_LENGTH}. * * @param str the {@code String} to be sanitized. @@ -44,6 +45,17 @@ public static String sanitize(String str) { return builder.toString(); } + /** + * Determines whether the {@code String} is a valid tag key, tag value, or metric name. + * + * @param string the {@code String} to be validated. + * @return whether the {@code String} is valid. + * @see #sanitize(String) + */ + public static boolean isValid(String string) { + return string.length() <= MAX_LENGTH && isPrintableString(string); + } + private static boolean isPrintableString(String str) { for (int i = 0; i < str.length(); i++) { if (!isPrintableChar(str.charAt(i))) { diff --git a/core/src/main/java/com/google/instrumentation/tags/TagKey.java b/core/src/main/java/com/google/instrumentation/tags/TagKey.java index f0fb5c62a2..d1bc6cda87 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagKey.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagKey.java @@ -18,6 +18,7 @@ import static com.google.instrumentation.tags.TagKey.TagType.TAG_STRING; import com.google.auto.value.AutoValue; +import com.google.common.base.Preconditions; import com.google.instrumentation.internal.StringUtil; import javax.annotation.concurrent.Immutable; @@ -42,45 +43,81 @@ enum TagType { TagKey() {} /** - * Constructs a {@code TagKey} from the given string. The string will be sanitized such - * that: + * Constructs a {@code TagKey} from the given string. The string must meet the following + * requirements: * *

    - *
  1. length is restricted to {@link #MAX_LENGTH}, strings longer than that will be truncated. - *
  2. characters are restricted to printable ascii characters, non-printable characters will be - * replaced by an underscore '_'. + *
  3. It cannot be longer than {@link #MAX_LENGTH}. + *
  4. It can only contain printable ascii characters. *
+ * + * @param name the name of the key. + * @throws IllegalArgumentException if the name is not valid. */ - public static TagKey createString(String key) { - return new AutoValue_TagKey(StringUtil.sanitize(key), TAG_STRING); + public static TagKey createString(String name) { + Preconditions.checkArgument(StringUtil.isValid(name)); + return createStringInternal(name); + } + + // Creates a TagKey by sanitizing the given String. + static TagKey createStringSanitized(String name) { + return createStringInternal(StringUtil.sanitize(name)); + } + + private static TagKey createStringInternal(String name) { + return new AutoValue_TagKey(name, TAG_STRING); } /** - * Constructs a {@code TagKey} from the given string. The string will be sanitized such - * that: + * Constructs a {@code TagKey} from the given string. The string must meet the following + * requirements: * *
    - *
  1. length is restricted to {@link #MAX_LENGTH}, strings longer than that will be truncated. - *
  2. characters are restricted to printable ascii characters, non-printable characters will be - * replaced by an underscore '_'. + *
  3. It cannot be longer than {@link #MAX_LENGTH}. + *
  4. It can only contain printable ascii characters. *
+ * + * @param name the name of the key. + * @throws IllegalArgumentException if the name is not valid. */ - public static TagKey createInt(String key) { - return new AutoValue_TagKey(StringUtil.sanitize(key), TAG_INT); + public static TagKey createInt(String name) { + Preconditions.checkArgument(StringUtil.isValid(name)); + return createIntInternal(name); + } + + // Creates a TagKey by sanitizing the given String. + static TagKey createIntSanitized(String name) { + return createIntInternal(StringUtil.sanitize(name)); + } + + private static TagKey createIntInternal(String name) { + return new AutoValue_TagKey(name, TAG_INT); } /** - * Constructs a {@code TagKey} from the given string. The string will be sanitized such - * that: + * Constructs a {@code TagKey} from the given string. The string must meet the following + * requirements: * *
    - *
  1. length is restricted to {@link #MAX_LENGTH}, strings longer than that will be truncated. - *
  2. characters are restricted to printable ascii characters, non-printable characters will be - * replaced by an underscore '_'. + *
  3. It cannot be longer than {@link #MAX_LENGTH}. + *
  4. It can only contain printable ascii characters. *
+ * + * @param name the name of the key. + * @throws IllegalArgumentException if the name is not valid. */ - public static TagKey createBoolean(String key) { - return new AutoValue_TagKey(StringUtil.sanitize(key), TAG_BOOL); + public static TagKey createBool(String name) { + Preconditions.checkArgument(StringUtil.isValid(name)); + return createBoolInternal(name); + } + + // Creates a TagKey by sanitizing the given String. + static TagKey createBoolSanitized(String name) { + return createBoolInternal(StringUtil.sanitize(name)); + } + + private static TagKey createBoolInternal(String name) { + return new AutoValue_TagKey(name, TAG_BOOL); } abstract String getName(); diff --git a/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java b/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java index 4bdbb91985..5ae0d920d7 100644 --- a/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java +++ b/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java @@ -18,7 +18,9 @@ import com.google.common.testing.EqualsTester; import com.google.instrumentation.internal.StringUtil; import java.util.Arrays; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -26,24 +28,48 @@ @RunWith(JUnit4.class) public final class TagKeyTest { + @Rule public final ExpectedException thrown = ExpectedException.none(); + @Test public void testGetName() { assertThat(TagKey.createString("foo").getName()).isEqualTo("foo"); } @Test - public void testKeyMaxLength() { + public void createString_AllowTagKeyNameWithMaxLength() { char[] key = new char[TagKey.MAX_LENGTH]; - char[] truncKey = new char[TagKey.MAX_LENGTH + 10]; + Arrays.fill(key, 'k'); + TagKey.createString(new String(key)); + } + + @Test + public void createString_DisallowTagKeyNameOverMaxLength() { + char[] key = new char[TagKey.MAX_LENGTH + 1]; + Arrays.fill(key, 'k'); + thrown.expect(IllegalArgumentException.class); + TagKey.createString(new String(key)); + } + + @Test + public void createStringSanitized_TruncateLongKey() { + char[] key = new char[TagKey.MAX_LENGTH]; + char[] truncKey = new char[TagKey.MAX_LENGTH + 1]; Arrays.fill(key, 'k'); Arrays.fill(truncKey, 'k'); - assertThat(TagKey.createString(new String(truncKey)).getName()).isEqualTo(new String(key)); + assertThat(TagKey.createStringSanitized(new String(truncKey)).getName()) + .isEqualTo(new String(key)); + } + + @Test + public void createString_DisallowUnprintableChars() { + thrown.expect(IllegalArgumentException.class); + TagKey.createString("\2ab\3cd"); } @Test - public void testKeyBadChar() { + public void createStringSanitized_SubstituteUnprintableChars() { String key = "\2ab\3cd"; - assertThat(TagKey.createString(key).getName()) + assertThat(TagKey.createStringSanitized(key).getName()) .isEqualTo( StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + "ab" @@ -52,11 +78,11 @@ public void testKeyBadChar() { } @Test - public void testEquals() { + public void testTagKeyEquals() { new EqualsTester() .addEqualityGroup(TagKey.createString("foo"), TagKey.createString("foo")) .addEqualityGroup(TagKey.createInt("foo")) - .addEqualityGroup(TagKey.createBoolean("foo")) + .addEqualityGroup(TagKey.createBool("foo")) .addEqualityGroup(TagKey.createString("bar")) .testEquals(); } diff --git a/core_impl/src/test/java/com/google/instrumentation/tags/TagMapTest.java b/core_impl/src/test/java/com/google/instrumentation/tags/TagMapTest.java index 3cfece7635..0c3cac6f73 100644 --- a/core_impl/src/test/java/com/google/instrumentation/tags/TagMapTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/tags/TagMapTest.java @@ -33,7 +33,7 @@ public class TagMapTest { private static final TagKey KS1 = TagKey.createString("k1"); private static final TagKey KS2 = TagKey.createString("k2"); private static final TagKey KI = TagKey.createInt("k2"); - private static final TagKey KB = TagKey.createBoolean("k3"); + private static final TagKey KB = TagKey.createBool("k3"); private final TestLogger tagSetLogger = new TestLogger(); @@ -47,15 +47,15 @@ public void applyBuilderOperationsInOrder() { public void allowMutlipleKeysWithSameNameButDifferentTypes() { TagKey stringKey = TagKey.createString("key"); TagKey intKey = TagKey.createInt("key"); - TagKey booleanKey = TagKey.createBoolean("key"); + TagKey boolKey = TagKey.createBool("key"); assertThat( newBuilder() .set(stringKey, "value") .set(intKey, 123) - .set(booleanKey, true) + .set(boolKey, true) .build() .getTags()) - .containsExactly(stringKey, "value", intKey, 123L, booleanKey, true); + .containsExactly(stringKey, "value", intKey, 123L, boolKey, true); } @Test @@ -120,7 +120,7 @@ public void testGetTagWithNonexistentInt() { @Test(expected = IllegalArgumentException.class) public void testGetTagWithNonexistentBoolean() { - newBuilder().build().getBooleanTagValue(TagKey.createBoolean("unknown")); + newBuilder().build().getBooleanTagValue(TagKey.createBool("unknown")); } @Test From 39a1755772c55496c8562892c888b9a2d3054a6b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 17 May 2017 13:08:46 -0700 Subject: [PATCH 0109/1581] Make TagMap a final class, and remove logging. --- .../google/instrumentation/tags/TagMap.java | 135 +++++++++++-- .../instrumentation/tags/TagMapTest.java | 37 +--- .../internal/logging/Logger.java | 28 --- .../internal/logging/TestLogger.java | 82 -------- .../instrumentation/tags/TagMapImpl.java | 179 ------------------ 5 files changed, 127 insertions(+), 334 deletions(-) rename {core_impl => core}/src/test/java/com/google/instrumentation/tags/TagMapTest.java (81%) delete mode 100644 core_impl/src/main/java/com/google/instrumentation/internal/logging/Logger.java delete mode 100644 core_impl/src/main/java/com/google/instrumentation/internal/logging/TestLogger.java delete mode 100644 core_impl/src/main/java/com/google/instrumentation/tags/TagMapImpl.java diff --git a/core/src/main/java/com/google/instrumentation/tags/TagMap.java b/core/src/main/java/com/google/instrumentation/tags/TagMap.java index 654d546e81..fe4bebe6d5 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagMap.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagMap.java @@ -13,7 +13,12 @@ package com.google.instrumentation.tags; +import com.google.common.base.Preconditions; import com.google.instrumentation.internal.StringUtil; +import com.google.instrumentation.tags.TagKey.TagType; +import java.util.HashMap; +import java.util.Map; +import javax.annotation.concurrent.Immutable; /** * A map from keys to values that can be used to label anything that is associated with a specific @@ -22,17 +27,31 @@ *

For example, {@code TagMap}s can be used to label stats, log messages, or debugging * information. */ -public abstract class TagMap { +@Immutable +public final class TagMap { /** The maximum length for a string tag value. */ public static final int MAX_STRING_LENGTH = StringUtil.MAX_LENGTH; + // The types of the TagKey and value must match for each entry. + private final Map, Object> tags; + + TagMap(Map, Object> tags) { + this.tags = tags; + } + + Map, Object> getTags() { + return tags; + } + /** * Determines whether a key is present. * * @param key the key to look up. * @return {@code true} if the key is present. */ - public abstract boolean tagKeyExists(TagKey key); + public boolean tagKeyExists(TagKey key) { + return tags.containsKey(key); + } /** * Looks up a value of type {@code String}. @@ -41,7 +60,13 @@ public abstract class TagMap { * @return the tag value associated with the given key. * @throws IllegalArgumentException if the key doesn't exist. */ - public abstract String getStringTagValue(TagKey key); + public String getStringTagValue(TagKey key) { + String value = (String) tags.get(key); + if (value == null) { + throw new IllegalArgumentException("key " + key + " does not exist."); + } + return value; + } /** * Looks up a value of type {@code long}. @@ -50,7 +75,13 @@ public abstract class TagMap { * @return the tag value associated with the given key. * @throws IllegalArgumentException if the key doesn't exist. */ - public abstract long getIntTagValue(TagKey key); + public long getIntTagValue(TagKey key) { + Long value = (Long) tags.get(key); + if (value == null) { + throw new IllegalArgumentException("key " + key + " does not exist."); + } + return value; + } /** * Looks up a value of type {@code boolean}. @@ -59,17 +90,34 @@ public abstract class TagMap { * @return the tag value associated with the given key. * @throws IllegalArgumentException if the key doesn't exist. */ - public abstract boolean getBooleanTagValue(TagKey key); + public boolean getBooleanTagValue(TagKey key) { + Boolean value = (Boolean) tags.get(key); + if (value == null) { + throw new IllegalArgumentException("key " + key + " does not exist."); + } + return value; + } /** * Returns a builder based on this {@code TagMap}. * * @return a builder based on this {@code TagMap}. */ - public abstract Builder toBuilder(); + public Builder toBuilder() { + return new Builder(getTags()); + } /** Builder for the {@link TagMap} class. */ - public abstract static class Builder { + public static final class Builder { + private final Map, Object> tags; + + private Builder(Map, Object> tags) { + this.tags = new HashMap, Object>(tags); + } + + Builder() { + this.tags = new HashMap, Object>(); + } /** * Adds the key/value pair if the key is not present. If the key is present, it logs an error. @@ -78,7 +126,10 @@ public abstract static class Builder { * @param value the value to insert for the given key. * @return this */ - public abstract Builder insert(TagKey key, String value); + public Builder insert(TagKey key, String value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); + return insertInternal(key, StringUtil.sanitize(value)); + } /** * Adds the key/value pair if the key is not present. If the key is present, it logs an error. @@ -87,7 +138,10 @@ public abstract static class Builder { * @param value the value to insert for the given key. * @return this */ - public abstract Builder insert(TagKey key, long value); + public Builder insert(TagKey key, long value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); + return insertInternal(key, value); + } /** * Adds the key/value pair if the key is not present. If the key is present, it logs an error. @@ -96,7 +150,17 @@ public abstract static class Builder { * @param value the value to insert for the given key. * @return this */ - public abstract Builder insert(TagKey key, boolean value); + public Builder insert(TagKey key, boolean value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); + return insertInternal(key, value); + } + + private Builder insertInternal(TagKey key, TagValueT value) { + if (!tags.containsKey(key)) { + tags.put(key, value); + } + return this; + } /** * Adds the key/value pair regardless of whether the key is present. @@ -105,7 +169,10 @@ public abstract static class Builder { * @param value the value to set for the given key. * @return this */ - public abstract Builder set(TagKey key, String value); + public Builder set(TagKey key, String value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); + return setInternal(key, StringUtil.sanitize(value)); + } /** * Adds the key/value pair regardless of whether the key is present. @@ -114,7 +181,10 @@ public abstract static class Builder { * @param value the value to set for the given key. * @return this */ - public abstract Builder set(TagKey key, long value); + public Builder set(TagKey key, long value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); + return setInternal(key, value); + } /** * Adds the key/value pair regardless of whether the key is present. @@ -123,7 +193,15 @@ public abstract static class Builder { * @param value the value to set for the given key. * @return this */ - public abstract Builder set(TagKey key, boolean value); + public Builder set(TagKey key, boolean value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); + return setInternal(key, value); + } + + private Builder setInternal(TagKey key, TagValueT value) { + tags.put(key, value); + return this; + } /** * Adds the key/value pair only if the key is already present. @@ -132,7 +210,10 @@ public abstract static class Builder { * @param value the value to update for the given key. * @return this */ - public abstract Builder update(TagKey key, String value); + public Builder update(TagKey key, String value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); + return updateInternal(key, StringUtil.sanitize(value)); + } /** * Adds the key/value pair only if the key is already present. @@ -141,7 +222,10 @@ public abstract static class Builder { * @param value the value to update for the given key. * @return this */ - public abstract Builder update(TagKey key, long value); + public Builder update(TagKey key, long value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); + return updateInternal(key, value); + } /** * Adds the key/value pair only if the key is already present. @@ -150,7 +234,17 @@ public abstract static class Builder { * @param value the value to update for the given key. * @return this */ - public abstract Builder update(TagKey key, boolean value); + public Builder update(TagKey key, boolean value) { + Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); + return updateInternal(key, value); + } + + private Builder updateInternal(TagKey key, TagValueT value) { + if (tags.containsKey(key)) { + tags.put(key, value); + } + return this; + } /** * Removes the key if it exists. @@ -158,13 +252,18 @@ public abstract static class Builder { * @param key the key to look up. * @return this */ - public abstract Builder clear(TagKey key); + public Builder clear(TagKey key) { + tags.remove(key); + return this; + } /** * Creates a {@code TagMap} from this builder. * * @return a {@code TagMap} with the same tags as this builder. */ - public abstract TagMap build(); + public TagMap build() { + return new TagMap(new HashMap, Object>(tags)); + } } } diff --git a/core_impl/src/test/java/com/google/instrumentation/tags/TagMapTest.java b/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java similarity index 81% rename from core_impl/src/test/java/com/google/instrumentation/tags/TagMapTest.java rename to core/src/test/java/com/google/instrumentation/tags/TagMapTest.java index 0c3cac6f73..09502be46a 100644 --- a/core_impl/src/test/java/com/google/instrumentation/tags/TagMapTest.java +++ b/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java @@ -17,10 +17,7 @@ import com.google.common.collect.ImmutableMap; import com.google.instrumentation.internal.StringUtil; -import com.google.instrumentation.internal.logging.TestLogger; -import com.google.instrumentation.internal.logging.TestLogger.LogRecord; import java.util.Arrays; -import java.util.logging.Level; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -35,8 +32,6 @@ public class TagMapTest { private static final TagKey KI = TagKey.createInt("k2"); private static final TagKey KB = TagKey.createBool("k3"); - private final TestLogger tagSetLogger = new TestLogger(); - @Test public void applyBuilderOperationsInOrder() { assertThat(newBuilder().set(KS1, "v1").set(KS1, "v2").build().getTags()) @@ -60,49 +55,37 @@ public void allowMutlipleKeysWithSameNameButDifferentTypes() { @Test public void testInsert() { - TagMapImpl tags = singletonTagMap(KS1, "v1"); + TagMap tags = singletonTagMap(KS1, "v1"); + assertThat(tags.toBuilder().insert(KS1, "v2").build().getTags()).containsExactly(KS1, "v1"); assertThat(tags.toBuilder().insert(KS2, "v2").build().getTags()) .containsExactly(KS1, "v1", KS2, "v2"); - assertThat(tagSetLogger.getMessages()).isEmpty(); - } - - @Test - public void testInsertExistingTag() { - TagMapImpl tags = singletonTagMap(KS1, "v1"); - assertThat(tagSetLogger.getMessages()).isEmpty(); - assertThat(tags.toBuilder().insert(KS1, "v2").build().getTags()).containsExactly(KS1, "v1"); - assertThat(tagSetLogger.getMessages()) - .containsExactly(LogRecord.create(Level.WARNING, "Tag key already exists: " + KS1)); } @Test public void testSet() { - TagMapImpl tags = singletonTagMap(KS1, "v1"); + TagMap tags = singletonTagMap(KS1, "v1"); assertThat(tags.toBuilder().set(KS1, "v2").build().getTags()).containsExactly(KS1, "v2"); assertThat(tags.toBuilder().set(KS2, "v2").build().getTags()) .containsExactly(KS1, "v1", KS2, "v2"); - assertThat(tagSetLogger.getMessages()).isEmpty(); } @Test public void testUpdate() { - TagMapImpl tags = singletonTagMap(KS1, "v1"); + TagMap tags = singletonTagMap(KS1, "v1"); assertThat(tags.toBuilder().update(KS1, "v2").build().getTags()).containsExactly(KS1, "v2"); assertThat(tags.toBuilder().update(KS2, "v2").build().getTags()).containsExactly(KS1, "v1"); - assertThat(tagSetLogger.getMessages()).isEmpty(); } @Test public void testClear() { - TagMapImpl tags = singletonTagMap(KS1, "v1"); + TagMap tags = singletonTagMap(KS1, "v1"); assertThat(tags.toBuilder().clear(KS1).build().getTags()).isEmpty(); assertThat(tags.toBuilder().clear(KS2).build().getTags()).containsExactly(KS1, "v1"); - assertThat(tagSetLogger.getMessages()).isEmpty(); } @Test public void testGetTag() { - TagMapImpl tags = newBuilder().set(KS1, "my string").set(KB, true).set(KI, 100).build(); + TagMap tags = newBuilder().set(KS1, "my string").set(KB, true).set(KI, 100).build(); assertThat(tags.getStringTagValue(KS1)).isEqualTo("my string"); assertThat(tags.getBooleanTagValue(KB)).isEqualTo(true); assertThat(tags.getIntTagValue(KI)).isEqualTo(100); @@ -185,11 +168,11 @@ public void disallowUpdatingWrongTypeOfKey() { newBuilder().update(badIntKey, 123); } - private TagMapImpl.Builder newBuilder() { - return new TagMapImpl.Builder(tagSetLogger); + private static TagMap.Builder newBuilder() { + return new TagMap.Builder(); } - private TagMapImpl singletonTagMap(TagKey key, TagValueT value) { - return new TagMapImpl(tagSetLogger, ImmutableMap., Object>of(key, value)); + private static TagMap singletonTagMap(TagKey key, TagValueT value) { + return new TagMap(ImmutableMap., Object>of(key, value)); } } diff --git a/core_impl/src/main/java/com/google/instrumentation/internal/logging/Logger.java b/core_impl/src/main/java/com/google/instrumentation/internal/logging/Logger.java deleted file mode 100644 index 8133b96439..0000000000 --- a/core_impl/src/main/java/com/google/instrumentation/internal/logging/Logger.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.internal.logging; - -import java.util.logging.Level; - -/** Logging interface that can be used for testing log messages. */ -public interface Logger { - - /** - * Log the given message at the given level. - * - * @param level the logging level. - * @param message the message to log. - */ - void log(Level level, String message); -} diff --git a/core_impl/src/main/java/com/google/instrumentation/internal/logging/TestLogger.java b/core_impl/src/main/java/com/google/instrumentation/internal/logging/TestLogger.java deleted file mode 100644 index 779e8c027e..0000000000 --- a/core_impl/src/main/java/com/google/instrumentation/internal/logging/TestLogger.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.internal.logging; - -import com.google.auto.value.AutoValue; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; -import javax.annotation.concurrent.GuardedBy; -import javax.annotation.concurrent.Immutable; -import javax.annotation.concurrent.ThreadSafe; - -/** - * A {@code Logger} that stores all of its log messages in memory and can be used for testing - * logging. - */ -@ThreadSafe -public final class TestLogger implements Logger { - - @GuardedBy("this") - private final List messages = new ArrayList(); - - @Override - public synchronized void log(Level level, String message) { - messages.add(LogRecord.create(level, message)); - } - - /** - * Returns a snapshot of all messages logged so far. - * - * @return a list of all log messages. - */ - public synchronized List getMessages() { - return new ArrayList(messages); - } - - /** - * A stored log record. - */ - @Immutable - @AutoValue - public abstract static class LogRecord { - - LogRecord() {} - - /** - * Creates a {@code LogRecord}. - * - * @param level the logging level. - * @param message the log message. - * @return a {@code LogRecord}. - */ - public static LogRecord create(Level level, String message) { - return new AutoValue_TestLogger_LogRecord(level, message); - } - - /** - * Returns the logging level of the message. - * - * @return the logging level of the message. - */ - public abstract Level getLevel(); - - /** - * Returns the logged message. - * - * @return the logged message. - */ - public abstract String getMessage(); - } -} diff --git a/core_impl/src/main/java/com/google/instrumentation/tags/TagMapImpl.java b/core_impl/src/main/java/com/google/instrumentation/tags/TagMapImpl.java deleted file mode 100644 index 6348412bc4..0000000000 --- a/core_impl/src/main/java/com/google/instrumentation/tags/TagMapImpl.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.tags; - -import com.google.common.base.Preconditions; -import com.google.instrumentation.internal.StringUtil; -import com.google.instrumentation.internal.logging.Logger; -import com.google.instrumentation.tags.TagKey.TagType; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; - -/** A set of tags. */ -// The class is immutable, except for the logger. -public final class TagMapImpl extends TagMap { - - private final Logger logger; - - // The types of the TagKey and value must match for each entry. - private final Map, Object> tags; - - TagMapImpl(Logger logger, Map, Object> tags) { - this.logger = logger; - this.tags = tags; - } - - Map, Object> getTags() { - return tags; - } - - @Override - public boolean tagKeyExists(TagKey key) { - return tags.containsKey(key); - } - - @Override - public String getStringTagValue(TagKey key) { - String value = (String) tags.get(key); - if (value == null) { - throw new IllegalArgumentException("key " + key + " does not exist."); - } - return value; - } - - @Override - public long getIntTagValue(TagKey key) { - Long value = (Long) tags.get(key); - if (value == null) { - throw new IllegalArgumentException("key " + key + " does not exist."); - } - return value; - } - - @Override - public boolean getBooleanTagValue(TagKey key) { - Boolean value = (Boolean) tags.get(key); - if (value == null) { - throw new IllegalArgumentException("key " + key + " does not exist."); - } - return value; - } - - @Override - public Builder toBuilder() { - return new Builder(logger, getTags()); - } - - public static final class Builder extends TagMap.Builder { - private final Logger logger; - private final Map, Object> tags; - - private Builder(Logger logger, Map, Object> tags) { - this.logger = logger; - this.tags = new HashMap, Object>(tags); - } - - Builder(Logger logger) { - this.logger = logger; - this.tags = new HashMap, Object>(); - } - - @Override - public Builder insert(TagKey key, String value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); - return insertInternal(key, StringUtil.sanitize(value)); - } - - @Override - public Builder insert(TagKey key, long value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); - return insertInternal(key, value); - } - - @Override - public Builder insert(TagKey key, boolean value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); - return insertInternal(key, value); - } - - private Builder insertInternal(TagKey key, TagValueT value) { - if (!tags.containsKey(key)) { - tags.put(key, value); - } else { - logger.log(Level.WARNING, "Tag key already exists: " + key); - } - return this; - } - - @Override - public Builder set(TagKey key, String value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); - return setInternal(key, StringUtil.sanitize(value)); - } - - @Override - public Builder set(TagKey key, long value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); - return setInternal(key, value); - } - - @Override - public Builder set(TagKey key, boolean value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); - return setInternal(key, value); - } - - private Builder setInternal(TagKey key, TagValueT value) { - tags.put(key, value); - return this; - } - - @Override - public Builder update(TagKey key, String value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); - return updateInternal(key, StringUtil.sanitize(value)); - } - - @Override - public Builder update(TagKey key, long value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); - return updateInternal(key, value); - } - - @Override - public Builder update(TagKey key, boolean value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); - return updateInternal(key, value); - } - - private Builder updateInternal(TagKey key, TagValueT value) { - if (tags.containsKey(key)) { - tags.put(key, value); - } - return this; - } - - @Override - public Builder clear(TagKey key) { - tags.remove(key); - return this; - } - - @Override - public TagMapImpl build() { - return new TagMapImpl(logger, new HashMap, Object>(tags)); - } - } -} From 43c24f284849041e4ec3abebeb6c274ac77c4dfa Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 17 May 2017 17:21:46 -0700 Subject: [PATCH 0110/1581] Remove APIs for reading tags. --- .../google/instrumentation/tags/TagMap.java | 55 ------------------- .../instrumentation/tags/TagMapTest.java | 25 --------- 2 files changed, 80 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagMap.java b/core/src/main/java/com/google/instrumentation/tags/TagMap.java index fe4bebe6d5..1db052efd3 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagMap.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagMap.java @@ -43,61 +43,6 @@ Map, Object> getTags() { return tags; } - /** - * Determines whether a key is present. - * - * @param key the key to look up. - * @return {@code true} if the key is present. - */ - public boolean tagKeyExists(TagKey key) { - return tags.containsKey(key); - } - - /** - * Looks up a value of type {@code String}. - * - * @param key the key to look up. - * @return the tag value associated with the given key. - * @throws IllegalArgumentException if the key doesn't exist. - */ - public String getStringTagValue(TagKey key) { - String value = (String) tags.get(key); - if (value == null) { - throw new IllegalArgumentException("key " + key + " does not exist."); - } - return value; - } - - /** - * Looks up a value of type {@code long}. - * - * @param key the key to look up. - * @return the tag value associated with the given key. - * @throws IllegalArgumentException if the key doesn't exist. - */ - public long getIntTagValue(TagKey key) { - Long value = (Long) tags.get(key); - if (value == null) { - throw new IllegalArgumentException("key " + key + " does not exist."); - } - return value; - } - - /** - * Looks up a value of type {@code boolean}. - * - * @param key the key to look up. - * @return the tag value associated with the given key. - * @throws IllegalArgumentException if the key doesn't exist. - */ - public boolean getBooleanTagValue(TagKey key) { - Boolean value = (Boolean) tags.get(key); - if (value == null) { - throw new IllegalArgumentException("key " + key + " does not exist."); - } - return value; - } - /** * Returns a builder based on this {@code TagMap}. * diff --git a/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java b/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java index 09502be46a..f6a3dca8a3 100644 --- a/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java +++ b/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java @@ -29,8 +29,6 @@ public class TagMapTest { private static final TagKey KS1 = TagKey.createString("k1"); private static final TagKey KS2 = TagKey.createString("k2"); - private static final TagKey KI = TagKey.createInt("k2"); - private static final TagKey KB = TagKey.createBool("k3"); @Test public void applyBuilderOperationsInOrder() { @@ -83,29 +81,6 @@ public void testClear() { assertThat(tags.toBuilder().clear(KS2).build().getTags()).containsExactly(KS1, "v1"); } - @Test - public void testGetTag() { - TagMap tags = newBuilder().set(KS1, "my string").set(KB, true).set(KI, 100).build(); - assertThat(tags.getStringTagValue(KS1)).isEqualTo("my string"); - assertThat(tags.getBooleanTagValue(KB)).isEqualTo(true); - assertThat(tags.getIntTagValue(KI)).isEqualTo(100); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetTagWithNonexistentString() { - newBuilder().build().getStringTagValue(TagKey.createString("unknown")); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetTagWithNonexistentInt() { - newBuilder().build().getIntTagValue(TagKey.createInt("unknown")); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetTagWithNonexistentBoolean() { - newBuilder().build().getBooleanTagValue(TagKey.createBool("unknown")); - } - @Test public void testValueMaxLength() { char[] chars = new char[TagMap.MAX_STRING_LENGTH]; From 002f6e8444e4c63006678bf545963c94691f56f7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 17 May 2017 17:47:28 -0700 Subject: [PATCH 0111/1581] Temporarily remove TagMap.Builder.insert(...) and TagMap.Builder.update(...). --- .../google/instrumentation/tags/TagMap.java | 86 ------------------- .../instrumentation/tags/TagMapTest.java | 53 +----------- 2 files changed, 4 insertions(+), 135 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagMap.java b/core/src/main/java/com/google/instrumentation/tags/TagMap.java index 1db052efd3..a56e41c121 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagMap.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagMap.java @@ -64,49 +64,6 @@ private Builder(Map, Object> tags) { this.tags = new HashMap, Object>(); } - /** - * Adds the key/value pair if the key is not present. If the key is present, it logs an error. - * - * @param key the key to look up. - * @param value the value to insert for the given key. - * @return this - */ - public Builder insert(TagKey key, String value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); - return insertInternal(key, StringUtil.sanitize(value)); - } - - /** - * Adds the key/value pair if the key is not present. If the key is present, it logs an error. - * - * @param key the key to look up. - * @param value the value to insert for the given key. - * @return this - */ - public Builder insert(TagKey key, long value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); - return insertInternal(key, value); - } - - /** - * Adds the key/value pair if the key is not present. If the key is present, it logs an error. - * - * @param key the key to look up. - * @param value the value to insert for the given key. - * @return this - */ - public Builder insert(TagKey key, boolean value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); - return insertInternal(key, value); - } - - private Builder insertInternal(TagKey key, TagValueT value) { - if (!tags.containsKey(key)) { - tags.put(key, value); - } - return this; - } - /** * Adds the key/value pair regardless of whether the key is present. * @@ -148,49 +105,6 @@ private Builder setInternal(TagKey key, TagValueT value) return this; } - /** - * Adds the key/value pair only if the key is already present. - * - * @param key the key to look up. - * @param value the value to update for the given key. - * @return this - */ - public Builder update(TagKey key, String value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); - return updateInternal(key, StringUtil.sanitize(value)); - } - - /** - * Adds the key/value pair only if the key is already present. - * - * @param key the key to look up. - * @param value the value to update for the given key. - * @return this - */ - public Builder update(TagKey key, long value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); - return updateInternal(key, value); - } - - /** - * Adds the key/value pair only if the key is already present. - * - * @param key the key to look up. - * @param value the value to update for the given key. - * @return this - */ - public Builder update(TagKey key, boolean value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); - return updateInternal(key, value); - } - - private Builder updateInternal(TagKey key, TagValueT value) { - if (tags.containsKey(key)) { - tags.put(key, value); - } - return this; - } - /** * Removes the key if it exists. * diff --git a/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java b/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java index f6a3dca8a3..9c5e206d37 100644 --- a/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java +++ b/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java @@ -51,14 +51,6 @@ public void allowMutlipleKeysWithSameNameButDifferentTypes() { .containsExactly(stringKey, "value", intKey, 123L, boolKey, true); } - @Test - public void testInsert() { - TagMap tags = singletonTagMap(KS1, "v1"); - assertThat(tags.toBuilder().insert(KS1, "v2").build().getTags()).containsExactly(KS1, "v1"); - assertThat(tags.toBuilder().insert(KS2, "v2").build().getTags()) - .containsExactly(KS1, "v1", KS2, "v2"); - } - @Test public void testSet() { TagMap tags = singletonTagMap(KS1, "v1"); @@ -67,13 +59,6 @@ public void testSet() { .containsExactly(KS1, "v1", KS2, "v2"); } - @Test - public void testUpdate() { - TagMap tags = singletonTagMap(KS1, "v1"); - assertThat(tags.toBuilder().update(KS1, "v2").build().getTags()).containsExactly(KS1, "v2"); - assertThat(tags.toBuilder().update(KS2, "v2").build().getTags()).containsExactly(KS1, "v1"); - } - @Test public void testClear() { TagMap tags = singletonTagMap(KS1, "v1"); @@ -89,60 +74,30 @@ public void testValueMaxLength() { Arrays.fill(truncChars, 'v'); String value = new String(chars); String truncValue = new String(chars); - TagKey key1 = TagKey.createString("K1"); - TagKey key2 = TagKey.createString("K2"); - TagKey key3 = TagKey.createString("K3"); - assertThat( - newBuilder() - .insert(key1, value) - .set(key2, value) - .set(key3, "") // allow next line to update existing value - .update(key3, value) - .build() - .getTags()) - .containsExactly(key1, truncValue, key2, truncValue, key3, truncValue); + TagKey key = TagKey.createString("K"); + assertThat(newBuilder().set(key, value).build().getTags()).containsExactly(key, truncValue); } @Test public void testValueBadChar() { String value = "\2ab\3cd"; - TagKey key1 = TagKey.createString("K1"); - TagKey key2 = TagKey.createString("K2"); - TagKey key3 = TagKey.createString("K3"); + TagKey key = TagKey.createString("K"); String expected = StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + "ab" + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + "cd"; - assertThat( - newBuilder() - .insert(key1, value) - .set(key2, value) - .set(key3, "") // allow next line to update existing value - .update(key3, value) - .build() - .getTags()) - .containsExactly(key1, expected, key2, expected, key3, expected); + assertThat(newBuilder().set(key, value).build().getTags()).containsExactly(key, expected); } @SuppressWarnings({"unchecked", "rawtypes"}) private final TagKey badIntKey = (TagKey) TagKey.createString("Key"); - @Test(expected = IllegalArgumentException.class) - public void disallowInsertingWrongTypeOfKey() { - newBuilder().insert(badIntKey, 123); - } - @Test(expected = IllegalArgumentException.class) public void disallowSettingWrongTypeOfKey() { newBuilder().set(badIntKey, 123); } - @Test(expected = IllegalArgumentException.class) - public void disallowUpdatingWrongTypeOfKey() { - newBuilder().update(badIntKey, 123); - } - private static TagMap.Builder newBuilder() { return new TagMap.Builder(); } From 21636245b2da922a71675a9faf86f7d373a3914f Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 17 May 2017 18:06:42 -0700 Subject: [PATCH 0112/1581] Throw IllegalArgumentException when tag value is invalid. --- .../google/instrumentation/tags/TagMap.java | 3 +- .../instrumentation/tags/TagMapTest.java | 32 +++++++++++-------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagMap.java b/core/src/main/java/com/google/instrumentation/tags/TagMap.java index a56e41c121..55667d5880 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagMap.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagMap.java @@ -73,7 +73,8 @@ private Builder(Map, Object> tags) { */ public Builder set(TagKey key, String value) { Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); - return setInternal(key, StringUtil.sanitize(value)); + Preconditions.checkArgument(StringUtil.isValid(value)); + return setInternal(key, value); } /** diff --git a/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java b/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java index 9c5e206d37..d145b0cbd1 100644 --- a/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java +++ b/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java @@ -16,9 +16,10 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableMap; -import com.google.instrumentation.internal.StringUtil; import java.util.Arrays; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -27,6 +28,8 @@ @RunWith(JUnit4.class) public class TagMapTest { + @Rule public final ExpectedException thrown = ExpectedException.none(); + private static final TagKey KS1 = TagKey.createString("k1"); private static final TagKey KS2 = TagKey.createString("k2"); @@ -67,27 +70,30 @@ public void testClear() { } @Test - public void testValueMaxLength() { + public void allowStringTagValueWithMaxLength() { char[] chars = new char[TagMap.MAX_STRING_LENGTH]; - char[] truncChars = new char[TagMap.MAX_STRING_LENGTH + 10]; Arrays.fill(chars, 'v'); - Arrays.fill(truncChars, 'v'); String value = new String(chars); - String truncValue = new String(chars); TagKey key = TagKey.createString("K"); - assertThat(newBuilder().set(key, value).build().getTags()).containsExactly(key, truncValue); + newBuilder().set(key, value); + } + + @Test + public void disallowStringTagValueOverMaxLength() { + char[] chars = new char[TagMap.MAX_STRING_LENGTH + 1]; + Arrays.fill(chars, 'v'); + String value = new String(chars); + TagKey key = TagKey.createString("K"); + thrown.expect(IllegalArgumentException.class); + newBuilder().set(key, value); } @Test - public void testValueBadChar() { + public void disallowStringTagValueWithUnprintableChars() { String value = "\2ab\3cd"; TagKey key = TagKey.createString("K"); - String expected = - StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE - + "ab" - + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE - + "cd"; - assertThat(newBuilder().set(key, value).build().getTags()).containsExactly(key, expected); + thrown.expect(IllegalArgumentException.class); + newBuilder().set(key, value); } @SuppressWarnings({"unchecked", "rawtypes"}) From 7e357e1ee7eea74ce5855d657525eaac08dd469d Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 18 May 2017 17:29:43 -0700 Subject: [PATCH 0113/1581] Add messages to argument checks in DistributionAggregation.create(...). --- .../instrumentation/stats/DistributionAggregation.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java b/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java index a6aeaa475d..397679370a 100644 --- a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java +++ b/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java @@ -77,9 +77,11 @@ public static DistributionAggregation create( private static DistributionAggregation createInternal( long count, double mean, double sum, Range range, List tags, List bucketCounts) { - Preconditions.checkArgument(count >= 0); - Preconditions.checkArgument(count != 0 || mean == 0); - Preconditions.checkArgument(count != 0 || sum == 0); + Preconditions.checkArgument(count >= 0, "Count must be non-negative."); + if (count == 0) { + Preconditions.checkArgument(mean == 0, "Mean must be 0 when the count is 0."); + Preconditions.checkArgument(sum == 0, "Sum must be 0 when the count is 0."); + } return new AutoValue_DistributionAggregation(count, mean, sum, range, tags, bucketCounts); } From f11ceb87e7b543ef86b3a619718ba4327400800b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 18 May 2017 18:02:37 -0700 Subject: [PATCH 0114/1581] Update Travis build status link for census-instrumentation organization. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f9d18631b..6703abae8a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Instrumentation - A stats collection framework ====================================================== -[![Build Status](https://travis-ci.org/google/instrumentation-java.svg?branch=master)](https://travis-ci.org/google/instrumentation-java) [![Build status](https://ci.appveyor.com/api/projects/status/w6sjnfpcp8s5l1s1/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/instrumentation-java/branch/master) +[![Build Status](https://travis-ci.org/census-instrumentation/instrumentation-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/instrumentation-java) [![Build status](https://ci.appveyor.com/api/projects/status/w6sjnfpcp8s5l1s1/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/instrumentation-java/branch/master) Instrumentation provides a framework to define and collect stats against metrics and to break those stats down across user-defined dimensions. From 4bcda7c5145f6c624b57104aaed191b93f86806a Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 19 May 2017 11:40:48 -0700 Subject: [PATCH 0115/1581] Update Appveyor build status link for census-instrumentation organization. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6703abae8a..cdd290da4e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Instrumentation - A stats collection framework ====================================================== -[![Build Status](https://travis-ci.org/census-instrumentation/instrumentation-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/instrumentation-java) [![Build status](https://ci.appveyor.com/api/projects/status/w6sjnfpcp8s5l1s1/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/instrumentation-java/branch/master) +[![Build Status](https://travis-ci.org/census-instrumentation/instrumentation-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/instrumentation-java) [![Build status](https://ci.appveyor.com/api/projects/status/v5dbthkucuewsu33/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/instrumentation-java/branch/master) Instrumentation provides a framework to define and collect stats against metrics and to break those stats down across user-defined dimensions. From 2d2badc38f045bcf3500745f8a5f8e194aab0b96 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Mon, 15 May 2017 13:32:59 -0700 Subject: [PATCH 0116/1581] Add probability-based sampler to API --- .../instrumentation/trace/Samplers.java | 77 +++++++++++++++++++ .../google/instrumentation/trace/TraceId.java | 14 ++++ .../instrumentation/trace/SamplersTest.java | 71 +++++++++++++++++ 3 files changed, 162 insertions(+) diff --git a/core/src/main/java/com/google/instrumentation/trace/Samplers.java b/core/src/main/java/com/google/instrumentation/trace/Samplers.java index fe89755ffe..296442af00 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Samplers.java +++ b/core/src/main/java/com/google/instrumentation/trace/Samplers.java @@ -13,6 +13,9 @@ package com.google.instrumentation.trace; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + import java.util.List; import javax.annotation.Nullable; @@ -42,6 +45,17 @@ public static Sampler neverSample() { return NEVER_SAMPLE; } + /** + * Returns a {@link Sampler} that makes a "yes" decision with a given probability. + * + * @param probability The desired probability of sampling. Must be within [0.0, 1.0]. + * @return a {@code Sampler} that makes a "yes" decision with a given probability. + * @throws IllegalArgumentException if {@code probability} is out of range + */ + public static Sampler probabilitySampler(double probability) { + return new ProbabilitySampler(probability); + } + private static final class AlwaysSampleSampler extends Sampler { private AlwaysSampleSampler() {} @@ -83,4 +97,67 @@ public String toString() { return "NeverSampleSampler"; } } + + private static final class ProbabilitySampler extends Sampler { + // We assume the lower 64 bits of the traceId's are randomly distributed around the whole (long) + // range. We convert an incoming probability into an upper bound on that value, such that we can + // just compare the absolute value of the id and the bound to see if we are within the desired + // probability range. Using the low bits of the traceId also ensures that systems that only use + // 64 bit ID's will also work with this sampler. + private final long idUpperBound; + private final double probability; + + /** + * Create a new {@link ProbabilitySampler}. The probability of sampling a trace is equal to that + * of the specified probability. + * + * @param probability The desired probability of sampling. Must be within [0.0, 1.0]. + * @throws IllegalArgumentException if {@code probability} is out of range + */ + private ProbabilitySampler(double probability) { + checkArgument( + probability >= 0.0 && probability <= 1.0, "probability must be in range [0.0, 1.0]"); + this.probability = probability; + // Special case the limits, to avoid any possible issues with lack of precision across + // double/long boundaries. For probability == 0.0, we use Long.MIN_VALUE as this guarantees + // that we will never sample a trace, even in the case where the id == Long.MIN_VALUE, since + // Math.Abs(Long.MIN_VALUE) == Long.MIN_VALUE. + if (probability == 0.0) { + idUpperBound = Long.MIN_VALUE; + } else if (probability == 1.0) { + idUpperBound = Long.MAX_VALUE; + } else { + idUpperBound = (long) (probability * Long.MAX_VALUE); + } + } + + @Override + protected boolean shouldSample( + @Nullable SpanContext parentContext, + boolean remoteParent, + TraceId traceId, + SpanId spanId, + String name, + @Nullable List parentLinks) { + checkNotNull(traceId, "traceId"); + checkNotNull(name, "name"); + // Always enable sampling if parent was sampled. + if (parentContext != null && parentContext.getTraceOptions().isSampled()) { + return true; + } + // Always sample if we are within probability range. This is true even for child spans (that + // may have had a different sampling decision made) to allow for different sampling policies, + // and dynamic increases to sampling probabilities for debugging purposes. + // Note use of '<' for comparison. This ensures that we never sample for probability == 0.0, + // while allowing for a (very) small chance of *not* sampling if the id == Long.MAX_VALUE. + // This is considered a reasonable tradeoff for the simplicity/performance requirements (this + // code is executed in-line for every Span creation). + return Math.abs(traceId.getLowerLong()) < idUpperBound; + } + + @Override + public String toString() { + return String.format("ProbabilitySampler(%f)", probability); + } + } } diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceId.java b/core/src/main/java/com/google/instrumentation/trace/TraceId.java index 9a68be4331..ab3c2d52ee 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceId.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceId.java @@ -133,6 +133,20 @@ public boolean isValid() { return !Arrays.equals(bytes, INVALID.bytes); } + // Return the lower 8 bytes of the trace-id as a long value, assuming little-endian order. This + // is used in ProbabilitySampler. + long getLowerLong() { + long result = 0; + for (int i = 0; i < Long.SIZE / Byte.SIZE; i++) { + result <<= Byte.SIZE; + result |= (bytes[i] & 0xff); + } + if (result < 0) { + return -result; + } + return result; + } + @Override public boolean equals(Object obj) { if (obj == this) { diff --git a/core/src/test/java/com/google/instrumentation/trace/SamplersTest.java b/core/src/test/java/com/google/instrumentation/trace/SamplersTest.java index db8aa041b1..887b17647b 100644 --- a/core/src/test/java/com/google/instrumentation/trace/SamplersTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/SamplersTest.java @@ -94,4 +94,75 @@ public void neverSampleSampler_AlwaysReturnFalse() { public void neverSampleSampler_ToString() { assertThat(Samplers.neverSample().toString()).isEqualTo("NeverSampleSampler"); } + + @Test(expected = IllegalArgumentException.class) + public void probabilitySampler_outOfRangeHighProbability() { + Samplers.probabilitySampler(1.01); + } + + @Test(expected = IllegalArgumentException.class) + public void probabilitySampler_outOfRangeLowProbability() { + Samplers.probabilitySampler(-0.00001); + } + + private final void probabilitySampler_AlwaysReturnTrueForSampled(Sampler sampler) { + final int numSamples = 100; // Number of traces for which to generate sampling decisions. + for (int i = 0; i < numSamples; i++) { + assertThat( + sampler.shouldSample( + sampledSpanContext, + false, + TraceId.generateRandomId(random), + spanId, + "bar", + Collections.emptyList())) + .isTrue(); + } + } + + private final void probabilitySampler_SamplesWithProbabilityForUnsampled( + Sampler sampler, double probability) { + final int numSamples = 1000; // Number of traces for which to generate sampling decisions. + int count = 0; // Count of spans with sampling enabled + for (int i = 0; i < numSamples; i++) { + if (sampler.shouldSample( + notSampledSpanContext, + false, + TraceId.generateRandomId(random), + spanId, + "bar", + Collections.emptyList())) { + count++; + } + } + double proportionSampled = (double) count / numSamples; + // Allow for a large amount of slop (+/- 10%) in number of sampled traces, to avoid flakiness. + assertThat(proportionSampled < probability + 0.1 && proportionSampled > probability - 0.1) + .isTrue(); + } + + @Test + public void probabilitySamper_SamplesWithProbability() { + final Sampler neverSample = Samplers.probabilitySampler(0.0); + probabilitySampler_AlwaysReturnTrueForSampled(neverSample); + probabilitySampler_SamplesWithProbabilityForUnsampled(neverSample, 0.0); + final Sampler alwaysSample = Samplers.probabilitySampler(1.0); + probabilitySampler_AlwaysReturnTrueForSampled(alwaysSample); + probabilitySampler_SamplesWithProbabilityForUnsampled(alwaysSample, 1.0); + final Sampler fiftyPercentSample = Samplers.probabilitySampler(0.5); + probabilitySampler_AlwaysReturnTrueForSampled(fiftyPercentSample); + probabilitySampler_SamplesWithProbabilityForUnsampled(fiftyPercentSample, 0.5); + final Sampler twentyPercentSample = Samplers.probabilitySampler(0.2); + probabilitySampler_AlwaysReturnTrueForSampled(twentyPercentSample); + probabilitySampler_SamplesWithProbabilityForUnsampled(twentyPercentSample, 0.2); + final Sampler twoThirdsSample = Samplers.probabilitySampler(2.0 / 3.0); + probabilitySampler_AlwaysReturnTrueForSampled(twoThirdsSample); + probabilitySampler_SamplesWithProbabilityForUnsampled(twoThirdsSample, 2.0 / 3.0); + } + + @Test + public void probabilitySampler_ToString() { + assertThat((Samplers.probabilitySampler(0.5)).toString()) + .isEqualTo("ProbabilitySampler(0.500000)"); + } } From aea8ffec7c861bd68cdc04931b37942de14c364d Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 23 May 2017 20:16:35 -0700 Subject: [PATCH 0117/1581] Change the default sampler. (#319) * Make the probability sampler with a default probability of 1/10000 the default sampler for instrumentation library. * Change to use AutoValue for the probability and idUpperBound to avoid overwriting equals and hashCode. --- .../instrumentation/trace/Samplers.java | 49 ++++++++++--------- .../instrumentation/trace/SpanData.java | 8 +-- .../instrumentation/trace/TraceConfig.java | 8 ++- .../instrumentation/trace/SamplersTest.java | 2 +- .../trace/TraceParamsTest.java | 2 +- 5 files changed, 33 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/trace/Samplers.java b/core/src/main/java/com/google/instrumentation/trace/Samplers.java index 296442af00..59b637f512 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Samplers.java +++ b/core/src/main/java/com/google/instrumentation/trace/Samplers.java @@ -14,10 +14,11 @@ package com.google.instrumentation.trace; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; +import com.google.auto.value.AutoValue; import java.util.List; import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; /** Static class to access a set of pre-defined {@link Sampler Samplers}. */ public final class Samplers { @@ -53,9 +54,10 @@ public static Sampler neverSample() { * @throws IllegalArgumentException if {@code probability} is out of range */ public static Sampler probabilitySampler(double probability) { - return new ProbabilitySampler(probability); + return ProbabilitySampler.create(probability); } + @Immutable private static final class AlwaysSampleSampler extends Sampler { private AlwaysSampleSampler() {} @@ -77,6 +79,7 @@ public String toString() { } } + @Immutable private static final class NeverSampleSampler extends Sampler { private NeverSampleSampler() {} @@ -98,26 +101,32 @@ public String toString() { } } - private static final class ProbabilitySampler extends Sampler { - // We assume the lower 64 bits of the traceId's are randomly distributed around the whole (long) - // range. We convert an incoming probability into an upper bound on that value, such that we can - // just compare the absolute value of the id and the bound to see if we are within the desired - // probability range. Using the low bits of the traceId also ensures that systems that only use - // 64 bit ID's will also work with this sampler. - private final long idUpperBound; - private final double probability; + // We assume the lower 64 bits of the traceId's are randomly distributed around the whole (long) + // range. We convert an incoming probability into an upper bound on that value, such that we can + // just compare the absolute value of the id and the bound to see if we are within the desired + // probability range. Using the low bits of the traceId also ensures that systems that only use + // 64 bit ID's will also work with this sampler. + @AutoValue + @Immutable + abstract static class ProbabilitySampler extends Sampler { + ProbabilitySampler() {} + + abstract double getProbability(); + + abstract long getIdUpperBound(); /** - * Create a new {@link ProbabilitySampler}. The probability of sampling a trace is equal to that - * of the specified probability. + * Returns a new {@link ProbabilitySampler}. The probability of sampling a trace is equal to + * that of the specified probability. * * @param probability The desired probability of sampling. Must be within [0.0, 1.0]. + * @return a new {@link ProbabilitySampler}. * @throws IllegalArgumentException if {@code probability} is out of range */ - private ProbabilitySampler(double probability) { + private static ProbabilitySampler create(double probability) { checkArgument( probability >= 0.0 && probability <= 1.0, "probability must be in range [0.0, 1.0]"); - this.probability = probability; + long idUpperBound = 0; // Special case the limits, to avoid any possible issues with lack of precision across // double/long boundaries. For probability == 0.0, we use Long.MIN_VALUE as this guarantees // that we will never sample a trace, even in the case where the id == Long.MIN_VALUE, since @@ -129,18 +138,17 @@ private ProbabilitySampler(double probability) { } else { idUpperBound = (long) (probability * Long.MAX_VALUE); } + return new AutoValue_Samplers_ProbabilitySampler(probability, idUpperBound); } @Override - protected boolean shouldSample( + protected final boolean shouldSample( @Nullable SpanContext parentContext, boolean remoteParent, TraceId traceId, SpanId spanId, String name, @Nullable List parentLinks) { - checkNotNull(traceId, "traceId"); - checkNotNull(name, "name"); // Always enable sampling if parent was sampled. if (parentContext != null && parentContext.getTraceOptions().isSampled()) { return true; @@ -152,12 +160,7 @@ protected boolean shouldSample( // while allowing for a (very) small chance of *not* sampling if the id == Long.MAX_VALUE. // This is considered a reasonable tradeoff for the simplicity/performance requirements (this // code is executed in-line for every Span creation). - return Math.abs(traceId.getLowerLong()) < idUpperBound; - } - - @Override - public String toString() { - return String.format("ProbabilitySampler(%f)", probability); + return Math.abs(traceId.getLowerLong()) < getIdUpperBound(); } } } diff --git a/core/src/main/java/com/google/instrumentation/trace/SpanData.java b/core/src/main/java/com/google/instrumentation/trace/SpanData.java index 296870787d..8435709c3d 100644 --- a/core/src/main/java/com/google/instrumentation/trace/SpanData.java +++ b/core/src/main/java/com/google/instrumentation/trace/SpanData.java @@ -234,9 +234,7 @@ public static TimedEvents create(List> events, int droppedE TimedEvents() {} } - /** - * A set of attributes and the number of dropped attributes representation. - */ + /** A set of attributes and the number of dropped attributes representation. */ @Immutable @AutoValue public abstract static class Attributes { @@ -274,9 +272,7 @@ public static Attributes create( Attributes() {} } - /** - * A list of links and the number of dropped links representation. - */ + /** A list of links and the number of dropped links representation. */ @Immutable @AutoValue public abstract static class Links { diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java b/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java index 34b64b3605..de3177b187 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java @@ -62,8 +62,8 @@ static TraceConfig getNoopTraceConfig() { @Immutable public abstract static class TraceParams { // These values are the default values for all the global parameters. - // TODO(aveitch): Change this when a rate/probability sampler is available. - private static final Sampler DEFAULT_SAMPLER = Samplers.neverSample(); + private static final double DEFAULT_PROBABILITY = 1e-4; + private static final Sampler DEFAULT_SAMPLER = Samplers.probabilitySampler(DEFAULT_PROBABILITY); private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES = 32; private static final int DEFAULT_SPAN_MAX_NUM_ANNOTATIONS = 32; private static final int DEFAULT_SPAN_MAX_NUM_NETWORK_EVENTS = 128; @@ -125,9 +125,7 @@ private static Builder builder() { */ public abstract Builder toBuilder(); - /** - * A {@code Builder} class for {@link TraceParams}. - */ + /** A {@code Builder} class for {@link TraceParams}. */ @AutoValue.Builder public abstract static class Builder { diff --git a/core/src/test/java/com/google/instrumentation/trace/SamplersTest.java b/core/src/test/java/com/google/instrumentation/trace/SamplersTest.java index 887b17647b..aa361ef8ba 100644 --- a/core/src/test/java/com/google/instrumentation/trace/SamplersTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/SamplersTest.java @@ -163,6 +163,6 @@ public void probabilitySamper_SamplesWithProbability() { @Test public void probabilitySampler_ToString() { assertThat((Samplers.probabilitySampler(0.5)).toString()) - .isEqualTo("ProbabilitySampler(0.500000)"); + .contains("0.5"); } } diff --git a/core/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java b/core/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java index c939fc7338..52e6aecc8e 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java +++ b/core/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java @@ -25,7 +25,7 @@ public class TraceParamsTest { @Test public void defaultTraceParams() { - assertThat(TraceParams.DEFAULT.getSampler()).isEqualTo(Samplers.neverSample()); + assertThat(TraceParams.DEFAULT.getSampler()).isEqualTo(Samplers.probabilitySampler(1e-4)); assertThat(TraceParams.DEFAULT.getMaxNumberOfAttributes()).isEqualTo(32); assertThat(TraceParams.DEFAULT.getMaxNumberOfAnnotations()).isEqualTo(32); assertThat(TraceParams.DEFAULT.getMaxNumberOfNetworkEvents()).isEqualTo(128); From 6e8e39047eba9d545a193a8c23e150eded66ccdf Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 24 May 2017 14:07:59 -0700 Subject: [PATCH 0118/1581] Capitalize ASCII in comments. --- .../main/java/com/google/instrumentation/tags/TagKey.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagKey.java b/core/src/main/java/com/google/instrumentation/tags/TagKey.java index d1bc6cda87..0a52c26737 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagKey.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagKey.java @@ -48,7 +48,7 @@ enum TagType { * *

    *
  1. It cannot be longer than {@link #MAX_LENGTH}. - *
  2. It can only contain printable ascii characters. + *
  3. It can only contain printable ASCII characters. *
* * @param name the name of the key. @@ -74,7 +74,7 @@ private static TagKey createStringInternal(String name) { * *
    *
  1. It cannot be longer than {@link #MAX_LENGTH}. - *
  2. It can only contain printable ascii characters. + *
  3. It can only contain printable ASCII characters. *
* * @param name the name of the key. @@ -100,7 +100,7 @@ private static TagKey createIntInternal(String name) { * *
    *
  1. It cannot be longer than {@link #MAX_LENGTH}. - *
  2. It can only contain printable ascii characters. + *
  3. It can only contain printable ASCII characters. *
* * @param name the name of the key. From 223ec0781052fe23c56abc2747366b2f3087d685 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 24 May 2017 14:09:15 -0700 Subject: [PATCH 0119/1581] Remove methods for sanitizing tag key names. --- .../google/instrumentation/tags/TagKey.java | 15 ------------- .../instrumentation/tags/TagKeyTest.java | 22 ------------------- 2 files changed, 37 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagKey.java b/core/src/main/java/com/google/instrumentation/tags/TagKey.java index 0a52c26737..dd5615d5d8 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagKey.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagKey.java @@ -59,11 +59,6 @@ public static TagKey createString(String name) { return createStringInternal(name); } - // Creates a TagKey by sanitizing the given String. - static TagKey createStringSanitized(String name) { - return createStringInternal(StringUtil.sanitize(name)); - } - private static TagKey createStringInternal(String name) { return new AutoValue_TagKey(name, TAG_STRING); } @@ -85,11 +80,6 @@ public static TagKey createInt(String name) { return createIntInternal(name); } - // Creates a TagKey by sanitizing the given String. - static TagKey createIntSanitized(String name) { - return createIntInternal(StringUtil.sanitize(name)); - } - private static TagKey createIntInternal(String name) { return new AutoValue_TagKey(name, TAG_INT); } @@ -111,11 +101,6 @@ public static TagKey createBool(String name) { return createBoolInternal(name); } - // Creates a TagKey by sanitizing the given String. - static TagKey createBoolSanitized(String name) { - return createBoolInternal(StringUtil.sanitize(name)); - } - private static TagKey createBoolInternal(String name) { return new AutoValue_TagKey(name, TAG_BOOL); } diff --git a/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java b/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java index 5ae0d920d7..9aee5b3dc2 100644 --- a/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java +++ b/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java @@ -16,7 +16,6 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import com.google.instrumentation.internal.StringUtil; import java.util.Arrays; import org.junit.Rule; import org.junit.Test; @@ -50,33 +49,12 @@ public void createString_DisallowTagKeyNameOverMaxLength() { TagKey.createString(new String(key)); } - @Test - public void createStringSanitized_TruncateLongKey() { - char[] key = new char[TagKey.MAX_LENGTH]; - char[] truncKey = new char[TagKey.MAX_LENGTH + 1]; - Arrays.fill(key, 'k'); - Arrays.fill(truncKey, 'k'); - assertThat(TagKey.createStringSanitized(new String(truncKey)).getName()) - .isEqualTo(new String(key)); - } - @Test public void createString_DisallowUnprintableChars() { thrown.expect(IllegalArgumentException.class); TagKey.createString("\2ab\3cd"); } - @Test - public void createStringSanitized_SubstituteUnprintableChars() { - String key = "\2ab\3cd"; - assertThat(TagKey.createStringSanitized(key).getName()) - .isEqualTo( - StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE - + "ab" - + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE - + "cd"); - } - @Test public void testTagKeyEquals() { new EqualsTester() From d642c29f2b3a937bc950713cfee6aef782706302 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 24 May 2017 14:17:24 -0700 Subject: [PATCH 0120/1581] Rename "Int" tag key type to "Long" for consistency with Java types. --- .../java/com/google/instrumentation/tags/TagKey.java | 12 ++++++------ .../java/com/google/instrumentation/tags/TagMap.java | 2 +- .../com/google/instrumentation/tags/TagKeyTest.java | 2 +- .../com/google/instrumentation/tags/TagMapTest.java | 10 +++++----- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagKey.java b/core/src/main/java/com/google/instrumentation/tags/TagKey.java index dd5615d5d8..0cd708da5f 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagKey.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagKey.java @@ -14,7 +14,7 @@ package com.google.instrumentation.tags; import static com.google.instrumentation.tags.TagKey.TagType.TAG_BOOL; -import static com.google.instrumentation.tags.TagKey.TagType.TAG_INT; +import static com.google.instrumentation.tags.TagKey.TagType.TAG_LONG; import static com.google.instrumentation.tags.TagKey.TagType.TAG_STRING; import com.google.auto.value.AutoValue; @@ -36,7 +36,7 @@ public abstract class TagKey { enum TagType { TAG_STRING, - TAG_INT, + TAG_LONG, TAG_BOOL } @@ -75,13 +75,13 @@ private static TagKey createStringInternal(String name) { * @param name the name of the key. * @throws IllegalArgumentException if the name is not valid. */ - public static TagKey createInt(String name) { + public static TagKey createLong(String name) { Preconditions.checkArgument(StringUtil.isValid(name)); - return createIntInternal(name); + return createLongInternal(name); } - private static TagKey createIntInternal(String name) { - return new AutoValue_TagKey(name, TAG_INT); + private static TagKey createLongInternal(String name) { + return new AutoValue_TagKey(name, TAG_LONG); } /** diff --git a/core/src/main/java/com/google/instrumentation/tags/TagMap.java b/core/src/main/java/com/google/instrumentation/tags/TagMap.java index 55667d5880..b4a86bbf75 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagMap.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagMap.java @@ -85,7 +85,7 @@ public Builder set(TagKey key, String value) { * @return this */ public Builder set(TagKey key, long value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_INT); + Preconditions.checkArgument(key.getTagType() == TagType.TAG_LONG); return setInternal(key, value); } diff --git a/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java b/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java index 9aee5b3dc2..ecdb008183 100644 --- a/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java +++ b/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java @@ -59,7 +59,7 @@ public void createString_DisallowUnprintableChars() { public void testTagKeyEquals() { new EqualsTester() .addEqualityGroup(TagKey.createString("foo"), TagKey.createString("foo")) - .addEqualityGroup(TagKey.createInt("foo")) + .addEqualityGroup(TagKey.createLong("foo")) .addEqualityGroup(TagKey.createBool("foo")) .addEqualityGroup(TagKey.createString("bar")) .testEquals(); diff --git a/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java b/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java index d145b0cbd1..e6440185f7 100644 --- a/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java +++ b/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java @@ -42,16 +42,16 @@ public void applyBuilderOperationsInOrder() { @Test public void allowMutlipleKeysWithSameNameButDifferentTypes() { TagKey stringKey = TagKey.createString("key"); - TagKey intKey = TagKey.createInt("key"); + TagKey longKey = TagKey.createLong("key"); TagKey boolKey = TagKey.createBool("key"); assertThat( newBuilder() .set(stringKey, "value") - .set(intKey, 123) + .set(longKey, 123) .set(boolKey, true) .build() .getTags()) - .containsExactly(stringKey, "value", intKey, 123L, boolKey, true); + .containsExactly(stringKey, "value", longKey, 123L, boolKey, true); } @Test @@ -97,11 +97,11 @@ public void disallowStringTagValueWithUnprintableChars() { } @SuppressWarnings({"unchecked", "rawtypes"}) - private final TagKey badIntKey = (TagKey) TagKey.createString("Key"); + private final TagKey badLongKey = (TagKey) TagKey.createString("Key"); @Test(expected = IllegalArgumentException.class) public void disallowSettingWrongTypeOfKey() { - newBuilder().set(badIntKey, 123); + newBuilder().set(badLongKey, 123); } private static TagMap.Builder newBuilder() { From d0c1e4ca96a3f743dac151a586b44c4be7d28538 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 24 May 2017 14:19:28 -0700 Subject: [PATCH 0121/1581] Reword Javadocs. --- .../main/java/com/google/instrumentation/tags/TagMap.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagMap.java b/core/src/main/java/com/google/instrumentation/tags/TagMap.java index b4a86bbf75..96b56f7d75 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagMap.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagMap.java @@ -67,7 +67,7 @@ private Builder(Map, Object> tags) { /** * Adds the key/value pair regardless of whether the key is present. * - * @param key the key to look up. + * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this */ @@ -80,7 +80,7 @@ public Builder set(TagKey key, String value) { /** * Adds the key/value pair regardless of whether the key is present. * - * @param key the key to look up. + * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this */ @@ -92,7 +92,7 @@ public Builder set(TagKey key, long value) { /** * Adds the key/value pair regardless of whether the key is present. * - * @param key the key to look up. + * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this */ @@ -109,7 +109,7 @@ private Builder setInternal(TagKey key, TagValueT value) /** * Removes the key if it exists. * - * @param key the key to look up. + * @param key the {@code TagKey} which will be cleared. * @return this */ public Builder clear(TagKey key) { From c5dd310534c14958b3da87bda79427dd93786b02 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 24 May 2017 14:21:10 -0700 Subject: [PATCH 0122/1581] Add a TODO about tag value class. --- core/src/main/java/com/google/instrumentation/tags/TagMap.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagMap.java b/core/src/main/java/com/google/instrumentation/tags/TagMap.java index 96b56f7d75..2285d05546 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagMap.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagMap.java @@ -73,6 +73,9 @@ private Builder(Map, Object> tags) { */ public Builder set(TagKey key, String value) { Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); + + // TODO(sebright): Consider adding a TagValue class to avoid validating the String every time + // it is set. Preconditions.checkArgument(StringUtil.isValid(value)); return setInternal(key, value); } From 6fc72302860cdeb017ebdb376b5812ffd6255872 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 24 May 2017 14:26:21 -0700 Subject: [PATCH 0123/1581] Add @throws to Javadocs. --- .../main/java/com/google/instrumentation/tags/TagMap.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagMap.java b/core/src/main/java/com/google/instrumentation/tags/TagMap.java index 2285d05546..206053d2c4 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagMap.java +++ b/core/src/main/java/com/google/instrumentation/tags/TagMap.java @@ -70,6 +70,9 @@ private Builder(Map, Object> tags) { * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this + * @throws IllegalArgumentException if either argument is null, the key is the wrong type, or + * the value contains unprintable characters or is longer than {@link + * TagMap#MAX_STRING_LENGTH}. */ public Builder set(TagKey key, String value) { Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); @@ -86,6 +89,7 @@ public Builder set(TagKey key, String value) { * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this + * @throws IllegalArgumentException if the key is null or the key is the wrong type. */ public Builder set(TagKey key, long value) { Preconditions.checkArgument(key.getTagType() == TagType.TAG_LONG); @@ -98,6 +102,7 @@ public Builder set(TagKey key, long value) { * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this + * @throws IllegalArgumentException if the key is null or the key is the wrong type. */ public Builder set(TagKey key, boolean value) { Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); From 6799f003887e7fe98d33abb62f7ee6ddf1823496 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Wed, 24 May 2017 14:24:42 -0700 Subject: [PATCH 0124/1581] Fix Distribution TODOs --- .../stats/BucketBoundaries.java | 16 +++++----- .../instrumentation/stats/Distribution.java | 12 ++++---- .../stats/MutableDistribution.java | 29 +++++++++++++------ .../stats/BucketBoundariesTest.java | 6 ++-- .../stats/MutableDistributionTest.java | 9 ++++-- 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java b/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java index 317beb4df9..a6aec37ffb 100644 --- a/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java +++ b/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java @@ -33,17 +33,19 @@ public abstract class BucketBoundaries { * @param bucketBoundaries the boundaries for the buckets in the underlying {@link Distribution}. * @return a new {@code BucketBoundaries} with the specified boundaries. * @throws NullPointerException if {@code bucketBoundaries} is null. - * @throws IllegalArgumentException if {@code bucketBoundaries} is not sorted, or has zero length. + * @throws IllegalArgumentException if {@code bucketBoundaries} is not sorted. */ public static final BucketBoundaries create(List bucketBoundaries) { checkNotNull(bucketBoundaries, "bucketBoundaries list should not be null."); List bucketBoundariesCopy = new ArrayList(bucketBoundaries); // Deep copy. - checkArgument(!bucketBoundariesCopy.isEmpty(), "Zero length bucket boundaries"); - double lower = bucketBoundariesCopy.get(0); - for (int i = 1; i < bucketBoundariesCopy.size(); i++) { - double next = bucketBoundariesCopy.get(i); - checkArgument(lower < next, "Bucket boundaries not sorted."); - lower = next; + // Check if sorted. + if (bucketBoundariesCopy.size() > 1) { + double lower = bucketBoundariesCopy.get(0); + for (int i = 1; i < bucketBoundariesCopy.size(); i++) { + double next = bucketBoundariesCopy.get(i); + checkArgument(lower < next, "Bucket boundaries not sorted."); + lower = next; + } } return new AutoValue_BucketBoundaries(Collections.unmodifiableList(bucketBoundariesCopy)); } diff --git a/core/src/main/java/com/google/instrumentation/stats/Distribution.java b/core/src/main/java/com/google/instrumentation/stats/Distribution.java index 6dbea406c0..697c632d53 100644 --- a/core/src/main/java/com/google/instrumentation/stats/Distribution.java +++ b/core/src/main/java/com/google/instrumentation/stats/Distribution.java @@ -42,9 +42,10 @@ * underflow bucket. * *

Although not forbidden, it is generally a bad idea to include non-finite values (infinities or - * NaNs) in the population of values, as this will render the {@code mean} meaningless. + * NaNs) in the population of values, as this will render derived values (e.g. {@code mean}) + * meaningless. */ -// TODO(songya): needs to determine whether N = 1 is valid. (Currently we don't allow N = 1.) + @Immutable @AutoValue abstract class Distribution { @@ -94,7 +95,7 @@ final double getMean() { } /** - * The sum of the values in the population. If {@link #getCount()} is zero then this value must + * The sum of the values in the population. If {@link #getCount()} is zero then this value will * also be zero. * * @return The sum of values in the population. @@ -102,8 +103,8 @@ final double getMean() { abstract double getSum(); /** - * The range of the population values. If {@link #getCount()} is zero then this returned range is - * implementation-dependent. + * The range of the population values. If {@link #getCount()} is zero then the returned range + * will contain the "impossible" range [+Inf, -Inf]. * * @return The {code Range} representing the range of population values. */ @@ -141,7 +142,6 @@ final double getMean() { abstract List getBucketCounts(); /** Describes a range of population values. */ - // TODO(sebright): Decide what to do when the distribution contains no values. @Immutable @AutoValue abstract static class Range { diff --git a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java b/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java index 9aa0299f2a..c24dbcfaeb 100644 --- a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java +++ b/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java @@ -24,6 +24,7 @@ final class MutableDistribution { private long count = 0; // The number of values in the population. private double sum = 0.0; // The sum of the values in the population. + private double sumOfSquares = 0.0; // The sum of the sqaures of the values in the population private Range range = Range.create(); // Range of values in the population. @Nullable @@ -85,7 +86,7 @@ long getCount() { } /** - * The sum of the values in the population. If {@link #getCount()} is zero then this value must + * The sum of the values in the population. If {@link #getCount()} is zero then this value will * also be zero. * * @return The sum of values in the population. @@ -94,6 +95,16 @@ long getCount() { return sum; } + /** + * The sum of the squares of values in the population. If {@link #getCount()} is zero then this + * value will also be zero. + * + * @return The sum of squares of values in the population. + */ + double getSumSquares() { + return sumOfSquares; + } + /** * The range of the population values. If {@link #getCount()} is zero then this returned range is * implementation-dependent. @@ -157,6 +168,7 @@ private void putIntoBucket(double value) { void add(double value) { count++; sum += value; + sumOfSquares += value * value; range.add(value); if (hasBuckets()) { putIntoBucket(value); @@ -165,10 +177,9 @@ void add(double value) { /** Mutable version of {@code Distribution.Range}. */ static final class Range { - // Maintain the invariant that max should always be greater than or equal to min. - // TODO(songya): needs to determine how we would want to initialize min and max. - private Double min = null; - private Double max = null; + // Initial "impossible" values, that will get reset as soon as first value is added. + private double min = Double.POSITIVE_INFINITY; + private double max = Double.NEGATIVE_INFINITY; /** Construct a new, empty {@code Range}. */ static final Range create() { @@ -176,7 +187,7 @@ static final Range create() { } /** - * The minimum of the population values. Will throw an exception if min has not been set. + * The minimum of the population values. * * @return The minimum of the population values. */ @@ -185,7 +196,7 @@ static final Range create() { } /** - * The maximum of the population values. Will throw an exception if max has not been set. + * The maximum of the population values. * * @return The maximum of the population values. */ @@ -199,10 +210,10 @@ static final Range create() { * @param value the new value */ void add(double value) { - if (min == null || value < min) { + if (value < min) { min = value; } - if (max == null || value > max) { + if (value > max) { max = value; } } diff --git a/core/src/test/java/com/google/instrumentation/stats/BucketBoundariesTest.java b/core/src/test/java/com/google/instrumentation/stats/BucketBoundariesTest.java index 130009c5fd..7b6ed8e79a 100644 --- a/core/src/test/java/com/google/instrumentation/stats/BucketBoundariesTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/BucketBoundariesTest.java @@ -69,10 +69,10 @@ public void testUnsortedBoundaries() throws Exception { } @Test - public void testNoBoundaries() throws Exception { + public void testNoBoundaries() { List buckets = Arrays.asList(); - thrown.expect(IllegalArgumentException.class); - BucketBoundaries.create(buckets); + BucketBoundaries bucketBoundaries = BucketBoundaries.create(buckets); + assertThat(bucketBoundaries.getBoundaries()).isEqualTo(buckets); } @Test diff --git a/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java b/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java index c8bc164825..f64dbbfb7e 100644 --- a/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java @@ -36,6 +36,8 @@ public void testEmptyDistribution() { assertThat(empty.getCount()).isEqualTo(0); assertThat(empty.getSum()).isWithin(TOLERANCE).of(0.0); assertThat(empty.getMean()).isNaN(); + assertThat(empty.getRange().getMin()).isEqualTo(Double.POSITIVE_INFINITY); + assertThat(empty.getRange().getMax()).isEqualTo(Double.NEGATIVE_INFINITY); assertThat(empty.getBucketCounts()).isNull(); } @@ -66,10 +68,11 @@ public void testUnsortedBoundaries() throws Exception { } @Test - public void testNoBoundaries() throws Exception { + public void testNoBoundaries() { List buckets = Arrays.asList(); - thrown.expect(IllegalArgumentException.class); - MutableDistribution.create(BucketBoundaries.create(buckets)); + MutableDistribution noBoundaries = MutableDistribution.create(BucketBoundaries.create(buckets)); + assertThat(noBoundaries.getBucketCounts()).hasSize(1); + assertThat(noBoundaries.getBucketCounts().get(0)).isEqualTo(0); } @Test From 051b4e43daad67429fd049711d5d37e0a180056d Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Wed, 24 May 2017 16:36:03 -0700 Subject: [PATCH 0125/1581] remove extra getSumSquares --- .../instrumentation/stats/MutableDistribution.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java b/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java index c24dbcfaeb..0a291e6d03 100644 --- a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java +++ b/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java @@ -95,16 +95,6 @@ long getCount() { return sum; } - /** - * The sum of the squares of values in the population. If {@link #getCount()} is zero then this - * value will also be zero. - * - * @return The sum of squares of values in the population. - */ - double getSumSquares() { - return sumOfSquares; - } - /** * The range of the population values. If {@link #getCount()} is zero then this returned range is * implementation-dependent. From 0023373ecb034012bc3698284c43a9ccb3899d45 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Wed, 24 May 2017 16:47:26 -0700 Subject: [PATCH 0126/1581] more removal... --- .../com/google/instrumentation/stats/MutableDistribution.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java b/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java index 0a291e6d03..7492ef9ce2 100644 --- a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java +++ b/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java @@ -24,7 +24,6 @@ final class MutableDistribution { private long count = 0; // The number of values in the population. private double sum = 0.0; // The sum of the values in the population. - private double sumOfSquares = 0.0; // The sum of the sqaures of the values in the population private Range range = Range.create(); // Range of values in the population. @Nullable @@ -158,7 +157,6 @@ private void putIntoBucket(double value) { void add(double value) { count++; sum += value; - sumOfSquares += value * value; range.add(value); if (hasBuckets()) { putIntoBucket(value); From 0b0cf36ab83a500da0e04305762aa71e1fe4674e Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 24 May 2017 17:14:23 -0700 Subject: [PATCH 0127/1581] Rename tags package to io.opencensus.tags. --- .../instrumentation => io/opencensus}/tags/TagKey.java | 8 ++++---- .../instrumentation => io/opencensus}/tags/TagMap.java | 4 ++-- .../opencensus}/tags/TagKeyTest.java | 2 +- .../opencensus}/tags/TagMapTest.java | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/tags/TagKey.java (92%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/tags/TagMap.java (97%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/tags/TagKeyTest.java (98%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/tags/TagMapTest.java (98%) diff --git a/core/src/main/java/com/google/instrumentation/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java similarity index 92% rename from core/src/main/java/com/google/instrumentation/tags/TagKey.java rename to core/src/main/java/io/opencensus/tags/TagKey.java index 0cd708da5f..f7297d29de 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.tags; +package io.opencensus.tags; -import static com.google.instrumentation.tags.TagKey.TagType.TAG_BOOL; -import static com.google.instrumentation.tags.TagKey.TagType.TAG_LONG; -import static com.google.instrumentation.tags.TagKey.TagType.TAG_STRING; +import static io.opencensus.tags.TagKey.TagType.TAG_BOOL; +import static io.opencensus.tags.TagKey.TagType.TAG_LONG; +import static io.opencensus.tags.TagKey.TagType.TAG_STRING; import com.google.auto.value.AutoValue; import com.google.common.base.Preconditions; diff --git a/core/src/main/java/com/google/instrumentation/tags/TagMap.java b/core/src/main/java/io/opencensus/tags/TagMap.java similarity index 97% rename from core/src/main/java/com/google/instrumentation/tags/TagMap.java rename to core/src/main/java/io/opencensus/tags/TagMap.java index 206053d2c4..40eaec906b 100644 --- a/core/src/main/java/com/google/instrumentation/tags/TagMap.java +++ b/core/src/main/java/io/opencensus/tags/TagMap.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.tags; +package io.opencensus.tags; import com.google.common.base.Preconditions; import com.google.instrumentation.internal.StringUtil; -import com.google.instrumentation.tags.TagKey.TagType; +import io.opencensus.tags.TagKey.TagType; import java.util.HashMap; import java.util.Map; import javax.annotation.concurrent.Immutable; diff --git a/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java b/core/src/test/java/io/opencensus/tags/TagKeyTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java rename to core/src/test/java/io/opencensus/tags/TagKeyTest.java index ecdb008183..196e56b084 100644 --- a/core/src/test/java/com/google/instrumentation/tags/TagKeyTest.java +++ b/core/src/test/java/io/opencensus/tags/TagKeyTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.tags; +package io.opencensus.tags; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java b/core/src/test/java/io/opencensus/tags/TagMapTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/tags/TagMapTest.java rename to core/src/test/java/io/opencensus/tags/TagMapTest.java index e6440185f7..6b552f5d5f 100644 --- a/core/src/test/java/com/google/instrumentation/tags/TagMapTest.java +++ b/core/src/test/java/io/opencensus/tags/TagMapTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.tags; +package io.opencensus.tags; import static com.google.common.truth.Truth.assertThat; From 940ca8508c30b8ed12fa9f89d17fddd1a72451c7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 25 May 2017 12:44:22 -0700 Subject: [PATCH 0128/1581] Warn that the API is unstable in README.md. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cdd290da4e..dd7fb57ec1 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,5 @@ Instrumentation - A stats collection framework [![Build Status](https://travis-ci.org/census-instrumentation/instrumentation-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/instrumentation-java) [![Build status](https://ci.appveyor.com/api/projects/status/v5dbthkucuewsu33/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/instrumentation-java/branch/master) Instrumentation provides a framework to define and collect stats against metrics and to -break those stats down across user-defined dimensions. +break those stats down across user-defined dimensions. The library is in alpha +stage and the API is subject to change. From b410af7fd851a06f85b2faa878f2e31814f772c7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 25 May 2017 19:07:15 -0700 Subject: [PATCH 0129/1581] Rename "Bool" tag key type to "Boolean" for consistency with Java types. --- core/src/main/java/io/opencensus/tags/TagKey.java | 12 ++++++------ core/src/main/java/io/opencensus/tags/TagMap.java | 2 +- .../src/test/java/io/opencensus/tags/TagKeyTest.java | 2 +- .../src/test/java/io/opencensus/tags/TagMapTest.java | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index f7297d29de..c139580b00 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -13,7 +13,7 @@ package io.opencensus.tags; -import static io.opencensus.tags.TagKey.TagType.TAG_BOOL; +import static io.opencensus.tags.TagKey.TagType.TAG_BOOLEAN; import static io.opencensus.tags.TagKey.TagType.TAG_LONG; import static io.opencensus.tags.TagKey.TagType.TAG_STRING; @@ -37,7 +37,7 @@ public abstract class TagKey { enum TagType { TAG_STRING, TAG_LONG, - TAG_BOOL + TAG_BOOLEAN } TagKey() {} @@ -96,13 +96,13 @@ private static TagKey createLongInternal(String name) { * @param name the name of the key. * @throws IllegalArgumentException if the name is not valid. */ - public static TagKey createBool(String name) { + public static TagKey createBoolean(String name) { Preconditions.checkArgument(StringUtil.isValid(name)); - return createBoolInternal(name); + return createBooleanInternal(name); } - private static TagKey createBoolInternal(String name) { - return new AutoValue_TagKey(name, TAG_BOOL); + private static TagKey createBooleanInternal(String name) { + return new AutoValue_TagKey(name, TAG_BOOLEAN); } abstract String getName(); diff --git a/core/src/main/java/io/opencensus/tags/TagMap.java b/core/src/main/java/io/opencensus/tags/TagMap.java index 40eaec906b..28a3005106 100644 --- a/core/src/main/java/io/opencensus/tags/TagMap.java +++ b/core/src/main/java/io/opencensus/tags/TagMap.java @@ -105,7 +105,7 @@ public Builder set(TagKey key, long value) { * @throws IllegalArgumentException if the key is null or the key is the wrong type. */ public Builder set(TagKey key, boolean value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOL); + Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOLEAN); return setInternal(key, value); } diff --git a/core/src/test/java/io/opencensus/tags/TagKeyTest.java b/core/src/test/java/io/opencensus/tags/TagKeyTest.java index 196e56b084..05d6f6e7f2 100644 --- a/core/src/test/java/io/opencensus/tags/TagKeyTest.java +++ b/core/src/test/java/io/opencensus/tags/TagKeyTest.java @@ -60,7 +60,7 @@ public void testTagKeyEquals() { new EqualsTester() .addEqualityGroup(TagKey.createString("foo"), TagKey.createString("foo")) .addEqualityGroup(TagKey.createLong("foo")) - .addEqualityGroup(TagKey.createBool("foo")) + .addEqualityGroup(TagKey.createBoolean("foo")) .addEqualityGroup(TagKey.createString("bar")) .testEquals(); } diff --git a/core/src/test/java/io/opencensus/tags/TagMapTest.java b/core/src/test/java/io/opencensus/tags/TagMapTest.java index 6b552f5d5f..46afcbb10b 100644 --- a/core/src/test/java/io/opencensus/tags/TagMapTest.java +++ b/core/src/test/java/io/opencensus/tags/TagMapTest.java @@ -43,15 +43,15 @@ public void applyBuilderOperationsInOrder() { public void allowMutlipleKeysWithSameNameButDifferentTypes() { TagKey stringKey = TagKey.createString("key"); TagKey longKey = TagKey.createLong("key"); - TagKey boolKey = TagKey.createBool("key"); + TagKey booleanKey = TagKey.createBoolean("key"); assertThat( newBuilder() .set(stringKey, "value") .set(longKey, 123) - .set(boolKey, true) + .set(booleanKey, true) .build() .getTags()) - .containsExactly(stringKey, "value", longKey, 123L, boolKey, true); + .containsExactly(stringKey, "value", longKey, 123L, booleanKey, true); } @Test From a6b6815a304463d2f206967481d27ba5cd132656 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 26 May 2017 11:11:33 -0700 Subject: [PATCH 0130/1581] Exclude javadoc for internal package. (#324) * Exclude javadoc for internal package add Internal annotation to the internal package. * Add internal annotation in core_impl, move @Internal in common. --- all/build.gradle | 1 + core/build.gradle | 2 + .../instrumentation/common/Internal.java | 37 +++++++++++++++++++ .../internal/package-info.java | 21 +++++++++++ core_impl/build.gradle | 2 + .../internal/package-info.java | 21 +++++++++++ 6 files changed, 84 insertions(+) create mode 100644 core/src/main/java/com/google/instrumentation/common/Internal.java create mode 100644 core/src/main/java/com/google/instrumentation/internal/package-info.java create mode 100644 core_impl/src/main/java/com/google/instrumentation/internal/package-info.java diff --git a/all/build.gradle b/all/build.gradle index 550b924c13..e1acc77430 100644 --- a/all/build.gradle +++ b/all/build.gradle @@ -41,6 +41,7 @@ javadoc { source subproject.javadoc.source options.links subproject.javadoc.options.links.toArray(new String[0]) } + exclude 'com/google/instrumentation/internal/**' } task jacocoMerge(type: JacocoMerge) { diff --git a/core/build.gradle b/core/build.gradle index ec1b7c5978..2520ff4cb4 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -11,3 +11,5 @@ dependencies { signature "org.codehaus.mojo.signature:java16:+@signature" } + +javadoc.exclude 'com/google/instrumentation/internal/**' \ No newline at end of file diff --git a/core/src/main/java/com/google/instrumentation/common/Internal.java b/core/src/main/java/com/google/instrumentation/common/Internal.java new file mode 100644 index 0000000000..448c523573 --- /dev/null +++ b/core/src/main/java/com/google/instrumentation/common/Internal.java @@ -0,0 +1,37 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.instrumentation.common; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotates a program element (class, method, package etc) which is internal to opencensus, not + * part of the public API, and should not be used by users of the opencensus library. + */ +@Internal +@Retention(RetentionPolicy.SOURCE) +@Target({ + ElementType.ANNOTATION_TYPE, + ElementType.CONSTRUCTOR, + ElementType.FIELD, + ElementType.METHOD, + ElementType.PACKAGE, + ElementType.TYPE}) +@Documented +public @interface Internal { +} diff --git a/core/src/main/java/com/google/instrumentation/internal/package-info.java b/core/src/main/java/com/google/instrumentation/internal/package-info.java new file mode 100644 index 0000000000..849397059d --- /dev/null +++ b/core/src/main/java/com/google/instrumentation/internal/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Interfaces and implementations that are internal to opencensus. + * + *

All the content under this package and its subpackages are considered annotated with {@link + * com.google.instrumentation.common.Internal}. + */ +@com.google.instrumentation.common.Internal +package com.google.instrumentation.internal; diff --git a/core_impl/build.gradle b/core_impl/build.gradle index 558c091853..9db6338a2c 100644 --- a/core_impl/build.gradle +++ b/core_impl/build.gradle @@ -10,3 +10,5 @@ dependencies { signature "org.codehaus.mojo.signature:java16:+@signature" } + +javadoc.exclude 'com/google/instrumentation/internal/**' \ No newline at end of file diff --git a/core_impl/src/main/java/com/google/instrumentation/internal/package-info.java b/core_impl/src/main/java/com/google/instrumentation/internal/package-info.java new file mode 100644 index 0000000000..849397059d --- /dev/null +++ b/core_impl/src/main/java/com/google/instrumentation/internal/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Interfaces and implementations that are internal to opencensus. + * + *

All the content under this package and its subpackages are considered annotated with {@link + * com.google.instrumentation.common.Internal}. + */ +@com.google.instrumentation.common.Internal +package com.google.instrumentation.internal; From c2476655c12d9b2c729d0ce596cb60df3e13f7de Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 26 May 2017 11:21:47 -0700 Subject: [PATCH 0131/1581] Hide factory methods for creating TagKeys with types other than String. --- core/src/main/java/io/opencensus/tags/TagKey.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index c139580b00..4f8f569d7d 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -75,7 +75,8 @@ private static TagKey createStringInternal(String name) { * @param name the name of the key. * @throws IllegalArgumentException if the name is not valid. */ - public static TagKey createLong(String name) { + // TODO(sebright): Make this public once we support types other than String. + static TagKey createLong(String name) { Preconditions.checkArgument(StringUtil.isValid(name)); return createLongInternal(name); } @@ -96,7 +97,8 @@ private static TagKey createLongInternal(String name) { * @param name the name of the key. * @throws IllegalArgumentException if the name is not valid. */ - public static TagKey createBoolean(String name) { + // TODO(sebright): Make this public once we support types other than String. + static TagKey createBoolean(String name) { Preconditions.checkArgument(StringUtil.isValid(name)); return createBooleanInternal(name); } From 65e3122bddcb2bcba2ab38025a580142f85c818b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 26 May 2017 11:24:29 -0700 Subject: [PATCH 0132/1581] Reword TagKey Javadocs. --- core/src/main/java/io/opencensus/tags/TagKey.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index 4f8f569d7d..b5c6c75a13 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -43,8 +43,9 @@ enum TagType { TagKey() {} /** - * Constructs a {@code TagKey} from the given string. The string must meet the following - * requirements: + * Constructs a {@code TagKey} with the given name. + * + *

The string must meet the following requirements: * *

    *
  1. It cannot be longer than {@link #MAX_LENGTH}. @@ -64,8 +65,9 @@ private static TagKey createStringInternal(String name) { } /** - * Constructs a {@code TagKey} from the given string. The string must meet the following - * requirements: + * Constructs a {@code TagKey} with the given name. + * + *

    The string must meet the following requirements: * *

      *
    1. It cannot be longer than {@link #MAX_LENGTH}. @@ -86,8 +88,9 @@ private static TagKey createLongInternal(String name) { } /** - * Constructs a {@code TagKey} from the given string. The string must meet the following - * requirements: + * Constructs a {@code TagKey} with the given name. + * + *

      The string must meet the following requirements: * *

        *
      1. It cannot be longer than {@link #MAX_LENGTH}. From bba584f93d8398998242a9f174cd62d2de5851e4 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 26 May 2017 11:30:07 -0700 Subject: [PATCH 0133/1581] Rename TagKey factory methods. --- .../main/java/io/opencensus/tags/TagKey.java | 18 +++++++++--------- .../java/io/opencensus/tags/TagKeyTest.java | 16 ++++++++-------- .../java/io/opencensus/tags/TagMapTest.java | 18 +++++++++--------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index b5c6c75a13..c7e39fbe49 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -55,12 +55,12 @@ enum TagType { * @param name the name of the key. * @throws IllegalArgumentException if the name is not valid. */ - public static TagKey createString(String name) { + public static TagKey createStringKey(String name) { Preconditions.checkArgument(StringUtil.isValid(name)); - return createStringInternal(name); + return createStringKeyInternal(name); } - private static TagKey createStringInternal(String name) { + private static TagKey createStringKeyInternal(String name) { return new AutoValue_TagKey(name, TAG_STRING); } @@ -78,12 +78,12 @@ private static TagKey createStringInternal(String name) { * @throws IllegalArgumentException if the name is not valid. */ // TODO(sebright): Make this public once we support types other than String. - static TagKey createLong(String name) { + static TagKey createLongKey(String name) { Preconditions.checkArgument(StringUtil.isValid(name)); - return createLongInternal(name); + return createLongKeyInternal(name); } - private static TagKey createLongInternal(String name) { + private static TagKey createLongKeyInternal(String name) { return new AutoValue_TagKey(name, TAG_LONG); } @@ -101,12 +101,12 @@ private static TagKey createLongInternal(String name) { * @throws IllegalArgumentException if the name is not valid. */ // TODO(sebright): Make this public once we support types other than String. - static TagKey createBoolean(String name) { + static TagKey createBooleanKey(String name) { Preconditions.checkArgument(StringUtil.isValid(name)); - return createBooleanInternal(name); + return createBooleanKeyInternal(name); } - private static TagKey createBooleanInternal(String name) { + private static TagKey createBooleanKeyInternal(String name) { return new AutoValue_TagKey(name, TAG_BOOLEAN); } diff --git a/core/src/test/java/io/opencensus/tags/TagKeyTest.java b/core/src/test/java/io/opencensus/tags/TagKeyTest.java index 05d6f6e7f2..1743c2e6a0 100644 --- a/core/src/test/java/io/opencensus/tags/TagKeyTest.java +++ b/core/src/test/java/io/opencensus/tags/TagKeyTest.java @@ -31,14 +31,14 @@ public final class TagKeyTest { @Test public void testGetName() { - assertThat(TagKey.createString("foo").getName()).isEqualTo("foo"); + assertThat(TagKey.createStringKey("foo").getName()).isEqualTo("foo"); } @Test public void createString_AllowTagKeyNameWithMaxLength() { char[] key = new char[TagKey.MAX_LENGTH]; Arrays.fill(key, 'k'); - TagKey.createString(new String(key)); + TagKey.createStringKey(new String(key)); } @Test @@ -46,22 +46,22 @@ public void createString_DisallowTagKeyNameOverMaxLength() { char[] key = new char[TagKey.MAX_LENGTH + 1]; Arrays.fill(key, 'k'); thrown.expect(IllegalArgumentException.class); - TagKey.createString(new String(key)); + TagKey.createStringKey(new String(key)); } @Test public void createString_DisallowUnprintableChars() { thrown.expect(IllegalArgumentException.class); - TagKey.createString("\2ab\3cd"); + TagKey.createStringKey("\2ab\3cd"); } @Test public void testTagKeyEquals() { new EqualsTester() - .addEqualityGroup(TagKey.createString("foo"), TagKey.createString("foo")) - .addEqualityGroup(TagKey.createLong("foo")) - .addEqualityGroup(TagKey.createBoolean("foo")) - .addEqualityGroup(TagKey.createString("bar")) + .addEqualityGroup(TagKey.createStringKey("foo"), TagKey.createStringKey("foo")) + .addEqualityGroup(TagKey.createLongKey("foo")) + .addEqualityGroup(TagKey.createBooleanKey("foo")) + .addEqualityGroup(TagKey.createStringKey("bar")) .testEquals(); } } diff --git a/core/src/test/java/io/opencensus/tags/TagMapTest.java b/core/src/test/java/io/opencensus/tags/TagMapTest.java index 46afcbb10b..41b3b24735 100644 --- a/core/src/test/java/io/opencensus/tags/TagMapTest.java +++ b/core/src/test/java/io/opencensus/tags/TagMapTest.java @@ -30,8 +30,8 @@ public class TagMapTest { @Rule public final ExpectedException thrown = ExpectedException.none(); - private static final TagKey KS1 = TagKey.createString("k1"); - private static final TagKey KS2 = TagKey.createString("k2"); + private static final TagKey KS1 = TagKey.createStringKey("k1"); + private static final TagKey KS2 = TagKey.createStringKey("k2"); @Test public void applyBuilderOperationsInOrder() { @@ -41,9 +41,9 @@ public void applyBuilderOperationsInOrder() { @Test public void allowMutlipleKeysWithSameNameButDifferentTypes() { - TagKey stringKey = TagKey.createString("key"); - TagKey longKey = TagKey.createLong("key"); - TagKey booleanKey = TagKey.createBoolean("key"); + TagKey stringKey = TagKey.createStringKey("key"); + TagKey longKey = TagKey.createLongKey("key"); + TagKey booleanKey = TagKey.createBooleanKey("key"); assertThat( newBuilder() .set(stringKey, "value") @@ -74,7 +74,7 @@ public void allowStringTagValueWithMaxLength() { char[] chars = new char[TagMap.MAX_STRING_LENGTH]; Arrays.fill(chars, 'v'); String value = new String(chars); - TagKey key = TagKey.createString("K"); + TagKey key = TagKey.createStringKey("K"); newBuilder().set(key, value); } @@ -83,7 +83,7 @@ public void disallowStringTagValueOverMaxLength() { char[] chars = new char[TagMap.MAX_STRING_LENGTH + 1]; Arrays.fill(chars, 'v'); String value = new String(chars); - TagKey key = TagKey.createString("K"); + TagKey key = TagKey.createStringKey("K"); thrown.expect(IllegalArgumentException.class); newBuilder().set(key, value); } @@ -91,13 +91,13 @@ public void disallowStringTagValueOverMaxLength() { @Test public void disallowStringTagValueWithUnprintableChars() { String value = "\2ab\3cd"; - TagKey key = TagKey.createString("K"); + TagKey key = TagKey.createStringKey("K"); thrown.expect(IllegalArgumentException.class); newBuilder().set(key, value); } @SuppressWarnings({"unchecked", "rawtypes"}) - private final TagKey badLongKey = (TagKey) TagKey.createString("Key"); + private final TagKey badLongKey = (TagKey) TagKey.createStringKey("Key"); @Test(expected = IllegalArgumentException.class) public void disallowSettingWrongTypeOfKey() { From 7f29e4a5a18a68dd64e1ba018da5745673cd8c7b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 26 May 2017 11:31:46 -0700 Subject: [PATCH 0134/1581] Remove unneeded private methods. --- core/src/main/java/io/opencensus/tags/TagKey.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index c7e39fbe49..f3127a45cb 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -57,10 +57,6 @@ enum TagType { */ public static TagKey createStringKey(String name) { Preconditions.checkArgument(StringUtil.isValid(name)); - return createStringKeyInternal(name); - } - - private static TagKey createStringKeyInternal(String name) { return new AutoValue_TagKey(name, TAG_STRING); } @@ -80,10 +76,6 @@ private static TagKey createStringKeyInternal(String name) { // TODO(sebright): Make this public once we support types other than String. static TagKey createLongKey(String name) { Preconditions.checkArgument(StringUtil.isValid(name)); - return createLongKeyInternal(name); - } - - private static TagKey createLongKeyInternal(String name) { return new AutoValue_TagKey(name, TAG_LONG); } @@ -103,10 +95,6 @@ private static TagKey createLongKeyInternal(String name) { // TODO(sebright): Make this public once we support types other than String. static TagKey createBooleanKey(String name) { Preconditions.checkArgument(StringUtil.isValid(name)); - return createBooleanKeyInternal(name); - } - - private static TagKey createBooleanKeyInternal(String name) { return new AutoValue_TagKey(name, TAG_BOOLEAN); } From bc8a0722509da71c7cdc41e111a878d4d3d430cc Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 26 May 2017 11:36:24 -0700 Subject: [PATCH 0135/1581] Test TagKey.getTagType(). --- core/src/test/java/io/opencensus/tags/TagKeyTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/test/java/io/opencensus/tags/TagKeyTest.java b/core/src/test/java/io/opencensus/tags/TagKeyTest.java index 1743c2e6a0..aed02d3fc8 100644 --- a/core/src/test/java/io/opencensus/tags/TagKeyTest.java +++ b/core/src/test/java/io/opencensus/tags/TagKeyTest.java @@ -16,6 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; +import io.opencensus.tags.TagKey.TagType; import java.util.Arrays; import org.junit.Rule; import org.junit.Test; @@ -34,6 +35,13 @@ public void testGetName() { assertThat(TagKey.createStringKey("foo").getName()).isEqualTo("foo"); } + @Test + public void testGetTagType() { + assertThat(TagKey.createStringKey("key").getTagType()).isEqualTo(TagType.TAG_STRING); + assertThat(TagKey.createLongKey("key").getTagType()).isEqualTo(TagType.TAG_LONG); + assertThat(TagKey.createBooleanKey("key").getTagType()).isEqualTo(TagType.TAG_BOOLEAN); + } + @Test public void createString_AllowTagKeyNameWithMaxLength() { char[] key = new char[TagKey.MAX_LENGTH]; From 926c55efa69c7ec5e78776d8032fbee6814edf0e Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 26 May 2017 11:39:10 -0700 Subject: [PATCH 0136/1581] Move MillisClock to core_impl. Cleanup formatting. (#325) --- .../instrumentation/common}/MillisClock.java | 4 +--- .../instrumentation/trace/SpanImplTest.java | 22 ++++++++----------- .../trace/TraceComponentImplBaseTest.java | 2 +- .../trace/TraceExporterImplTest.java | 2 +- .../stats/StatsManagerImpl.java | 2 +- .../trace/TraceComponentImpl.java | 2 +- .../trace/TraceComponentImplTest.java | 2 +- .../stats/StatsManagerImpl.java | 2 +- .../trace/TraceComponentImpl.java | 2 +- .../instrumentation/trace/TracingTest.java | 2 +- 10 files changed, 18 insertions(+), 24 deletions(-) rename {core/src/main/java/com/google/instrumentation/internal => core_impl/src/main/java/com/google/instrumentation/common}/MillisClock.java (89%) diff --git a/core/src/main/java/com/google/instrumentation/internal/MillisClock.java b/core_impl/src/main/java/com/google/instrumentation/common/MillisClock.java similarity index 89% rename from core/src/main/java/com/google/instrumentation/internal/MillisClock.java rename to core_impl/src/main/java/com/google/instrumentation/common/MillisClock.java index 035c6e82c7..a1be48ea70 100644 --- a/core/src/main/java/com/google/instrumentation/internal/MillisClock.java +++ b/core_impl/src/main/java/com/google/instrumentation/common/MillisClock.java @@ -11,10 +11,8 @@ * limitations under the License. */ -package com.google.instrumentation.internal; +package com.google.instrumentation.common; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.Timestamp; import javax.annotation.concurrent.ThreadSafe; /** diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java index 3f24c862d9..26742032a9 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java @@ -307,10 +307,10 @@ public void droppingAndAddingAttributes() { assertThat(spanData.getAttributes().getAttributeMap().size()).isEqualTo(maxNumberOfAttributes); for (int i = 0; i < maxNumberOfAttributes; i++) { assertThat( - spanData - .getAttributes() - .getAttributeMap() - .get("MyStringAttributeKey" + (i + maxNumberOfAttributes))) + spanData + .getAttributes() + .getAttributeMap() + .get("MyStringAttributeKey" + (i + maxNumberOfAttributes))) .isEqualTo(AttributeValue.longAttributeValue(i + maxNumberOfAttributes)); } for (int i = 0; i < maxNumberOfAttributes / 2; i++) { @@ -325,19 +325,15 @@ public void droppingAndAddingAttributes() { // Test that we still have in the attributes map the latest maxNumberOfAttributes / 2 entries. for (int i = 0; i < maxNumberOfAttributes / 2; i++) { assertThat( - spanData - .getAttributes() - .getAttributeMap() - .get("MyStringAttributeKey" + (i + maxNumberOfAttributes * 3 / 2))) + spanData + .getAttributes() + .getAttributeMap() + .get("MyStringAttributeKey" + (i + maxNumberOfAttributes * 3 / 2))) .isEqualTo(AttributeValue.longAttributeValue(i + maxNumberOfAttributes * 3 / 2)); } // Test that we have the newest re-added initial entries. for (int i = 0; i < maxNumberOfAttributes / 2; i++) { - assertThat( - spanData - .getAttributes() - .getAttributeMap() - .get("MyStringAttributeKey" + i)) + assertThat(spanData.getAttributes().getAttributeMap().get("MyStringAttributeKey" + i)) .isEqualTo(AttributeValue.longAttributeValue(i)); } } diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java index d82c6d0955..8f739d2847 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java @@ -15,8 +15,8 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.instrumentation.common.MillisClock; import com.google.instrumentation.common.SimpleEventQueue; -import com.google.instrumentation.internal.MillisClock; import com.google.instrumentation.trace.RandomHandler.SecureRandomHandler; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java index 7a30d530c7..70b5cedf75 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java @@ -17,8 +17,8 @@ import static org.mockito.Matchers.anyListOf; import static org.mockito.Mockito.doThrow; +import com.google.instrumentation.common.MillisClock; import com.google.instrumentation.common.SimpleEventQueue; -import com.google.instrumentation.internal.MillisClock; import com.google.instrumentation.trace.Span.Options; import com.google.instrumentation.trace.TraceConfig.TraceParams; import com.google.instrumentation.trace.TraceExporter.ServiceHandler; diff --git a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java index fe3fb91f49..998777bfb5 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -13,8 +13,8 @@ package com.google.instrumentation.stats; +import com.google.instrumentation.common.MillisClock; import com.google.instrumentation.common.SimpleEventQueue; -import com.google.instrumentation.internal.MillisClock; /** * Android-compatible implementation of {@link StatsManager}. diff --git a/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java index cfa44e065c..0712590041 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -13,8 +13,8 @@ package com.google.instrumentation.trace; +import com.google.instrumentation.common.MillisClock; import com.google.instrumentation.common.SimpleEventQueue; -import com.google.instrumentation.internal.MillisClock; import com.google.instrumentation.trace.RandomHandler.SecureRandomHandler; /** Android-compatible implementation of the {@link TraceComponent}. */ diff --git a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java index 66a2b6d5e5..a4f8b4f97d 100644 --- a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java @@ -15,7 +15,7 @@ import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.internal.MillisClock; +import com.google.instrumentation.common.MillisClock; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java index 2f9ff4d6e2..1e0e8bdac8 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -14,7 +14,7 @@ package com.google.instrumentation.stats; import com.google.instrumentation.common.DisruptorEventQueue; -import com.google.instrumentation.internal.MillisClock; +import com.google.instrumentation.common.MillisClock; /** Java 7 and 8 implementation of {@link StatsManager}. */ public final class StatsManagerImpl extends StatsManagerImplBase { diff --git a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java index 766bc7fbd4..3a2db7caa9 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java @@ -14,7 +14,7 @@ package com.google.instrumentation.trace; import com.google.instrumentation.common.DisruptorEventQueue; -import com.google.instrumentation.internal.MillisClock; +import com.google.instrumentation.common.MillisClock; /** Java 7 and 8 implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplBase { diff --git a/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java b/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java index dcff6973ea..ba550e73e8 100644 --- a/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java +++ b/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java @@ -15,7 +15,7 @@ import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.internal.MillisClock; +import com.google.instrumentation.common.MillisClock; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; From 8bf7f5ec8c1c464b5bfc6045322dcf718f3e271e Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Fri, 26 May 2017 15:49:10 -0700 Subject: [PATCH 0137/1581] Add variance to Distribution --- .../instrumentation/stats/Distribution.java | 11 +++++++++ .../stats/MutableDistribution.java | 24 ++++++++++++++++++- .../stats/MutableDistributionTest.java | 6 +++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/Distribution.java b/core/src/main/java/com/google/instrumentation/stats/Distribution.java index 697c632d53..d8e5cff71f 100644 --- a/core/src/main/java/com/google/instrumentation/stats/Distribution.java +++ b/core/src/main/java/com/google/instrumentation/stats/Distribution.java @@ -64,6 +64,7 @@ static Distribution create(MutableDistribution distribution) { return new AutoValue_Distribution( distribution.getCount(), distribution.getSum(), + distribution.getSumSquaredDeviations(), Range.create(distribution.getRange()), distribution.getBucketBoundaries(), bucketCounts); @@ -102,6 +103,16 @@ final double getMean() { */ abstract double getSum(); + /** + * The sum of squared deviations from the mean for values in the population. For values x_i this + * is Sum[i=1..n]((x_i - mean)^2) + * + *

        If {@link #getCount()} is zero then this value will also be zero. + * + * @return The sum of squared deviations from the mean for values in the population. + */ + abstract double getSumSquaredDeviations(); + /** * The range of the population values. If {@link #getCount()} is zero then the returned range * will contain the "impossible" range [+Inf, -Inf]. diff --git a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java b/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java index 7492ef9ce2..d07eff3992 100644 --- a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java +++ b/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java @@ -24,6 +24,8 @@ final class MutableDistribution { private long count = 0; // The number of values in the population. private double sum = 0.0; // The sum of the values in the population. + private double mean = 0.0; // The mean of the values in the population + private double sumSquaredDeviations = 0.0; // The sum of squares of deviation from mean private Range range = Range.create(); // Range of values in the population. @Nullable @@ -81,7 +83,7 @@ long getCount() { * @return The arithmetic mean of all values in the population. */ double getMean() { - return sum / count; + return (count == 0) ? Double.NaN : mean; } /** @@ -94,6 +96,22 @@ long getCount() { return sum; } + /** + * The sum of squared deviations from the mean for values in the population. For values x_i this + * is Sum[i=1..n]((x_i - mean)^2) + * + *

        If {@link #getCount()} is zero then this value will also be zero. + * + *

        Computed using Welfords method (see + * https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance, or Knuth, "The Art of + * Computer Programming", Vol. 2, page 323, 3rd edition + * + * @return The sum of squared deviations from the mean for values in the population. + */ + double getSumSquaredDeviations() { + return sumSquaredDeviations; + } + /** * The range of the population values. If {@link #getCount()} is zero then this returned range is * implementation-dependent. @@ -157,6 +175,10 @@ private void putIntoBucket(double value) { void add(double value) { count++; sum += value; + double deltaFromMean = value - mean; + mean += deltaFromMean / count; + double deltaFromMean2 = value - mean; + sumSquaredDeviations += deltaFromMean * deltaFromMean2; range.add(value); if (hasBuckets()) { putIntoBucket(value); diff --git a/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java b/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java index f64dbbfb7e..40b660ab7f 100644 --- a/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java @@ -35,6 +35,7 @@ public void testEmptyDistribution() { MutableDistribution empty = MutableDistribution.create(); assertThat(empty.getCount()).isEqualTo(0); assertThat(empty.getSum()).isWithin(TOLERANCE).of(0.0); + assertThat(empty.getSumSquaredDeviations()).isWithin(TOLERANCE).of(0.0); assertThat(empty.getMean()).isNaN(); assertThat(empty.getRange().getMin()).isEqualTo(Double.POSITIVE_INFINITY); assertThat(empty.getRange().getMax()).isEqualTo(Double.NEGATIVE_INFINITY); @@ -47,6 +48,7 @@ public void testEmptyDistributionWithBuckets() { MutableDistribution empty = MutableDistribution.create(BucketBoundaries.create(buckets)); assertThat(empty.getCount()).isEqualTo(0); assertThat(empty.getSum()).isWithin(TOLERANCE).of(0.0); + assertThat(empty.getSumSquaredDeviations()).isWithin(TOLERANCE).of(0.0); assertThat(empty.getMean()).isNaN(); assertThat(empty.getBucketCounts()).hasSize(4); for (Long element : empty.getBucketCounts()) { @@ -81,24 +83,28 @@ public void testDistribution() { distribution.add(1.0); assertThat(distribution.getCount()).isEqualTo(1); assertThat(distribution.getSum()).isWithin(TOLERANCE).of(1.0); + assertThat(distribution.getSumSquaredDeviations()).isWithin(TOLERANCE).of(0.0); assertThat(distribution.getMean()).isWithin(TOLERANCE).of(1.0); assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(1.0); assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(1.0); distribution.add(1.0); assertThat(distribution.getCount()).isEqualTo(2); assertThat(distribution.getSum()).isWithin(TOLERANCE).of(2.0); + assertThat(distribution.getSumSquaredDeviations()).isWithin(TOLERANCE).of(0.0); assertThat(distribution.getMean()).isWithin(TOLERANCE).of(1.0); assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(1.0); assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(1.0); distribution.add(7.0); assertThat(distribution.getCount()).isEqualTo(3); assertThat(distribution.getSum()).isWithin(TOLERANCE).of(9.0); + assertThat(distribution.getSumSquaredDeviations()).isWithin(TOLERANCE).of(24.0); assertThat(distribution.getMean()).isWithin(TOLERANCE).of(3.0); assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(1.0); assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(7.0); distribution.add(-4.6); assertThat(distribution.getCount()).isEqualTo(4); assertThat(distribution.getSum()).isWithin(TOLERANCE).of(4.4); + assertThat(distribution.getSumSquaredDeviations()).isWithin(TOLERANCE).of(67.32); assertThat(distribution.getMean()).isWithin(TOLERANCE).of(1.1); assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(-4.6); assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(7.0); From a7a2d61a66d0ff107f40a6550fe4b3f3173048ef Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Fri, 26 May 2017 16:51:24 -0700 Subject: [PATCH 0138/1581] minor changes to address comments --- .../google/instrumentation/stats/Distribution.java | 4 ++-- .../instrumentation/stats/MutableDistribution.java | 10 +++++----- .../stats/MutableDistributionTest.java | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/stats/Distribution.java b/core/src/main/java/com/google/instrumentation/stats/Distribution.java index d8e5cff71f..f9f685a70a 100644 --- a/core/src/main/java/com/google/instrumentation/stats/Distribution.java +++ b/core/src/main/java/com/google/instrumentation/stats/Distribution.java @@ -64,7 +64,7 @@ static Distribution create(MutableDistribution distribution) { return new AutoValue_Distribution( distribution.getCount(), distribution.getSum(), - distribution.getSumSquaredDeviations(), + distribution.getSumOfSquaredDeviations(), Range.create(distribution.getRange()), distribution.getBucketBoundaries(), bucketCounts); @@ -111,7 +111,7 @@ final double getMean() { * * @return The sum of squared deviations from the mean for values in the population. */ - abstract double getSumSquaredDeviations(); + abstract double getSumOfSquaredDeviations(); /** * The range of the population values. If {@link #getCount()} is zero then the returned range diff --git a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java b/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java index d07eff3992..5fefe2400f 100644 --- a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java +++ b/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java @@ -25,7 +25,7 @@ final class MutableDistribution { private long count = 0; // The number of values in the population. private double sum = 0.0; // The sum of the values in the population. private double mean = 0.0; // The mean of the values in the population - private double sumSquaredDeviations = 0.0; // The sum of squares of deviation from mean + private double sumOfSquaredDeviations = 0.0; // The sum of squares of deviation from mean private Range range = Range.create(); // Range of values in the population. @Nullable @@ -104,12 +104,12 @@ long getCount() { * *

        Computed using Welfords method (see * https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance, or Knuth, "The Art of - * Computer Programming", Vol. 2, page 323, 3rd edition + * Computer Programming", Vol. 2, page 323, 3rd edition) * * @return The sum of squared deviations from the mean for values in the population. */ - double getSumSquaredDeviations() { - return sumSquaredDeviations; + double getSumOfSquaredDeviations() { + return sumOfSquaredDeviations; } /** @@ -178,7 +178,7 @@ void add(double value) { double deltaFromMean = value - mean; mean += deltaFromMean / count; double deltaFromMean2 = value - mean; - sumSquaredDeviations += deltaFromMean * deltaFromMean2; + sumOfSquaredDeviations += deltaFromMean * deltaFromMean2; range.add(value); if (hasBuckets()) { putIntoBucket(value); diff --git a/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java b/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java index 40b660ab7f..a15f707990 100644 --- a/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java @@ -35,7 +35,7 @@ public void testEmptyDistribution() { MutableDistribution empty = MutableDistribution.create(); assertThat(empty.getCount()).isEqualTo(0); assertThat(empty.getSum()).isWithin(TOLERANCE).of(0.0); - assertThat(empty.getSumSquaredDeviations()).isWithin(TOLERANCE).of(0.0); + assertThat(empty.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(0.0); assertThat(empty.getMean()).isNaN(); assertThat(empty.getRange().getMin()).isEqualTo(Double.POSITIVE_INFINITY); assertThat(empty.getRange().getMax()).isEqualTo(Double.NEGATIVE_INFINITY); @@ -48,7 +48,7 @@ public void testEmptyDistributionWithBuckets() { MutableDistribution empty = MutableDistribution.create(BucketBoundaries.create(buckets)); assertThat(empty.getCount()).isEqualTo(0); assertThat(empty.getSum()).isWithin(TOLERANCE).of(0.0); - assertThat(empty.getSumSquaredDeviations()).isWithin(TOLERANCE).of(0.0); + assertThat(empty.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(0.0); assertThat(empty.getMean()).isNaN(); assertThat(empty.getBucketCounts()).hasSize(4); for (Long element : empty.getBucketCounts()) { @@ -83,28 +83,28 @@ public void testDistribution() { distribution.add(1.0); assertThat(distribution.getCount()).isEqualTo(1); assertThat(distribution.getSum()).isWithin(TOLERANCE).of(1.0); - assertThat(distribution.getSumSquaredDeviations()).isWithin(TOLERANCE).of(0.0); + assertThat(distribution.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(0.0); assertThat(distribution.getMean()).isWithin(TOLERANCE).of(1.0); assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(1.0); assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(1.0); distribution.add(1.0); assertThat(distribution.getCount()).isEqualTo(2); assertThat(distribution.getSum()).isWithin(TOLERANCE).of(2.0); - assertThat(distribution.getSumSquaredDeviations()).isWithin(TOLERANCE).of(0.0); + assertThat(distribution.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(0.0); assertThat(distribution.getMean()).isWithin(TOLERANCE).of(1.0); assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(1.0); assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(1.0); distribution.add(7.0); assertThat(distribution.getCount()).isEqualTo(3); assertThat(distribution.getSum()).isWithin(TOLERANCE).of(9.0); - assertThat(distribution.getSumSquaredDeviations()).isWithin(TOLERANCE).of(24.0); + assertThat(distribution.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(24.0); assertThat(distribution.getMean()).isWithin(TOLERANCE).of(3.0); assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(1.0); assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(7.0); distribution.add(-4.6); assertThat(distribution.getCount()).isEqualTo(4); assertThat(distribution.getSum()).isWithin(TOLERANCE).of(4.4); - assertThat(distribution.getSumSquaredDeviations()).isWithin(TOLERANCE).of(67.32); + assertThat(distribution.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(67.32); assertThat(distribution.getMean()).isWithin(TOLERANCE).of(1.1); assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(-4.6); assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(7.0); From fadc48911d5a1e3bc0291aeb407de0beca11b01e Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 31 May 2017 17:21:45 -0700 Subject: [PATCH 0139/1581] Reword TagKey Javadocs. --- core/src/main/java/io/opencensus/tags/TagKey.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index f3127a45cb..f99f03b3c5 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -45,7 +45,7 @@ enum TagType { /** * Constructs a {@code TagKey} with the given name. * - *

        The string must meet the following requirements: + *

        The name must meet the following requirements: * *

          *
        1. It cannot be longer than {@link #MAX_LENGTH}. @@ -63,7 +63,7 @@ public static TagKey createStringKey(String name) { /** * Constructs a {@code TagKey} with the given name. * - *

          The string must meet the following requirements: + *

          The name must meet the following requirements: * *

            *
          1. It cannot be longer than {@link #MAX_LENGTH}. @@ -82,7 +82,7 @@ static TagKey createLongKey(String name) { /** * Constructs a {@code TagKey} with the given name. * - *

            The string must meet the following requirements: + *

            The name must meet the following requirements: * *

              *
            1. It cannot be longer than {@link #MAX_LENGTH}. From 680f2faf2ce1d5c180846d361fca47df5a63d36b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 31 May 2017 17:25:32 -0700 Subject: [PATCH 0140/1581] Use static imports for Preconditions.checkArgument. --- core/src/main/java/io/opencensus/tags/TagKey.java | 8 ++++---- core/src/main/java/io/opencensus/tags/TagMap.java | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index f99f03b3c5..5775eae7da 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -13,12 +13,12 @@ package io.opencensus.tags; +import static com.google.common.base.Preconditions.checkArgument; import static io.opencensus.tags.TagKey.TagType.TAG_BOOLEAN; import static io.opencensus.tags.TagKey.TagType.TAG_LONG; import static io.opencensus.tags.TagKey.TagType.TAG_STRING; import com.google.auto.value.AutoValue; -import com.google.common.base.Preconditions; import com.google.instrumentation.internal.StringUtil; import javax.annotation.concurrent.Immutable; @@ -56,7 +56,7 @@ enum TagType { * @throws IllegalArgumentException if the name is not valid. */ public static TagKey createStringKey(String name) { - Preconditions.checkArgument(StringUtil.isValid(name)); + checkArgument(StringUtil.isValid(name)); return new AutoValue_TagKey(name, TAG_STRING); } @@ -75,7 +75,7 @@ public static TagKey createStringKey(String name) { */ // TODO(sebright): Make this public once we support types other than String. static TagKey createLongKey(String name) { - Preconditions.checkArgument(StringUtil.isValid(name)); + checkArgument(StringUtil.isValid(name)); return new AutoValue_TagKey(name, TAG_LONG); } @@ -94,7 +94,7 @@ static TagKey createLongKey(String name) { */ // TODO(sebright): Make this public once we support types other than String. static TagKey createBooleanKey(String name) { - Preconditions.checkArgument(StringUtil.isValid(name)); + checkArgument(StringUtil.isValid(name)); return new AutoValue_TagKey(name, TAG_BOOLEAN); } diff --git a/core/src/main/java/io/opencensus/tags/TagMap.java b/core/src/main/java/io/opencensus/tags/TagMap.java index 28a3005106..06b88192c5 100644 --- a/core/src/main/java/io/opencensus/tags/TagMap.java +++ b/core/src/main/java/io/opencensus/tags/TagMap.java @@ -13,7 +13,8 @@ package io.opencensus.tags; -import com.google.common.base.Preconditions; +import static com.google.common.base.Preconditions.checkArgument; + import com.google.instrumentation.internal.StringUtil; import io.opencensus.tags.TagKey.TagType; import java.util.HashMap; @@ -75,11 +76,11 @@ private Builder(Map, Object> tags) { * TagMap#MAX_STRING_LENGTH}. */ public Builder set(TagKey key, String value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_STRING); + checkArgument(key.getTagType() == TagType.TAG_STRING); // TODO(sebright): Consider adding a TagValue class to avoid validating the String every time // it is set. - Preconditions.checkArgument(StringUtil.isValid(value)); + checkArgument(StringUtil.isValid(value)); return setInternal(key, value); } @@ -92,7 +93,7 @@ public Builder set(TagKey key, String value) { * @throws IllegalArgumentException if the key is null or the key is the wrong type. */ public Builder set(TagKey key, long value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_LONG); + checkArgument(key.getTagType() == TagType.TAG_LONG); return setInternal(key, value); } @@ -105,7 +106,7 @@ public Builder set(TagKey key, long value) { * @throws IllegalArgumentException if the key is null or the key is the wrong type. */ public Builder set(TagKey key, boolean value) { - Preconditions.checkArgument(key.getTagType() == TagType.TAG_BOOLEAN); + checkArgument(key.getTagType() == TagType.TAG_BOOLEAN); return setInternal(key, value); } From 22b8ee40df9ad9f03184dfd951c415ea15dfff18 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 31 May 2017 17:27:01 -0700 Subject: [PATCH 0141/1581] Hide TagMap.Builder methods that use non-String value types. --- core/src/main/java/io/opencensus/tags/TagMap.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagMap.java b/core/src/main/java/io/opencensus/tags/TagMap.java index 06b88192c5..ce7f61a6d8 100644 --- a/core/src/main/java/io/opencensus/tags/TagMap.java +++ b/core/src/main/java/io/opencensus/tags/TagMap.java @@ -92,7 +92,8 @@ public Builder set(TagKey key, String value) { * @return this * @throws IllegalArgumentException if the key is null or the key is the wrong type. */ - public Builder set(TagKey key, long value) { + // TODO(sebright): Make this public once we support types other than String. + Builder set(TagKey key, long value) { checkArgument(key.getTagType() == TagType.TAG_LONG); return setInternal(key, value); } @@ -105,7 +106,8 @@ public Builder set(TagKey key, long value) { * @return this * @throws IllegalArgumentException if the key is null or the key is the wrong type. */ - public Builder set(TagKey key, boolean value) { + // TODO(sebright): Make this public once we support types other than String. + Builder set(TagKey key, boolean value) { checkArgument(key.getTagType() == TagType.TAG_BOOLEAN); return setInternal(key, value); } From df1f2dbb7dd50aa23c1e201a05088898d674e338 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 31 May 2017 17:30:17 -0700 Subject: [PATCH 0142/1581] Copy input map in TagMap constructor. --- core/src/main/java/io/opencensus/tags/TagMap.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/io/opencensus/tags/TagMap.java b/core/src/main/java/io/opencensus/tags/TagMap.java index ce7f61a6d8..2b64880b17 100644 --- a/core/src/main/java/io/opencensus/tags/TagMap.java +++ b/core/src/main/java/io/opencensus/tags/TagMap.java @@ -17,6 +17,7 @@ import com.google.instrumentation.internal.StringUtil; import io.opencensus.tags.TagKey.TagType; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.annotation.concurrent.Immutable; @@ -37,7 +38,7 @@ public final class TagMap { private final Map, Object> tags; TagMap(Map, Object> tags) { - this.tags = tags; + this.tags = Collections.unmodifiableMap(new HashMap, Object>(tags)); } Map, Object> getTags() { From f12bb75a4027324f60523a4ad178d7a7cc5b6f05 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Thu, 1 Jun 2017 09:44:13 -0700 Subject: [PATCH 0143/1581] Fix NullPointerException in getView() without BucketBoundaries. (#328) * Fix a bug in getView() without BucketBoundaries. * Update the check for null bucket counts. --- .../instrumentation/stats/MutableView.java | 11 ++++-- .../stats/StatsManagerImplTest.java | 21 ++++++++++ .../instrumentation/stats/StatsTestUtil.java | 39 +++++++++++++++++-- 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java b/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java index bb78442fa5..6659385659 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java @@ -29,6 +29,7 @@ * A mutable version of {@link View}, used for recording stats and start/end time. */ abstract class MutableView { + // TODO(songya): might want to update the default tag value later. @VisibleForTesting static final TagValue UNKNOWN_TAG_VALUE = TagValue.create("unknown/not set"); @@ -105,10 +106,14 @@ final View toView(Clock clock) { new ArrayList(); for (Entry, MutableDistribution> entry : tagValueDistributionMap.entrySet()) { MutableDistribution distribution = entry.getValue(); - distributionAggregations.add( + DistributionAggregation distributionAggregation = distribution.getBucketCounts() == null + ? DistributionAggregation.create(distribution.getCount(), distribution.getMean(), + distribution.getSum(), convertRange(distribution.getRange()), + generateTags(entry.getKey())) : DistributionAggregation.create(distribution.getCount(), distribution.getMean(), distribution.getSum(), convertRange(distribution.getRange()), - generateTags(entry.getKey()), distribution.getBucketCounts())); + generateTags(entry.getKey()), distribution.getBucketCounts()); + distributionAggregations.add(distributionAggregation); } return DistributionView.create(distributionViewDescriptor, distributionAggregations, start, clock.now()); @@ -123,7 +128,7 @@ Timestamp getStart() { private final DistributionViewDescriptor distributionViewDescriptor; private final Map, MutableDistribution> tagValueDistributionMap = - new HashMap, MutableDistribution>(); + new HashMap, MutableDistribution>(); private final Timestamp start; private MutableDistributionView( diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 9d03b0fe14..0bd23d97eb 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -440,6 +440,27 @@ public void testMultipleViewsDifferentMeasures() { Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(2.2)))); } + @Test + public void testGetDistributionViewWithoutBucketBoundaries() { + ViewDescriptor viewDescr = + createDistributionViewDescriptor( + VIEW_NAME, MEASUREMENT_DESCRIPTOR, DistributionAggregationDescriptor.create(), + Arrays.asList(KEY)); + clock.setTime(Timestamp.create(1, 0)); + statsManager.registerView(viewDescr); + statsManager.record( + createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 1.1)); + clock.setTime(Timestamp.create(3, 0)); + DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + assertThat(view.getStart()).isEqualTo(Timestamp.create(1, 0)); + assertThat(view.getEnd()).isEqualTo(Timestamp.create(3, 0)); + assertDistributionAggregationsEquivalent( + view.getDistributionAggregations(), + Arrays.asList( + StatsTestUtil.createDistributionAggregation( + Arrays.asList(Tag.create(KEY, VALUE)), Arrays.asList(1.1)))); + } + // TODO(sebright) Consider making this helper method work with larger ranges of double values and // moving it to StatsTestUtil. private static void assertDistributionAggregationsEquivalent( diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java index a89e1c3de0..58b9ef2c8d 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java @@ -54,7 +54,7 @@ private static StatsContextImpl createContext( /** * Creates a {@code DistributionAggregation} by adding the given values to a new {@link - * MutableDistribution}. + * MutableDistribution} that has {@code BucketBoundaries}. * * @param tags the {@code DistributionAggregation}'s tags. * @param bucketBoundaries the bucket boundaries. @@ -77,6 +77,29 @@ static DistributionAggregation createDistributionAggregation( mdist.getBucketCounts()); } + /** + * Creates a {@code DistributionAggregation} by adding the given values to a new {@link + * MutableDistribution} that does not have {@code BucketBoundaries}. + * + * @param tags the {@code DistributionAggregation}'s tags. + * @param values the values to add to the distribution. + * @return the new {@code DistributionAggregation} + */ + static DistributionAggregation createDistributionAggregation( + List tags, List values) { + MutableDistribution mdist = MutableDistribution.create(); + for (double value : values) { + mdist.add(value); + } + MutableDistribution.Range range = mdist.getRange(); + return DistributionAggregation.create( + mdist.getCount(), + mdist.getMean(), + mdist.getSum(), + DistributionAggregation.Range.create(range.getMin(), range.getMax()), + tags); + } + /** * Asserts that the two sets of {@code DistributionAggregation}s are equivalent, with a given * tolerance. The tolerance is used when comparing the mean and sum of values. The order of the @@ -124,12 +147,20 @@ private static void assertDistributionAggregationValuesEquivalent( .of(agg2.getMean()); Truth.assertWithMessage(msg + " sum").that(agg1.getSum()).isWithin(tolerance).of(agg2.getSum()); Truth.assertWithMessage(msg + " range").that(agg1.getRange()).isEqualTo(agg2.getRange()); - Truth.assertWithMessage(msg + " bucket counts") - .that(removeTrailingZeros(agg1.getBucketCounts())) - .isEqualTo(removeTrailingZeros(agg2.getBucketCounts())); + + if (agg1.getBucketCounts() == null && agg2.getBucketCounts() == null) { + return; + } else { + Truth.assertWithMessage(msg + " bucket counts") + .that(removeTrailingZeros(agg1.getBucketCounts())) + .isEqualTo(removeTrailingZeros(agg2.getBucketCounts())); + } } private static List removeTrailingZeros(List longs) { + if (longs == null) { + return null; + } List truncated = new ArrayList(longs); while (!truncated.isEmpty() && Iterables.getLast(truncated) == 0) { truncated.remove(truncated.size() - 1); From 49cef6a95595ba20bd0b4d0f1be02a14f70c8add Mon Sep 17 00:00:00 2001 From: Yang Song Date: Thu, 1 Jun 2017 10:35:12 -0700 Subject: [PATCH 0144/1581] Fix some small style issues. (#329) --- .../instrumentation/stats/MutableDistributionTest.java | 4 ++-- .../java/com/google/instrumentation/stats/MutableView.java | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java b/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java index a15f707990..11cce7350a 100644 --- a/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java @@ -37,8 +37,8 @@ public void testEmptyDistribution() { assertThat(empty.getSum()).isWithin(TOLERANCE).of(0.0); assertThat(empty.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(0.0); assertThat(empty.getMean()).isNaN(); - assertThat(empty.getRange().getMin()).isEqualTo(Double.POSITIVE_INFINITY); - assertThat(empty.getRange().getMax()).isEqualTo(Double.NEGATIVE_INFINITY); + assertThat(empty.getRange().getMin()).isPositiveInfinity(); + assertThat(empty.getRange().getMax()).isNegativeInfinity(); assertThat(empty.getBucketCounts()).isNull(); } diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java b/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java index 6659385659..55636cd069 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java @@ -31,7 +31,8 @@ abstract class MutableView { // TODO(songya): might want to update the default tag value later. - @VisibleForTesting static final TagValue UNKNOWN_TAG_VALUE = TagValue.create("unknown/not set"); + @VisibleForTesting + static final TagValue UNKNOWN_TAG_VALUE = TagValue.create("unknown/not set"); /** * The {@link ViewDescriptor} associated with this {@link View}. @@ -109,8 +110,8 @@ final View toView(Clock clock) { DistributionAggregation distributionAggregation = distribution.getBucketCounts() == null ? DistributionAggregation.create(distribution.getCount(), distribution.getMean(), distribution.getSum(), convertRange(distribution.getRange()), - generateTags(entry.getKey())) : - DistributionAggregation.create(distribution.getCount(), distribution.getMean(), + generateTags(entry.getKey())) + : DistributionAggregation.create(distribution.getCount(), distribution.getMean(), distribution.getSum(), convertRange(distribution.getRange()), generateTags(entry.getKey()), distribution.getBucketCounts()); distributionAggregations.add(distributionAggregation); From 7219d065880566fb92c544b65b24adee0d47ec95 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Thu, 1 Jun 2017 13:21:08 -0700 Subject: [PATCH 0145/1581] Update stats example to use APIs in StatsContextFactory. (#330) --- examples/build.gradle | 3 +- .../examples/stats/StatsRunner.java | 51 ++++++------------- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/examples/build.gradle b/examples/build.gradle index 47563924a9..711f3bd85b 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -8,8 +8,7 @@ tasks.withType(JavaCompile) { dependencies { compile project(':core'), project(':core_impl'), - project(':core_impl_java'), - libraries.grpc_context + project(':core_impl_java') } // Provide convenience executables for trying out the examples. diff --git a/examples/src/main/java/com/google/instrumentation/examples/stats/StatsRunner.java b/examples/src/main/java/com/google/instrumentation/examples/stats/StatsRunner.java index 0641b84284..a7e901df1c 100644 --- a/examples/src/main/java/com/google/instrumentation/examples/stats/StatsRunner.java +++ b/examples/src/main/java/com/google/instrumentation/examples/stats/StatsRunner.java @@ -13,15 +13,16 @@ package com.google.instrumentation.examples.stats; +import com.google.instrumentation.common.NonThrowingCloseable; import com.google.instrumentation.stats.MeasurementDescriptor; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; import com.google.instrumentation.stats.MeasurementMap; import com.google.instrumentation.stats.Stats; import com.google.instrumentation.stats.StatsContext; +import com.google.instrumentation.stats.StatsContextFactory; import com.google.instrumentation.stats.TagKey; import com.google.instrumentation.stats.TagValue; -import io.grpc.Context; import java.util.Arrays; /** Simple program that uses Stats contexts. */ @@ -43,49 +44,29 @@ public class StatsRunner { private static final MeasurementDescriptor M2 = MeasurementDescriptor.create("m2", "2nd test metric", simpleMeasurementUnit); + private static final StatsContextFactory factory = Stats.getStatsContextFactory(); + private static final StatsContext DEFAULT = factory.getDefault(); + /** Main method. */ public static void main(String[] args) { System.out.println("Hello Stats World"); System.out.println("Default Tags: " + DEFAULT); - System.out.println("Current Tags: " + getCurrentStatsContext()); - Context context1 = withCurrent(DEFAULT.with(K1, V1, K2, V2)); - Context original = context1.attach(); - try { - System.out.println(" Current Tags: " + getCurrentStatsContext()); + System.out.println("Current Tags: " + factory.getCurrentStatsContext()); + StatsContext tags1 = DEFAULT.with(K1, V1, K2, V2); + try (NonThrowingCloseable scopedStatsCtx1 = factory.withStatsContext(tags1)) { + System.out.println(" Current Tags: " + factory.getCurrentStatsContext()); System.out.println( " Current == Default + tags1: " - + getCurrentStatsContext().equals(getStatsContext(context1))); - Context context2 = withCurrent(getCurrentStatsContext().with(K3, V3, K4, V4)); - context2.attach(); - try { - System.out.println(" Current Tags: " + getCurrentStatsContext()); + + factory.getCurrentStatsContext().equals(tags1)); + StatsContext tags2 = tags1.with(K3, V3, K4, V4); + try (NonThrowingCloseable scopedStatsCtx2 = factory.withStatsContext(tags2)) { + System.out.println(" Current Tags: " + factory.getCurrentStatsContext()); System.out.println( " Current == Default + tags1 + tags2: " - + getCurrentStatsContext().equals(getStatsContext(context2))); - getCurrentStatsContext().record(MeasurementMap.of(M1, 0.2, M2, 0.4)); - } finally { - context2.detach(context1); + + factory.getCurrentStatsContext().equals(tags2)); + factory.getCurrentStatsContext().record(MeasurementMap.of(M1, 0.2, M2, 0.4)); } - } finally { - context1.detach(original); } - System.out.println("Current == Default: " + getCurrentStatsContext().equals(DEFAULT)); - } - - private static final StatsContext DEFAULT = Stats.getStatsContextFactory().getDefault(); - - private static final Context.Key STATS_CONTEXT_KEY = - Context.keyWithDefault("StatsContextKey", DEFAULT); - - private static final StatsContext getCurrentStatsContext() { - return getStatsContext(Context.current()); - } - - private static final StatsContext getStatsContext(Context context) { - return STATS_CONTEXT_KEY.get(context); - } - - private static final Context withCurrent(StatsContext context) { - return Context.current().withValue(STATS_CONTEXT_KEY, context); + System.out.println("Current == Default: " + factory.getCurrentStatsContext().equals(DEFAULT)); } } From e7d4da217dbb86afd3cd8159667688c6b76b0d80 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 1 Jun 2017 15:23:38 -0700 Subject: [PATCH 0146/1581] Add API for active/samples in-process spans. (#318) --- .../instrumentation/trace/TraceExporter.java | 484 +++++++++++++++++- .../trace/TraceExporterImpl.java | 8 + .../trace/TraceExporterImplTest.java | 3 +- 3 files changed, 479 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java index 967959e0f0..5bad30af46 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java @@ -13,10 +13,21 @@ package com.google.instrumentation.trace; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.auto.value.AutoValue; +import com.google.instrumentation.trace.Status.CanonicalCode; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.ThreadSafe; /** @@ -26,17 +37,28 @@ */ @ThreadSafe public abstract class TraceExporter { + private static final NoopTraceExporter noopTraceExporter = new NoopTraceExporter(); /** - * Registers a new service handler that is used by the library to export trace data. + * Returns the no-op implementation of the {@code TraceExporter}. + * + * @return the no-op implementation of the {@code TraceExporter}. + */ + static TraceExporter getNoopTraceExporter() { + return noopTraceExporter; + } + + /** + * Registers a new service handler that is used by the library to export {@code SpanData} for + * sampled spans (see {@link TraceOptions#isSampled()}). * *

              Example of usage: * *

              {@code
                  * public static void main(String[] args) {
                  *   Tracing.getTraceExporter().registerServiceHandler(
              -   *       "com.google.stackdriver", new StackdriverServiceHandler());
              +   *       "com.google.stackdriver.tracing", new StackdriverTracingServiceHandler());
                  *   // ...
                  * }
                  * }
              @@ -53,6 +75,439 @@ public abstract class TraceExporter { */ public abstract void unregisterServiceHandler(String name); + /** + * Returns the {@code InProcessDebuggingHandler} that can be used to get useful debugging + * information such as (active spans, latency based sampled spans, error based sampled spans). + * + * @return the {@code InProcessDebuggingHandler} or {@code null} if in-process debugging is not + * supported. + */ + @Nullable + public abstract InProcessDebuggingHandler getInProcessDebuggingHandler(); + + /** + * This class allows users to access in-process debugging information such as (getting access to + * all active spans, support latency based sampled spans and error based sampled spans). + * + *

              The active spans tracking is available for all the spans with the option {@link + * Span.Options#RECORD_EVENTS}. This functionality allows users to debug stuck operations or long + * living operations. + * + *

              For all completed spans with the option {@link Span.Options#RECORD_EVENTS} the library can + * store samples based on latency for succeeded operations or based on error code for failed + * operations. To activate this, users MUST manually configure all the span names for which + * samples will be collected (see {@link #collectSamplesForSpanNames(Collection)}). + */ + public abstract static class InProcessDebuggingHandler { + + InProcessDebuggingHandler() {} + + /** + * Returns the summary of all available in-process debugging data such as number of active + * spans, number of sampled spans in the latency based samples or error based samples. + * + *

              Latency based sampled summary buckets and error based sampled summary buckets are + * available only for span names registered using {@link + * #collectSamplesForSpanNames(Collection)}. + * + * @return the summary of all available in-process debugging data. + */ + public abstract Summary getSummary(); + + /** + * Returns a list of active spans that match the {@code filter}. + * + *

              Active spans are available for all the span names. + * + * @param filter used to filter the returned spans. + * @return a list of active spans that match the {@code filter}. + */ + public abstract Collection getActiveSpans(ActiveSpansFilter filter); + + /** + * Returns a list of succeeded spans (spans with {@link Status} equal to {@link Status#OK}) that + * match the {@code filter}. + * + *

              Latency based sampled spans are available only for span names registered using {@link + * #collectSamplesForSpanNames(Collection)}. + * + * @param filter used to filter the returned sampled spans. + * @return a list of succeeded spans that match the {@code filter}. + */ + public abstract Collection getLatencyBasedSampledSpans( + LatencyBasedSampledSpansFilter filter); + + /** + * Returns a list of failed spans (spans with {@link Status} other than {@link Status#OK}) that + * match the {@code filter}. + * + *

              Error based sampled spans are available only for span names registered using {@link + * #collectSamplesForSpanNames(Collection)}. + * + * @param filter used to filter the returned sampled spans. + * @return a list of failed spans that match the {@code filter}. + */ + public abstract Collection getErrorBasedSampledSpans( + ErrorBasedSampledSpansFilter filter); + + /** + * Appends a list of span names for which the library will collect latency based sampled spans + * and error based sampled spans. + * + *

              If called multiple times the library keeps the list of unique span names from all the + * calls. + * + * @param spanNames list of span names for which the library will collect samples. + */ + public abstract void collectSamplesForSpanNames(Collection spanNames); + + /** The summary of all in-process debugging information. */ + @AutoValue + @Immutable + public abstract static class Summary { + + Summary() {} + + /** + * Returns a new instance of {@code Summary}. + * + * @param perSpanNameSummary a map with summary for each different span name. + * @return a new instance of {@code Summary}. + * @throws NullPointerException if {@code perSpanNameSummary} is {@code null}. + */ + public static Summary create(Map perSpanNameSummary) { + return new AutoValue_TraceExporter_InProcessDebuggingHandler_Summary( + Collections.unmodifiableMap( + new HashMap( + checkNotNull(perSpanNameSummary, "perSpanNameSummary")))); + } + + /** + * Returns a map with summary of available data for each different span name. + * + * @return a map with all the span names and the summary. + */ + public abstract Map getPerSpanNameSummary(); + + /** Summary of all available data for a span name. */ + @AutoValue + @Immutable + public abstract static class PerSpanNameSummary { + + PerSpanNameSummary() {} + + /** + * Returns a new instance of {@code PerSpanNameSummary}. + * + * @param numActiveSpans the number of sampled spans. + * @param latencyBucketSummaries the summary for the latency buckets. + * @param errorBucketSummaries the summary for the error buckets. + * @return a new instance of {@code PerSpanNameSummary}. + * @throws NullPointerException if {@code latencyBucketSummaries} or {@code + * errorBucketSummaries} are {@code null}. + * @throws IllegalArgumentException if {@code numActiveSpans} is negative. + */ + public static PerSpanNameSummary create( + int numActiveSpans, + List latencyBucketSummaries, + List errorBucketSummaries) { + checkArgument(numActiveSpans >= 0, "Negative numActiveSpans."); + return new AutoValue_TraceExporter_InProcessDebuggingHandler_Summary_PerSpanNameSummary( + numActiveSpans, + Collections.unmodifiableList( + new ArrayList( + checkNotNull(latencyBucketSummaries, "latencyBucketSummaries"))), + Collections.unmodifiableList( + new ArrayList( + checkNotNull(errorBucketSummaries, "errorBucketSummaries")))); + } + + /** + * Returns the number of active spans. + * + * @return the number of active spans. + */ + public abstract int getNumActiveSpans(); + + /** + * Returns the list of all latency based sampled buckets summary. + * + *

              The list is sorted based on the lower latency boundary, and the upper bound of one + * match the lower bound of the next. Every bucket contains samples with latency within the + * interval [lowerBoundary, upperBoundary). + * + * @return the list of all latency based sampled buckets summary. + */ + public abstract List getLatencyBucketSummaries(); + + /** + * Returns the list of all error based sampled buckets summary. + * + *

              The list is sorted based on the {@link CanonicalCode#value()} and contains an entry + * for each of the values other than {@link CanonicalCode#OK}. + * + * @return the list of all error based sampled buckets summary. + */ + public abstract List getErrorBucketSummaries(); + + /** + * Summary of a latency based sampled spans bucket. Contains {@code Span} samples with + * latency between [latencyLowerNs, latencyUpperNs). + */ + @AutoValue + @Immutable + public abstract static class LatencyBucketSummary { + + LatencyBucketSummary() {} + + /** + * Returns a new instance of {@code LatencyBucketSummary}. The latency of the samples is + * in the interval [latencyLowerNs, latencyUpperNs). + * + * @param numSamples the number of sampled spans. + * @param latencyLowerNs the latency lower bound. + * @param latencyUpperNs the latency upper bound. + * @return a new instance of {@code LatencyBucketSummary}. + * @throws IllegalArgumentException if {@code numSamples} or {@code latencyLowerNs} or + * {@code latencyUpperNs} are negative. + */ + public static LatencyBucketSummary create( + int numSamples, long latencyLowerNs, long latencyUpperNs) { + checkArgument(numSamples >= 0, "Negative numSamples."); + checkArgument(latencyLowerNs >= 0, "Negative latencyLowerNs"); + checkArgument(latencyUpperNs >= 0, "Negative latencyUpperNs"); + //CHECKSTYLE:OFF: Long class name. + return new AutoValue_TraceExporter_InProcessDebuggingHandler_Summary_PerSpanNameSummary_LatencyBucketSummary( + numSamples, latencyLowerNs, latencyUpperNs); + //CHECKSTYLE:ON: Long class name. + } + + /** + * Returns the number of sampled spans in this bucket. + * + * @return the number of sampled spans in this bucket. + */ + public abstract int getNumSamples(); + + /** + * Returns the latency lower bound of this bucket (inclusive). + * + * @return the latency lower bound of this bucket. + */ + public abstract long getLatencyLowerNs(); + + /** + * Returns the latency upper bound of this bucket (exclusive). + * + * @return the latency upper bound of this bucket. + */ + public abstract long getLatencyUpperNs(); + } + + /** Summary of an error based sampled spans bucket. */ + @AutoValue + @Immutable + public abstract static class ErrorBucketSummary { + + ErrorBucketSummary() {} + + /** + * Returns a new instance of {@code ErrorBucketSummary}. + * + * @param numSamples the number of sampled spans. + * @param canonicalCode the error code of the bucket. + * @return a new instance of {@code ErrorBucketSummary}. + * @throws NullPointerException if {@code canonicalCode} is {@code null}. + * @throws IllegalArgumentException if {@code canonicalCode} is {@link CanonicalCode#OK} + * or {@code numSamples} is negative. + */ + public static ErrorBucketSummary create(int numSamples, CanonicalCode canonicalCode) { + checkArgument(numSamples >= 0, "Negative numSamples."); + checkArgument(canonicalCode != CanonicalCode.OK, "Invalid canonical code."); + //CHECKSTYLE:OFF: Long class name. + return new AutoValue_TraceExporter_InProcessDebuggingHandler_Summary_PerSpanNameSummary_ErrorBucketSummary( + numSamples, canonicalCode); + //CHECKSTYLE:ON: Long class name. + } + + /** + * Returns the number of sampled spans in this bucket. + * + * @return the number of sampled spans in this bucket. + */ + public abstract int getNumSamples(); + + /** + * Returns the {@code CanonicalCode} for this bucket. Always different than {@link + * CanonicalCode#OK}. + * + * @return the {@code CanonicalCode} for this bucket. + */ + public abstract CanonicalCode getCanonicalCode(); + } + } + } + + /** + * Filter for active spans. Used to filter results returned by the {@link + * #getActiveSpans(ActiveSpansFilter)} request. + */ + @AutoValue + @Immutable + public abstract static class ActiveSpansFilter { + + ActiveSpansFilter() {} + + /** + * Returns a new instance of {@code ActiveSpansFilter}. + * + *

              Filters all the spans based on {@code spanName} and returns a maximum of {@code + * maxSpansToReturn}. + * + * @param spanName the name of the span. + * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. + * @return a new instance of {@code ActiveSpansFilter}. + * @throws NullPointerException if {@code spanName} is {@code null}. + * @throws IllegalArgumentException if {@code maxSpansToReturn} is negative. + */ + public static ActiveSpansFilter create(String spanName, int maxSpansToReturn) { + checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); + return new AutoValue_TraceExporter_InProcessDebuggingHandler_ActiveSpansFilter( + spanName, maxSpansToReturn); + } + + /** + * Returns the span name. + * + * @return the span name. + */ + public abstract String getSpanName(); + + /** + * Returns the maximum number of spans to be returned. {@code 0} means all. + * + * @return the maximum number of spans to be returned. + */ + public abstract int getMaxSpansToReturn(); + } + + /** + * Filter for latency based sampled spans. Used to filter results returned by the {@link + * #getLatencyBasedSampledSpans(LatencyBasedSampledSpansFilter)} request. + */ + @AutoValue + @Immutable + public abstract static class LatencyBasedSampledSpansFilter { + + LatencyBasedSampledSpansFilter() {} + + /** + * Returns a new instance of {@code LatencyBasedSampledSpansFilter}. + * + *

              Filters all the spans based on {@code spanName} and latency in the interval + * [latencyLowerNs, latencyUpperNs) and returns a maximum of {@code maxSpansToReturn}. + * + * @param spanName the name of the span. + * @param latencyLowerNs the latency lower bound. + * @param latencyUpperNs the latency upper bound. + * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. + * @return a new instance of {@code LatencyBasedSampledSpansFilter}. + * @throws NullPointerException if {@code spanName} is {@code null}. + * @throws IllegalArgumentException if {@code maxSpansToReturn} or {@code latencyLowerNs} or + * {@code latencyUpperNs} are negative. + */ + public static LatencyBasedSampledSpansFilter create( + String spanName, long latencyLowerNs, long latencyUpperNs, int maxSpansToReturn) { + checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); + checkArgument(latencyLowerNs >= 0, "Negative latencyLowerNs"); + checkArgument(latencyUpperNs >= 0, "Negative latencyUpperNs"); + return new AutoValue_TraceExporter_InProcessDebuggingHandler_LatencyBasedSampledSpansFilter( + spanName, latencyLowerNs, latencyUpperNs, maxSpansToReturn); + } + + /** + * Returns the span name used by this filter. + * + * @return the span name used by this filter. + */ + public abstract String getSpanName(); + + /** + * Returns the latency lower bound of this bucket (inclusive). + * + * @return the latency lower bound of this bucket. + */ + public abstract long getLatencyLowerNs(); + + /** + * Returns the latency upper bound of this bucket (exclusive). + * + * @return the latency upper bound of this bucket. + */ + public abstract long getLatencyUpperNs(); + + /** + * Returns the maximum number of spans to be returned. {@code 0} means all. + * + * @return the maximum number of spans to be returned. + */ + public abstract int getMaxSpansToReturn(); + } + + /** Filter for error based sampled spans. */ + @AutoValue + @Immutable + public abstract static class ErrorBasedSampledSpansFilter { + + ErrorBasedSampledSpansFilter() {} + + /** + * Returns a new instance of {@code ErrorBasedSampledSpansFilter}. + * + *

              Filters all the spans based on {@code spanName} and {@code canonicalCode} and returns a + * maximum of {@code maxSpansToReturn}. + * + * @param spanName the name of the span. + * @param canonicalCode the error code of the span. + * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. + * @return a new instance of {@code ErrorBasedSampledSpansFilter}. + * @throws NullPointerException if {@code spanName} or {@code canonicalCode} are {@code null}. + * @throws IllegalArgumentException if {@code canonicalCode} is {@link CanonicalCode#OK} or + * {@code maxSpansToReturn} is negative. + */ + public static ErrorBasedSampledSpansFilter create( + String spanName, CanonicalCode canonicalCode, int maxSpansToReturn) { + checkArgument(canonicalCode != CanonicalCode.OK, "Invalid canonical code."); + checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); + return new AutoValue_TraceExporter_InProcessDebuggingHandler_ErrorBasedSampledSpansFilter( + spanName, canonicalCode, maxSpansToReturn); + } + + /** + * Returns the span name used by this filter. + * + * @return the span name used by this filter. + */ + public abstract String getSpanName(); + + /** + * Returns the canonical code used by this filter. Always different than {@link + * CanonicalCode#OK}. + * + * @return the canonical code used by this filter. + */ + public abstract CanonicalCode getCanonicalCode(); + + /** + * Returns the maximum number of spans to be returned. Used to enforce the number of returned + * {@code SpanData}. {@code 0} means all. + * + * @return the maximum number of spans to be returned. + */ + public abstract int getMaxSpansToReturn(); + } + } + /** * An abstract class that allows different tracing services to export recorded data for sampled * spans in their own format. @@ -73,7 +528,7 @@ public abstract static class ServiceHandler { * * @param spanDataList a list of {@code SpanData} objects to be exported. */ - public abstract void export(List spanDataList); + public abstract void export(Collection spanDataList); } /** @@ -91,11 +546,14 @@ public abstract static class ServiceHandler { */ @ThreadSafe public static final class LoggingServiceHandler extends ServiceHandler { + private static final Logger logger = Logger.getLogger(LoggingServiceHandler.class.getName()); private static final String SERVICE_NAME = "com.google.instrumentation.trace.LoggingServiceHandler"; private static final LoggingServiceHandler INSTANCE = new LoggingServiceHandler(); + private LoggingServiceHandler() {} + /** * Registers the {@code LoggingServiceHandler} to the {@code TraceExporter}. * @@ -117,29 +575,25 @@ public static void unregisterService(TraceExporter traceExporter) { } @Override - public void export(List spanDataList) { + public void export(Collection spanDataList) { for (SpanData spanData : spanDataList) { logger.log(Level.INFO, spanData.toString()); } } - - private LoggingServiceHandler() {} - } - - /** - * Returns the no-op implementation of the {@code TraceExporter}. - * - * @return the no-op implementation of the {@code TraceExporter}. - */ - static TraceExporter getNoopTraceExporter() { - return noopTraceExporter; } private static final class NoopTraceExporter extends TraceExporter { + @Override public void registerServiceHandler(String name, @Nullable ServiceHandler serviceHandler) {} @Override public void unregisterServiceHandler(String name) {} + + @Nullable + @Override + public InProcessDebuggingHandler getInProcessDebuggingHandler() { + return null; + } } } diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java b/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java index b373727d60..1057d8b40a 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java +++ b/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java @@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; /** @@ -65,6 +66,13 @@ public void unregisterServiceHandler(String name) { serviceExporterThread.unregisterServiceHandler(name); } + @Nullable + @Override + public InProcessDebuggingHandler getInProcessDebuggingHandler() { + // TODO(bdrutu): Implement this. + return null; + } + @Override public void onStart(SpanImpl span) { // Do nothing. When ActiveSpans functionality is implemented this will change to record the diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java b/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java index 70b5cedf75..03f0e408ed 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java @@ -23,6 +23,7 @@ import com.google.instrumentation.trace.TraceConfig.TraceParams; import com.google.instrumentation.trace.TraceExporter.ServiceHandler; import java.util.ArrayList; +import java.util.Collection; import java.util.EnumSet; import java.util.LinkedList; import java.util.List; @@ -184,7 +185,7 @@ private static final class FakeServiceHandler extends ServiceHandler { private final List spanDataList = new LinkedList(); @Override - public void export(List spanDataList) { + public void export(Collection spanDataList) { synchronized (monitor) { this.spanDataList.addAll(spanDataList); monitor.notifyAll(); From 84d0f46e88faa89c0d822a73a7a610b9ac1bc471 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 5 Jun 2017 10:23:18 -0700 Subject: [PATCH 0147/1581] Add API to remove a span name from the list of the span names from which the library collects samples. (#331) --- .../instrumentation/trace/TraceExporter.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java index 5bad30af46..d610ca7e11 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java +++ b/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java @@ -96,7 +96,7 @@ static TraceExporter getNoopTraceExporter() { *

              For all completed spans with the option {@link Span.Options#RECORD_EVENTS} the library can * store samples based on latency for succeeded operations or based on error code for failed * operations. To activate this, users MUST manually configure all the span names for which - * samples will be collected (see {@link #collectSamplesForSpanNames(Collection)}). + * samples will be collected (see {@link #registerSpanNamesForCollection(Collection)}). */ public abstract static class InProcessDebuggingHandler { @@ -108,7 +108,7 @@ public abstract static class InProcessDebuggingHandler { * *

              Latency based sampled summary buckets and error based sampled summary buckets are * available only for span names registered using {@link - * #collectSamplesForSpanNames(Collection)}. + * #registerSpanNamesForCollection(Collection)}. * * @return the summary of all available in-process debugging data. */ @@ -129,7 +129,7 @@ public abstract static class InProcessDebuggingHandler { * match the {@code filter}. * *

              Latency based sampled spans are available only for span names registered using {@link - * #collectSamplesForSpanNames(Collection)}. + * #registerSpanNamesForCollection(Collection)}. * * @param filter used to filter the returned sampled spans. * @return a list of succeeded spans that match the {@code filter}. @@ -142,7 +142,7 @@ public abstract Collection getLatencyBasedSampledSpans( * match the {@code filter}. * *

              Error based sampled spans are available only for span names registered using {@link - * #collectSamplesForSpanNames(Collection)}. + * #registerSpanNamesForCollection(Collection)}. * * @param filter used to filter the returned sampled spans. * @return a list of failed spans that match the {@code filter}. @@ -159,7 +159,18 @@ public abstract Collection getErrorBasedSampledSpans( * * @param spanNames list of span names for which the library will collect samples. */ - public abstract void collectSamplesForSpanNames(Collection spanNames); + public abstract void registerSpanNamesForCollection(Collection spanNames); + + /** + * Removes a list of span names for which the library will collect latency based sampled spans + * and error based sampled spans. + * + *

              The library keeps the list of unique registered span names for which samples will be + * called. This method allows users to remove span names from that list. + * + * @param spanNames list of span names for which the library will no longer collect samples. + */ + public abstract void unregisterSpanNamesForCollection(Collection spanNames); /** The summary of all in-process debugging information. */ @AutoValue From 80ec0c120bb133b3d3747406be7e4c543b9e0446 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 6 Jun 2017 13:56:55 -0700 Subject: [PATCH 0148/1581] Move internal & common & trace to the new package io.opencensus (#339) --- README.md | 8 +-- all/build.gradle | 9 +-- api/README.md | 6 ++ api/build.gradle | 11 ++++ .../java/io/opencensus}/common/Clock.java | 6 +- .../java/io/opencensus}/common/Duration.java | 37 +++++-------- .../java/io/opencensus}/common/Function.java | 8 +-- .../java/io/opencensus}/common/Internal.java | 18 +++--- .../common/NonThrowingCloseable.java | 2 +- .../java/io/opencensus}/common/Timestamp.java | 16 +++--- .../io/opencensus}/internal/Provider.java | 2 +- .../io/opencensus}/internal/StringUtil.java | 6 +- .../io/opencensus}/internal/TestClock.java | 12 ++-- .../opencensus}/internal/ZeroTimeClock.java | 10 ++-- .../io/opencensus}/internal/package-info.java | 6 +- .../main/java/io/opencensus/tags/TagKey.java | 14 ++--- .../main/java/io/opencensus/tags/TagMap.java | 2 +- .../java/io/opencensus}/trace/Annotation.java | 2 +- .../io/opencensus}/trace/AttributeValue.java | 2 +- .../trace/BinaryPropagationHandler.java | 2 +- .../java/io/opencensus}/trace/BlankSpan.java | 2 +- .../io/opencensus}/trace/ContextUtils.java | 4 +- .../io/opencensus}/trace/EndSpanOptions.java | 2 +- .../main/java/io/opencensus}/trace/Link.java | 2 +- .../io/opencensus}/trace/NetworkEvent.java | 4 +- .../java/io/opencensus}/trace/Sampler.java | 2 +- .../java/io/opencensus}/trace/Samplers.java | 2 +- .../opencensus}/trace/ScopedSpanHandle.java | 4 +- .../main/java/io/opencensus}/trace/Span.java | 2 +- .../io/opencensus}/trace/SpanBuilder.java | 4 +- .../io/opencensus}/trace/SpanContext.java | 2 +- .../java/io/opencensus}/trace/SpanData.java | 4 +- .../io/opencensus}/trace/SpanFactory.java | 2 +- .../java/io/opencensus}/trace/SpanId.java | 2 +- .../opencensus}/trace/StartSpanOptions.java | 2 +- .../java/io/opencensus}/trace/Status.java | 2 +- .../io/opencensus}/trace/TraceComponent.java | 6 +- .../io/opencensus}/trace/TraceConfig.java | 2 +- .../io/opencensus}/trace/TraceExporter.java | 9 ++- .../java/io/opencensus}/trace/TraceId.java | 2 +- .../io/opencensus}/trace/TraceOptions.java | 2 +- .../java/io/opencensus}/trace/Tracer.java | 4 +- .../java/io/opencensus}/trace/Tracing.java | 8 +-- .../io/opencensus}/common/DurationTest.java | 14 ++--- .../io/opencensus}/common/TimestampTest.java | 2 +- .../io/opencensus}/internal/ProviderTest.java | 20 +++---- .../opencensus}/internal/StringUtilTest.java | 6 +- .../opencensus}/internal/TestClockTest.java | 10 ++-- .../java/io/opencensus/tags/TagKeyTest.java | 0 .../java/io/opencensus/tags/TagMapTest.java | 0 .../io/opencensus}/trace/AnnotationTest.java | 2 +- .../opencensus}/trace/AttributeValueTest.java | 2 +- .../trace/BinaryPropagationHandlerTest.java | 2 +- .../io/opencensus}/trace/BlankSpanTest.java | 2 +- .../opencensus}/trace/ContextUtilsTest.java | 4 +- .../opencensus}/trace/EndSpanOptionsTest.java | 2 +- .../java/io/opencensus}/trace/LinkTest.java | 4 +- .../opencensus}/trace/NetworkEventTest.java | 4 +- .../io/opencensus}/trace/SamplersTest.java | 5 +- .../trace/ScopedSpanHandleTest.java | 4 +- .../io/opencensus}/trace/SpanBuilderTest.java | 4 +- .../io/opencensus}/trace/SpanContextTest.java | 2 +- .../io/opencensus}/trace/SpanDataTest.java | 14 ++--- .../java/io/opencensus}/trace/SpanIdTest.java | 2 +- .../java/io/opencensus}/trace/SpanTest.java | 2 +- .../trace/StartSpanOptionsTest.java | 2 +- .../java/io/opencensus}/trace/StatusTest.java | 2 +- .../opencensus}/trace/TraceComponentTest.java | 4 +- .../opencensus}/trace/TraceExporterTest.java | 10 ++-- .../io/opencensus}/trace/TraceIdTest.java | 2 +- .../opencensus}/trace/TraceOptionsTest.java | 2 +- .../io/opencensus}/trace/TraceParamsTest.java | 4 +- .../java/io/opencensus}/trace/TracerTest.java | 4 +- .../io/opencensus}/trace/TracingTest.java | 4 +- ...BinaryPropagationHandlerImplBenchmark.java | 2 +- ...ordTraceEventsNonSampledSpanBenchmark.java | 2 +- ...RecordTraceEventsSampledSpanBenchmark.java | 2 +- .../trace/StartEndSpanBenchmark.java | 2 +- core/build.gradle | 3 +- .../instrumentation/stats/ContextUtils.java | 2 +- .../stats/IntervalAggregation.java | 2 +- .../stats/IntervalAggregationDescriptor.java | 2 +- .../stats/MeasurementDescriptor.java | 2 +- .../instrumentation/stats/RpcConstants.java | 2 +- .../stats/RpcViewConstants.java | 3 +- .../google/instrumentation/stats/Stats.java | 2 +- .../stats/StatsContextFactory.java | 2 +- .../google/instrumentation/stats/TagKey.java | 2 +- .../instrumentation/stats/TagValue.java | 2 +- .../google/instrumentation/stats/View.java | 5 +- .../instrumentation/stats/ViewDescriptor.java | 2 +- .../stats/ContextUtilsTest.java | 2 +- .../IntervalAggregationDescriptorTest.java | 2 +- .../stats/IntervalAggregationTest.java | 2 +- .../stats/MeasurementDescriptorTest.java | 2 +- .../instrumentation/stats/TagKeyTest.java | 2 +- .../instrumentation/stats/TagValueTest.java | 2 +- .../stats/ViewDescriptorTest.java | 4 +- .../instrumentation/stats/ViewTest.java | 6 +- .../stats/MeasurementDescriptorToViewMap.java | 5 +- .../instrumentation/stats/MutableView.java | 5 +- .../stats/StatsManagerImplBase.java | 4 +- .../stats/StatsSerializer.java | 2 +- .../instrumentation/stats/ViewManager.java | 4 +- .../opencensus}/common/EventQueue.java | 10 ++-- .../opencensus}/common/MillisClock.java | 6 +- .../opencensus}/common/SimpleEventQueue.java | 2 +- .../opencensus}/internal/VarInt.java | 55 ++++++++----------- .../opencensus}/internal/package-info.java | 6 +- .../trace/BinaryPropagationHandlerImpl.java | 2 +- .../opencensus}/trace/RandomHandler.java | 2 +- .../opencensus}/trace/SpanFactoryImpl.java | 10 ++-- .../opencensus}/trace/SpanImpl.java | 8 +-- .../opencensus}/trace/TimestampConverter.java | 6 +- .../trace/TraceComponentImplBase.java | 11 ++-- .../opencensus}/trace/TraceConfigImpl.java | 2 +- .../opencensus}/trace/TraceExporterImpl.java | 6 +- .../opencensus}/trace/TracerImpl.java | 4 +- .../MeasurementDescriptorToViewMapTest.java | 6 +- .../stats/StatsContextFactoryTest.java | 8 +-- .../stats/StatsContextTest.java | 8 +-- .../stats/StatsManagerImplTest.java | 8 +-- .../BinaryPropagationHandlerImplTest.java | 2 +- .../trace/SpanFactoryImplTest.java | 10 ++-- .../opencensus}/trace/SpanImplTest.java | 14 ++--- .../trace/TimestampConverterTest.java | 6 +- .../trace/TraceComponentImplBaseTest.java | 8 +-- .../trace/TraceConfigImplTest.java | 4 +- .../trace/TraceExporterImplTest.java | 12 ++-- .../stats/StatsManagerImpl.java | 4 +- .../opencensus}/trace/TraceComponentImpl.java | 8 +-- .../trace/TraceComponentImplTest.java | 4 +- .../stats/StatsManagerImpl.java | 4 +- .../common/DisruptorEventQueue.java | 2 +- .../trace/ThreadLocalRandomHandler.java | 2 +- .../opencensus}/trace/TraceComponentImpl.java | 6 +- .../common/DisruptorEventQueueTest.java | 2 +- .../opencensus}/trace/TracingTest.java | 4 +- examples/build.gradle | 6 +- .../examples/stats/StatsRunner.java | 3 +- .../examples/trace/BasicContextTracing.java | 42 -------------- .../examples/trace/BasicScopedTracing.java | 41 -------------- .../examples/trace/BasicTracing.java | 35 ------------ .../trace/MultiSpansContextTracing.java | 12 ++-- .../trace/MultiSpansScopedTracing.java | 12 ++-- .../examples/trace/MultiSpansTracing.java | 10 ++-- settings.gradle | 4 ++ 147 files changed, 380 insertions(+), 513 deletions(-) create mode 100644 api/README.md create mode 100644 api/build.gradle rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/common/Clock.java (91%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/common/Duration.java (75%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/common/Function.java (77%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/common/Internal.java (81%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/common/NonThrowingCloseable.java (96%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/common/Timestamp.java (91%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/internal/Provider.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/internal/StringUtil.java (94%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/internal/TestClock.java (91%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/internal/ZeroTimeClock.java (85%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/internal/package-info.java (84%) rename {core => api}/src/main/java/io/opencensus/tags/TagKey.java (88%) rename {core => api}/src/main/java/io/opencensus/tags/TagMap.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/Annotation.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/AttributeValue.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/BinaryPropagationHandler.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/BlankSpan.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/ContextUtils.java (96%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/EndSpanOptions.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/Link.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/NetworkEvent.java (97%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/Sampler.java (97%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/Samplers.java (99%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/ScopedSpanHandle.java (93%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/Span.java (99%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/SpanBuilder.java (99%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/SpanContext.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/SpanData.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/SpanFactory.java (97%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/SpanId.java (99%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/StartSpanOptions.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/Status.java (99%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/TraceComponent.java (95%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/TraceConfig.java (99%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/TraceExporter.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/TraceId.java (99%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/TraceOptions.java (99%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/Tracer.java (98%) rename {core/src/main/java/com/google/instrumentation => api/src/main/java/io/opencensus}/trace/Tracing.java (91%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/common/DurationTest.java (92%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/common/TimestampTest.java (98%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/internal/ProviderTest.java (80%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/internal/StringUtilTest.java (94%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/internal/TestClockTest.java (91%) rename {core => api}/src/test/java/io/opencensus/tags/TagKeyTest.java (100%) rename {core => api}/src/test/java/io/opencensus/tags/TagMapTest.java (100%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/AnnotationTest.java (98%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/AttributeValueTest.java (98%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/BinaryPropagationHandlerTest.java (97%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/BlankSpanTest.java (98%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/ContextUtilsTest.java (96%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/EndSpanOptionsTest.java (98%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/LinkTest.java (96%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/NetworkEventTest.java (97%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/SamplersTest.java (97%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/ScopedSpanHandleTest.java (93%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/SpanBuilderTest.java (98%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/SpanContextTest.java (99%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/SpanDataTest.java (96%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/SpanIdTest.java (98%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/SpanTest.java (98%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/StartSpanOptionsTest.java (99%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/StatusTest.java (97%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/TraceComponentTest.java (94%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/TraceExporterTest.java (78%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/TraceIdTest.java (98%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/TraceOptionsTest.java (98%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/TraceParamsTest.java (96%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/TracerTest.java (98%) rename {core/src/test/java/com/google/instrumentation => api/src/test/java/io/opencensus}/trace/TracingTest.java (94%) rename benchmarks/src/jmh/java/{com/google/instrumentation => io/opencensus}/trace/BinaryPropagationHandlerImplBenchmark.java (98%) rename benchmarks/src/jmh/java/{com/google/instrumentation => io/opencensus}/trace/RecordTraceEventsNonSampledSpanBenchmark.java (98%) rename benchmarks/src/jmh/java/{com/google/instrumentation => io/opencensus}/trace/RecordTraceEventsSampledSpanBenchmark.java (98%) rename benchmarks/src/jmh/java/{com/google/instrumentation => io/opencensus}/trace/StartEndSpanBenchmark.java (98%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/common/EventQueue.java (82%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/common/MillisClock.java (88%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/common/SimpleEventQueue.java (95%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/internal/VarInt.java (88%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/internal/package-info.java (84%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/trace/BinaryPropagationHandlerImpl.java (99%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/trace/RandomHandler.java (96%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/trace/SpanFactoryImpl.java (94%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/trace/SpanImpl.java (98%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/trace/TimestampConverter.java (91%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/trace/TraceComponentImplBase.java (86%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/trace/TraceConfigImpl.java (96%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/trace/TraceExporterImpl.java (98%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/trace/TracerImpl.java (91%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/trace/BinaryPropagationHandlerImplTest.java (99%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/trace/SpanFactoryImplTest.java (96%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/trace/SpanImplTest.java (98%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/trace/TimestampConverterTest.java (92%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/trace/TraceComponentImplBaseTest.java (87%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/trace/TraceConfigImplTest.java (94%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/trace/TraceExporterImplTest.java (96%) rename core_impl_android/src/main/java/{com/google/instrumentation => io/opencensus}/trace/TraceComponentImpl.java (78%) rename core_impl_android/src/test/java/{com/google/instrumentation => io/opencensus}/trace/TraceComponentImplTest.java (93%) rename core_impl_java/src/main/java/{com/google/instrumentation => io/opencensus}/common/DisruptorEventQueue.java (99%) rename core_impl_java/src/main/java/{com/google/instrumentation => io/opencensus}/trace/ThreadLocalRandomHandler.java (95%) rename core_impl_java/src/main/java/{com/google/instrumentation => io/opencensus}/trace/TraceComponentImpl.java (85%) rename core_impl_java/src/test/java/{com/google/instrumentation => io/opencensus}/common/DisruptorEventQueueTest.java (98%) rename core_impl_java/src/test/java/{com/google/instrumentation => io/opencensus}/trace/TracingTest.java (93%) delete mode 100644 examples/src/main/java/com/google/instrumentation/examples/trace/BasicContextTracing.java delete mode 100644 examples/src/main/java/com/google/instrumentation/examples/trace/BasicScopedTracing.java delete mode 100644 examples/src/main/java/com/google/instrumentation/examples/trace/BasicTracing.java rename examples/src/main/java/{com/google/instrumentation => io/opencensus}/examples/trace/MultiSpansContextTracing.java (85%) rename examples/src/main/java/{com/google/instrumentation => io/opencensus}/examples/trace/MultiSpansScopedTracing.java (84%) rename examples/src/main/java/{com/google/instrumentation => io/opencensus}/examples/trace/MultiSpansTracing.java (85%) diff --git a/README.md b/README.md index dd7fb57ec1..965c98fe43 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -Instrumentation - A stats collection framework -====================================================== +OpenCensus - A stats collection and distributed tracing framework +================================================================= [![Build Status](https://travis-ci.org/census-instrumentation/instrumentation-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/instrumentation-java) [![Build status](https://ci.appveyor.com/api/projects/status/v5dbthkucuewsu33/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/instrumentation-java/branch/master) -Instrumentation provides a framework to define and collect stats against metrics and to -break those stats down across user-defined dimensions. The library is in alpha +OpenCensus provides a framework to define and collect stats against metrics and to +break those stats down across user-defined dimensions. The library is in alpha stage and the API is subject to change. diff --git a/all/build.gradle b/all/build.gradle index e1acc77430..3318927748 100644 --- a/all/build.gradle +++ b/all/build.gradle @@ -14,9 +14,10 @@ buildscript { // TODO(bdrutu): core_impl_android subproject currently isn't included because Javadoc cannot // handle multiple classes with the same name, such as StatsManagerImpl. def subprojects = [ - project(':core'), - project(':core_impl'), - project(':core_impl_java'), + project(':opencensus-api'), + project(':core'), + project(':core_impl'), + project(':core_impl_java'), ] for (subproject in rootProject.subprojects) { @@ -49,7 +50,7 @@ task jacocoMerge(type: JacocoMerge) { mustRunAfter(subprojects.jacocoTestReport.mustRunAfter) destinationFile = file("${buildDir}/jacoco/test.exec") executionData = files(subprojects.jacocoTestReport.executionData) - .filter { f -> f.exists() } + .filter { f -> f.exists() } } jacocoTestReport { diff --git a/api/README.md b/api/README.md new file mode 100644 index 0000000000..797ebe0ac9 --- /dev/null +++ b/api/README.md @@ -0,0 +1,6 @@ +OpenCensus API +====================================================== + +* Java 6 and Android compatible. +* The abstract classes in this directory can be subclassed to create alternative + implementations of the Instrumentation library. diff --git a/api/build.gradle b/api/build.gradle new file mode 100644 index 0000000000..7cfb33b26a --- /dev/null +++ b/api/build.gradle @@ -0,0 +1,11 @@ +description = 'OpenCensus: API' + +dependencies { + compile libraries.grpc_context, + libraries.guava + compileOnly libraries.auto_value + + signature "org.codehaus.mojo.signature:java16:+@signature" +} + +javadoc.exclude 'io/opencensus/**' \ No newline at end of file diff --git a/core/src/main/java/com/google/instrumentation/common/Clock.java b/api/src/main/java/io/opencensus/common/Clock.java similarity index 91% rename from core/src/main/java/com/google/instrumentation/common/Clock.java rename to api/src/main/java/io/opencensus/common/Clock.java index c57a964cce..420c519150 100644 --- a/core/src/main/java/com/google/instrumentation/common/Clock.java +++ b/api/src/main/java/io/opencensus/common/Clock.java @@ -11,11 +11,9 @@ * limitations under the License. */ -package com.google.instrumentation.common; +package io.opencensus.common; -/** - * Interface for getting the current time. - */ +/** Interface for getting the current time. */ public abstract class Clock { /** diff --git a/core/src/main/java/com/google/instrumentation/common/Duration.java b/api/src/main/java/io/opencensus/common/Duration.java similarity index 75% rename from core/src/main/java/com/google/instrumentation/common/Duration.java rename to api/src/main/java/io/opencensus/common/Duration.java index 657575da7c..c0e9f1bc70 100644 --- a/core/src/main/java/com/google/instrumentation/common/Duration.java +++ b/api/src/main/java/io/opencensus/common/Duration.java @@ -11,27 +11,24 @@ * limitations under the License. */ -package com.google.instrumentation.common; +package io.opencensus.common; /** - * Represents a signed, fixed-length span of time represented as a count of seconds and fractions - * of seconds at nanosecond resolution. It is independent of any calendar and concepts like "day" - * or "month". Range is approximately +-10,000 years. + * Represents a signed, fixed-length span of time represented as a count of seconds and fractions of + * seconds at nanosecond resolution. It is independent of any calendar and concepts like "day" or + * "month". Range is approximately +-10,000 years. */ public class Duration { /** * Creates a new time duration from given seconds and nanoseconds. * - * @param seconds Signed seconds of the span of time. Must be from -315,576,000,000 - * to +315,576,000,000 inclusive. - * - * @param nanos Signed fractions of a second at nanosecond resolution of the span - * of time. Durations less than one second are represented with a 0 - * `seconds` field and a positive or negative `nanos` field. For durations - * of one second or more, a non-zero value for the `nanos` field must be - * of the same sign as the `seconds` field. Must be from -999,999,999 - * to +999,999,999 inclusive. - * + * @param seconds Signed seconds of the span of time. Must be from -315,576,000,000 to + * +315,576,000,000 inclusive. + * @param nanos Signed fractions of a second at nanosecond resolution of the span of time. + * Durations less than one second are represented with a 0 `seconds` field and a positive or + * negative `nanos` field. For durations of one second or more, a non-zero value for the + * `nanos` field must be of the same sign as the `seconds` field. Must be from -999,999,999 to + * +999,999,999 inclusive. * @return new {@link Duration} with specified fields. For invalid inputs, a {@link Duration} of * zero is returned. */ @@ -48,25 +45,19 @@ public static Duration create(long seconds, int nanos) { return new Duration(seconds, nanos); } - /** - * Creates a new {@link Duration} from given milliseconds. - */ + /** Creates a new {@link Duration} from given milliseconds. */ public static Duration fromMillis(long millis) { long seconds = millis / NUM_MILLIS_PER_SECOND; int nanos = (int) (millis % NUM_MILLIS_PER_SECOND) * NUM_NANOS_PER_MILLI; return new Duration(seconds, nanos); } - /** - * Returns the number of seconds in the {@link Duration}. - */ + /** Returns the number of seconds in the {@link Duration}. */ public long getSeconds() { return seconds; } - /** - * Returns the number of nanoseconds in the {@link Duration}. - */ + /** Returns the number of nanoseconds in the {@link Duration}. */ public int getNanos() { return nanos; } diff --git a/core/src/main/java/com/google/instrumentation/common/Function.java b/api/src/main/java/io/opencensus/common/Function.java similarity index 77% rename from core/src/main/java/com/google/instrumentation/common/Function.java rename to api/src/main/java/io/opencensus/common/Function.java index 16471a5524..51bf845caf 100644 --- a/core/src/main/java/com/google/instrumentation/common/Function.java +++ b/api/src/main/java/io/opencensus/common/Function.java @@ -11,14 +11,14 @@ * limitations under the License. */ -package com.google.instrumentation.common; +package io.opencensus.common; /** * Used to specify matching functions for use encoding tagged unions (i.e. sum types) in Java. See - * {@link com.google.instrumentation.stats.ViewDescriptor} for an example of it's use. + * {@link io.opencensus.stats.ViewDescriptor} for an example of it's use. * - *

              Note: This class is based on the java.util.Function class added in Java 1.8. We cannot use - * the Function from Java 1.8 because this library is Java 1.6 compatible. + *

              Note: This class is based on the java.util.Function class added in Java 1.8. We cannot use the + * Function from Java 1.8 because this library is Java 1.6 compatible. */ public interface Function { B apply(A arg); diff --git a/core/src/main/java/com/google/instrumentation/common/Internal.java b/api/src/main/java/io/opencensus/common/Internal.java similarity index 81% rename from core/src/main/java/com/google/instrumentation/common/Internal.java rename to api/src/main/java/io/opencensus/common/Internal.java index 448c523573..9d540e21da 100644 --- a/core/src/main/java/com/google/instrumentation/common/Internal.java +++ b/api/src/main/java/io/opencensus/common/Internal.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.common; +package io.opencensus.common; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -26,12 +26,12 @@ @Internal @Retention(RetentionPolicy.SOURCE) @Target({ - ElementType.ANNOTATION_TYPE, - ElementType.CONSTRUCTOR, - ElementType.FIELD, - ElementType.METHOD, - ElementType.PACKAGE, - ElementType.TYPE}) + ElementType.ANNOTATION_TYPE, + ElementType.CONSTRUCTOR, + ElementType.FIELD, + ElementType.METHOD, + ElementType.PACKAGE, + ElementType.TYPE +}) @Documented -public @interface Internal { -} +public @interface Internal {} diff --git a/core/src/main/java/com/google/instrumentation/common/NonThrowingCloseable.java b/api/src/main/java/io/opencensus/common/NonThrowingCloseable.java similarity index 96% rename from core/src/main/java/com/google/instrumentation/common/NonThrowingCloseable.java rename to api/src/main/java/io/opencensus/common/NonThrowingCloseable.java index d00572bc96..1dac89f857 100644 --- a/core/src/main/java/com/google/instrumentation/common/NonThrowingCloseable.java +++ b/api/src/main/java/io/opencensus/common/NonThrowingCloseable.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.common; +package io.opencensus.common; import java.io.Closeable; diff --git a/core/src/main/java/com/google/instrumentation/common/Timestamp.java b/api/src/main/java/io/opencensus/common/Timestamp.java similarity index 91% rename from core/src/main/java/com/google/instrumentation/common/Timestamp.java rename to api/src/main/java/io/opencensus/common/Timestamp.java index 143f97663b..34c4c851dd 100644 --- a/core/src/main/java/com/google/instrumentation/common/Timestamp.java +++ b/api/src/main/java/io/opencensus/common/Timestamp.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.common; +package io.opencensus.common; import javax.annotation.concurrent.Immutable; @@ -42,13 +42,13 @@ private Timestamp(long seconds, int nanos) { /** * Creates a new timestamp from given seconds and nanoseconds. * - * @param seconds Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must - * be from from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive. - * @param nanos Non-negative fractions of a second at nanosecond resolution. Negative - * second values with fractions must still have non-negative nanos values that count forward - * in time. Must be from 0 to 999,999,999 inclusive. - * @return new {@link Timestamp} with specified fields. For invalid inputs, a {@link Timestamp} - * of zero is returned. + * @param seconds Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must be + * from from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive. + * @param nanos Non-negative fractions of a second at nanosecond resolution. Negative second + * values with fractions must still have non-negative nanos values that count forward in time. + * Must be from 0 to 999,999,999 inclusive. + * @return new {@link Timestamp} with specified fields. For invalid inputs, a {@link Timestamp} of + * zero is returned. */ public static Timestamp create(long seconds, int nanos) { if (seconds < -MAX_SECONDS || seconds > MAX_SECONDS) { diff --git a/core/src/main/java/com/google/instrumentation/internal/Provider.java b/api/src/main/java/io/opencensus/internal/Provider.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/internal/Provider.java rename to api/src/main/java/io/opencensus/internal/Provider.java index e98ea3478c..148b6c3876 100644 --- a/core/src/main/java/com/google/instrumentation/internal/Provider.java +++ b/api/src/main/java/io/opencensus/internal/Provider.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.internal; +package io.opencensus.internal; import java.util.ServiceConfigurationError; import java.util.logging.Level; diff --git a/core/src/main/java/com/google/instrumentation/internal/StringUtil.java b/api/src/main/java/io/opencensus/internal/StringUtil.java similarity index 94% rename from core/src/main/java/com/google/instrumentation/internal/StringUtil.java rename to api/src/main/java/io/opencensus/internal/StringUtil.java index 201d306696..48992ebd80 100644 --- a/core/src/main/java/com/google/instrumentation/internal/StringUtil.java +++ b/api/src/main/java/io/opencensus/internal/StringUtil.java @@ -11,11 +11,9 @@ * limitations under the License. */ -package com.google.instrumentation.internal; +package io.opencensus.internal; -/** - * Internal utility methods for working with tag keys, tag values, and metric names. - */ +/** Internal utility methods for working with tag keys, tag values, and metric names. */ public final class StringUtil { public static final int MAX_LENGTH = 255; diff --git a/core/src/main/java/com/google/instrumentation/internal/TestClock.java b/api/src/main/java/io/opencensus/internal/TestClock.java similarity index 91% rename from core/src/main/java/com/google/instrumentation/internal/TestClock.java rename to api/src/main/java/io/opencensus/internal/TestClock.java index 7cf922d155..d181da3a32 100644 --- a/core/src/main/java/com/google/instrumentation/internal/TestClock.java +++ b/api/src/main/java/io/opencensus/internal/TestClock.java @@ -11,18 +11,16 @@ * limitations under the License. */ -package com.google.instrumentation.internal; +package io.opencensus.internal; import com.google.common.math.LongMath; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.Duration; -import com.google.instrumentation.common.Timestamp; +import io.opencensus.common.Clock; +import io.opencensus.common.Duration; +import io.opencensus.common.Timestamp; import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.ThreadSafe; -/** - * A {@link Clock} that allows the time to be set for testing. - */ +/** A {@link Clock} that allows the time to be set for testing. */ @ThreadSafe public final class TestClock extends Clock { private static final int NUM_NANOS_PER_SECOND = 1000 * 1000 * 1000; diff --git a/core/src/main/java/com/google/instrumentation/internal/ZeroTimeClock.java b/api/src/main/java/io/opencensus/internal/ZeroTimeClock.java similarity index 85% rename from core/src/main/java/com/google/instrumentation/internal/ZeroTimeClock.java rename to api/src/main/java/io/opencensus/internal/ZeroTimeClock.java index 1d53a1e72c..022f02fe7f 100644 --- a/core/src/main/java/com/google/instrumentation/internal/ZeroTimeClock.java +++ b/api/src/main/java/io/opencensus/internal/ZeroTimeClock.java @@ -11,15 +11,13 @@ * limitations under the License. */ -package com.google.instrumentation.internal; +package io.opencensus.internal; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.Timestamp; +import io.opencensus.common.Clock; +import io.opencensus.common.Timestamp; import javax.annotation.concurrent.Immutable; -/** - * A {@link Clock} that always returns 0. - */ +/** A {@link Clock} that always returns 0. */ @Immutable public final class ZeroTimeClock extends Clock { private static final ZeroTimeClock INSTANCE = new ZeroTimeClock(); diff --git a/core/src/main/java/com/google/instrumentation/internal/package-info.java b/api/src/main/java/io/opencensus/internal/package-info.java similarity index 84% rename from core/src/main/java/com/google/instrumentation/internal/package-info.java rename to api/src/main/java/io/opencensus/internal/package-info.java index 849397059d..5fe0010d41 100644 --- a/core/src/main/java/com/google/instrumentation/internal/package-info.java +++ b/api/src/main/java/io/opencensus/internal/package-info.java @@ -15,7 +15,7 @@ * Interfaces and implementations that are internal to opencensus. * *

              All the content under this package and its subpackages are considered annotated with {@link - * com.google.instrumentation.common.Internal}. + * io.opencensus.common.Internal}. */ -@com.google.instrumentation.common.Internal -package com.google.instrumentation.internal; +@io.opencensus.common.Internal +package io.opencensus.internal; diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/api/src/main/java/io/opencensus/tags/TagKey.java similarity index 88% rename from core/src/main/java/io/opencensus/tags/TagKey.java rename to api/src/main/java/io/opencensus/tags/TagKey.java index 5775eae7da..970ee9250c 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/api/src/main/java/io/opencensus/tags/TagKey.java @@ -19,7 +19,7 @@ import static io.opencensus.tags.TagKey.TagType.TAG_STRING; import com.google.auto.value.AutoValue; -import com.google.instrumentation.internal.StringUtil; +import io.opencensus.internal.StringUtil; import javax.annotation.concurrent.Immutable; /** @@ -48,8 +48,8 @@ enum TagType { *

              The name must meet the following requirements: * *

                - *
              1. It cannot be longer than {@link #MAX_LENGTH}. - *
              2. It can only contain printable ASCII characters. + *
              3. It cannot be longer than {@link #MAX_LENGTH}. + *
              4. It can only contain printable ASCII characters. *
              * * @param name the name of the key. @@ -66,8 +66,8 @@ public static TagKey createStringKey(String name) { *

              The name must meet the following requirements: * *

                - *
              1. It cannot be longer than {@link #MAX_LENGTH}. - *
              2. It can only contain printable ASCII characters. + *
              3. It cannot be longer than {@link #MAX_LENGTH}. + *
              4. It can only contain printable ASCII characters. *
              * * @param name the name of the key. @@ -85,8 +85,8 @@ static TagKey createLongKey(String name) { *

              The name must meet the following requirements: * *

                - *
              1. It cannot be longer than {@link #MAX_LENGTH}. - *
              2. It can only contain printable ASCII characters. + *
              3. It cannot be longer than {@link #MAX_LENGTH}. + *
              4. It can only contain printable ASCII characters. *
              * * @param name the name of the key. diff --git a/core/src/main/java/io/opencensus/tags/TagMap.java b/api/src/main/java/io/opencensus/tags/TagMap.java similarity index 98% rename from core/src/main/java/io/opencensus/tags/TagMap.java rename to api/src/main/java/io/opencensus/tags/TagMap.java index 2b64880b17..8edbda0d0e 100644 --- a/core/src/main/java/io/opencensus/tags/TagMap.java +++ b/api/src/main/java/io/opencensus/tags/TagMap.java @@ -15,7 +15,7 @@ import static com.google.common.base.Preconditions.checkArgument; -import com.google.instrumentation.internal.StringUtil; +import io.opencensus.internal.StringUtil; import io.opencensus.tags.TagKey.TagType; import java.util.Collections; import java.util.HashMap; diff --git a/core/src/main/java/com/google/instrumentation/trace/Annotation.java b/api/src/main/java/io/opencensus/trace/Annotation.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/trace/Annotation.java rename to api/src/main/java/io/opencensus/trace/Annotation.java index cfd0e27f89..f72070e815 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Annotation.java +++ b/api/src/main/java/io/opencensus/trace/Annotation.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/trace/AttributeValue.java b/api/src/main/java/io/opencensus/trace/AttributeValue.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/trace/AttributeValue.java rename to api/src/main/java/io/opencensus/trace/AttributeValue.java index 09b749cd87..f66fd42597 100644 --- a/core/src/main/java/com/google/instrumentation/trace/AttributeValue.java +++ b/api/src/main/java/io/opencensus/trace/AttributeValue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/trace/BinaryPropagationHandler.java b/api/src/main/java/io/opencensus/trace/BinaryPropagationHandler.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/trace/BinaryPropagationHandler.java rename to api/src/main/java/io/opencensus/trace/BinaryPropagationHandler.java index 7ef9900b70..bc86dd7f9e 100644 --- a/core/src/main/java/com/google/instrumentation/trace/BinaryPropagationHandler.java +++ b/api/src/main/java/io/opencensus/trace/BinaryPropagationHandler.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/trace/BlankSpan.java b/api/src/main/java/io/opencensus/trace/BlankSpan.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/trace/BlankSpan.java rename to api/src/main/java/io/opencensus/trace/BlankSpan.java index e4a195fe8b..40e49551b7 100644 --- a/core/src/main/java/com/google/instrumentation/trace/BlankSpan.java +++ b/api/src/main/java/io/opencensus/trace/BlankSpan.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import java.util.Map; import javax.annotation.concurrent.Immutable; diff --git a/core/src/main/java/com/google/instrumentation/trace/ContextUtils.java b/api/src/main/java/io/opencensus/trace/ContextUtils.java similarity index 96% rename from core/src/main/java/com/google/instrumentation/trace/ContextUtils.java rename to api/src/main/java/io/opencensus/trace/ContextUtils.java index bab9c189db..c5331563ae 100644 --- a/core/src/main/java/com/google/instrumentation/trace/ContextUtils.java +++ b/api/src/main/java/io/opencensus/trace/ContextUtils.java @@ -11,10 +11,10 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; -import com.google.instrumentation.common.NonThrowingCloseable; import io.grpc.Context; +import io.opencensus.common.NonThrowingCloseable; /** * Util methods/functionality to interact with the {@link io.grpc.Context}. diff --git a/core/src/main/java/com/google/instrumentation/trace/EndSpanOptions.java b/api/src/main/java/io/opencensus/trace/EndSpanOptions.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/trace/EndSpanOptions.java rename to api/src/main/java/io/opencensus/trace/EndSpanOptions.java index 25f6e7c6d3..e58a06c381 100644 --- a/core/src/main/java/com/google/instrumentation/trace/EndSpanOptions.java +++ b/api/src/main/java/io/opencensus/trace/EndSpanOptions.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/trace/Link.java b/api/src/main/java/io/opencensus/trace/Link.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/trace/Link.java rename to api/src/main/java/io/opencensus/trace/Link.java index 2934a0832f..d582b68b8d 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Link.java +++ b/api/src/main/java/io/opencensus/trace/Link.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import com.google.auto.value.AutoValue; import javax.annotation.concurrent.Immutable; diff --git a/core/src/main/java/com/google/instrumentation/trace/NetworkEvent.java b/api/src/main/java/io/opencensus/trace/NetworkEvent.java similarity index 97% rename from core/src/main/java/com/google/instrumentation/trace/NetworkEvent.java rename to api/src/main/java/io/opencensus/trace/NetworkEvent.java index 19730a184b..10687074c4 100644 --- a/core/src/main/java/com/google/instrumentation/trace/NetworkEvent.java +++ b/api/src/main/java/io/opencensus/trace/NetworkEvent.java @@ -11,12 +11,12 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; import com.google.auto.value.AutoValue; -import com.google.instrumentation.common.Timestamp; +import io.opencensus.common.Timestamp; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; diff --git a/core/src/main/java/com/google/instrumentation/trace/Sampler.java b/api/src/main/java/io/opencensus/trace/Sampler.java similarity index 97% rename from core/src/main/java/com/google/instrumentation/trace/Sampler.java rename to api/src/main/java/io/opencensus/trace/Sampler.java index eec1cbd74d..e5014fa440 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Sampler.java +++ b/api/src/main/java/io/opencensus/trace/Sampler.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import java.util.List; import javax.annotation.Nullable; diff --git a/core/src/main/java/com/google/instrumentation/trace/Samplers.java b/api/src/main/java/io/opencensus/trace/Samplers.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/trace/Samplers.java rename to api/src/main/java/io/opencensus/trace/Samplers.java index 59b637f512..33c2a0065d 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Samplers.java +++ b/api/src/main/java/io/opencensus/trace/Samplers.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkArgument; diff --git a/core/src/main/java/com/google/instrumentation/trace/ScopedSpanHandle.java b/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java similarity index 93% rename from core/src/main/java/com/google/instrumentation/trace/ScopedSpanHandle.java rename to api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java index 2838071be2..965c4d9864 100644 --- a/core/src/main/java/com/google/instrumentation/trace/ScopedSpanHandle.java +++ b/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java @@ -11,9 +11,9 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; -import com.google.instrumentation.common.NonThrowingCloseable; +import io.opencensus.common.NonThrowingCloseable; /** * Defines a scope of code where the given {@link Span} is in the current context. The scope is diff --git a/core/src/main/java/com/google/instrumentation/trace/Span.java b/api/src/main/java/io/opencensus/trace/Span.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/trace/Span.java rename to api/src/main/java/io/opencensus/trace/Span.java index 6305c80aa1..76dcd9c7e6 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Span.java +++ b/api/src/main/java/io/opencensus/trace/Span.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/trace/SpanBuilder.java b/api/src/main/java/io/opencensus/trace/SpanBuilder.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/trace/SpanBuilder.java rename to api/src/main/java/io/opencensus/trace/SpanBuilder.java index 601b93109f..4b988dfc33 100644 --- a/core/src/main/java/com/google/instrumentation/trace/SpanBuilder.java +++ b/api/src/main/java/io/opencensus/trace/SpanBuilder.java @@ -11,9 +11,9 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; -import com.google.instrumentation.common.NonThrowingCloseable; +import io.opencensus.common.NonThrowingCloseable; import java.util.List; import javax.annotation.Nullable; diff --git a/core/src/main/java/com/google/instrumentation/trace/SpanContext.java b/api/src/main/java/io/opencensus/trace/SpanContext.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/trace/SpanContext.java rename to api/src/main/java/io/opencensus/trace/SpanContext.java index 4cec748bc5..4902f15f3c 100644 --- a/core/src/main/java/com/google/instrumentation/trace/SpanContext.java +++ b/api/src/main/java/io/opencensus/trace/SpanContext.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; diff --git a/core/src/main/java/com/google/instrumentation/trace/SpanData.java b/api/src/main/java/io/opencensus/trace/SpanData.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/trace/SpanData.java rename to api/src/main/java/io/opencensus/trace/SpanData.java index 8435709c3d..f9a8140f38 100644 --- a/core/src/main/java/com/google/instrumentation/trace/SpanData.java +++ b/api/src/main/java/io/opencensus/trace/SpanData.java @@ -11,12 +11,12 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; import com.google.auto.value.AutoValue; -import com.google.instrumentation.common.Timestamp; +import io.opencensus.common.Timestamp; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; diff --git a/core/src/main/java/com/google/instrumentation/trace/SpanFactory.java b/api/src/main/java/io/opencensus/trace/SpanFactory.java similarity index 97% rename from core/src/main/java/com/google/instrumentation/trace/SpanFactory.java rename to api/src/main/java/io/opencensus/trace/SpanFactory.java index 57c59c39e7..aca5bd852b 100644 --- a/core/src/main/java/com/google/instrumentation/trace/SpanFactory.java +++ b/api/src/main/java/io/opencensus/trace/SpanFactory.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import javax.annotation.Nullable; diff --git a/core/src/main/java/com/google/instrumentation/trace/SpanId.java b/api/src/main/java/io/opencensus/trace/SpanId.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/trace/SpanId.java rename to api/src/main/java/io/opencensus/trace/SpanId.java index 400ffdc35e..8128c9d7de 100644 --- a/core/src/main/java/com/google/instrumentation/trace/SpanId.java +++ b/api/src/main/java/io/opencensus/trace/SpanId.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/trace/StartSpanOptions.java b/api/src/main/java/io/opencensus/trace/StartSpanOptions.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/trace/StartSpanOptions.java rename to api/src/main/java/io/opencensus/trace/StartSpanOptions.java index 18d9e69138..01bc8885f7 100644 --- a/core/src/main/java/com/google/instrumentation/trace/StartSpanOptions.java +++ b/api/src/main/java/io/opencensus/trace/StartSpanOptions.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import com.google.common.base.Objects; import java.util.Collections; diff --git a/core/src/main/java/com/google/instrumentation/trace/Status.java b/api/src/main/java/io/opencensus/trace/Status.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/trace/Status.java rename to api/src/main/java/io/opencensus/trace/Status.java index 2c72a85680..22cb52875a 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Status.java +++ b/api/src/main/java/io/opencensus/trace/Status.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java b/api/src/main/java/io/opencensus/trace/TraceComponent.java similarity index 95% rename from core/src/main/java/com/google/instrumentation/trace/TraceComponent.java rename to api/src/main/java/io/opencensus/trace/TraceComponent.java index 885f0dea92..1829417f5a 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceComponent.java +++ b/api/src/main/java/io/opencensus/trace/TraceComponent.java @@ -11,10 +11,10 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.internal.ZeroTimeClock; +import io.opencensus.common.Clock; +import io.opencensus.internal.ZeroTimeClock; /** * Class that holds the implementation instances for {@link Tracer}, {@link diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java b/api/src/main/java/io/opencensus/trace/TraceConfig.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/trace/TraceConfig.java rename to api/src/main/java/io/opencensus/trace/TraceConfig.java index de3177b187..41fa75b802 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceConfig.java +++ b/api/src/main/java/io/opencensus/trace/TraceConfig.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java b/api/src/main/java/io/opencensus/trace/TraceExporter.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/trace/TraceExporter.java rename to api/src/main/java/io/opencensus/trace/TraceExporter.java index d610ca7e11..7da2d60408 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceExporter.java +++ b/api/src/main/java/io/opencensus/trace/TraceExporter.java @@ -11,13 +11,13 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import com.google.auto.value.AutoValue; -import com.google.instrumentation.trace.Status.CanonicalCode; +import io.opencensus.trace.Status.CanonicalCode; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -550,7 +550,7 @@ public abstract static class ServiceHandler { *
              {@code
                  * public static void main(String[] args) {
                  *   Tracing.getTraceExporter().registerServiceHandler(
              -   *       "com.google.instrumentation.LoggingServiceHandler", LoggingServiceHandler.getInstance());
              +   *       "io.opencensus.LoggingServiceHandler", LoggingServiceHandler.getInstance());
                  *   // ...
                  * }
                  * }
              @@ -559,8 +559,7 @@ public abstract static class ServiceHandler { public static final class LoggingServiceHandler extends ServiceHandler { private static final Logger logger = Logger.getLogger(LoggingServiceHandler.class.getName()); - private static final String SERVICE_NAME = - "com.google.instrumentation.trace.LoggingServiceHandler"; + private static final String SERVICE_NAME = "io.opencensus.trace.LoggingServiceHandler"; private static final LoggingServiceHandler INSTANCE = new LoggingServiceHandler(); private LoggingServiceHandler() {} diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceId.java b/api/src/main/java/io/opencensus/trace/TraceId.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/trace/TraceId.java rename to api/src/main/java/io/opencensus/trace/TraceId.java index ab3c2d52ee..5684efdfda 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceId.java +++ b/api/src/main/java/io/opencensus/trace/TraceId.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/trace/TraceOptions.java b/api/src/main/java/io/opencensus/trace/TraceOptions.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/trace/TraceOptions.java rename to api/src/main/java/io/opencensus/trace/TraceOptions.java index cdfec7225f..6fc04bb92c 100644 --- a/core/src/main/java/com/google/instrumentation/trace/TraceOptions.java +++ b/api/src/main/java/io/opencensus/trace/TraceOptions.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkElementIndex; diff --git a/core/src/main/java/com/google/instrumentation/trace/Tracer.java b/api/src/main/java/io/opencensus/trace/Tracer.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/trace/Tracer.java rename to api/src/main/java/io/opencensus/trace/Tracer.java index 2c1ccfc66d..56c4280d96 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Tracer.java +++ b/api/src/main/java/io/opencensus/trace/Tracer.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.instrumentation.common.NonThrowingCloseable; +import io.opencensus.common.NonThrowingCloseable; import javax.annotation.Nullable; /** diff --git a/core/src/main/java/com/google/instrumentation/trace/Tracing.java b/api/src/main/java/io/opencensus/trace/Tracing.java similarity index 91% rename from core/src/main/java/com/google/instrumentation/trace/Tracing.java rename to api/src/main/java/io/opencensus/trace/Tracing.java index 8759d38b7c..e6d34a45f4 100644 --- a/core/src/main/java/com/google/instrumentation/trace/Tracing.java +++ b/api/src/main/java/io/opencensus/trace/Tracing.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import com.google.common.annotations.VisibleForTesting; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.internal.Provider; +import io.opencensus.common.Clock; +import io.opencensus.internal.Provider; import java.util.logging.Level; import java.util.logging.Logger; @@ -76,7 +76,7 @@ static TraceComponent loadTraceComponent(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. return Provider.createInstance( - Class.forName("com.google.instrumentation.trace.TraceComponentImpl", true, classLoader), + Class.forName("io.opencensus.trace.TraceComponentImpl", true, classLoader), TraceComponent.class); } catch (ClassNotFoundException e) { logger.log(Level.FINE, "Using default implementation for TraceComponent.", e); diff --git a/core/src/test/java/com/google/instrumentation/common/DurationTest.java b/api/src/test/java/io/opencensus/common/DurationTest.java similarity index 92% rename from core/src/test/java/com/google/instrumentation/common/DurationTest.java rename to api/src/test/java/io/opencensus/common/DurationTest.java index 4ba9806c8b..b9861eea4b 100644 --- a/core/src/test/java/com/google/instrumentation/common/DurationTest.java +++ b/api/src/test/java/io/opencensus/common/DurationTest.java @@ -1,4 +1,4 @@ -package com.google.instrumentation.common; +package io.opencensus.common; import static com.google.common.truth.Truth.assertThat; @@ -15,14 +15,10 @@ public void testDurationCreate() { assertThat(Duration.create(24, 42).getNanos()).isEqualTo(42); assertThat(Duration.create(-24, -42).getSeconds()).isEqualTo(-24); assertThat(Duration.create(-24, -42).getNanos()).isEqualTo(-42); - assertThat(Duration.create(315576000000L, 999999999).getSeconds()) - .isEqualTo(315576000000L); - assertThat(Duration.create(315576000000L, 999999999).getNanos()) - .isEqualTo(999999999); - assertThat(Duration.create(-315576000000L, -999999999).getSeconds()) - .isEqualTo(-315576000000L); - assertThat(Duration.create(-315576000000L, -999999999).getNanos()) - .isEqualTo(-999999999); + assertThat(Duration.create(315576000000L, 999999999).getSeconds()).isEqualTo(315576000000L); + assertThat(Duration.create(315576000000L, 999999999).getNanos()).isEqualTo(999999999); + assertThat(Duration.create(-315576000000L, -999999999).getSeconds()).isEqualTo(-315576000000L); + assertThat(Duration.create(-315576000000L, -999999999).getNanos()).isEqualTo(-999999999); } @Test diff --git a/core/src/test/java/com/google/instrumentation/common/TimestampTest.java b/api/src/test/java/io/opencensus/common/TimestampTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/common/TimestampTest.java rename to api/src/test/java/io/opencensus/common/TimestampTest.java index d41733a711..5a02264b30 100644 --- a/core/src/test/java/com/google/instrumentation/common/TimestampTest.java +++ b/api/src/test/java/io/opencensus/common/TimestampTest.java @@ -1,4 +1,4 @@ -package com.google.instrumentation.common; +package io.opencensus.common; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/internal/ProviderTest.java b/api/src/test/java/io/opencensus/internal/ProviderTest.java similarity index 80% rename from core/src/test/java/com/google/instrumentation/internal/ProviderTest.java rename to api/src/test/java/io/opencensus/internal/ProviderTest.java index d8498b4324..f6aba5ec9b 100644 --- a/core/src/test/java/com/google/instrumentation/internal/ProviderTest.java +++ b/api/src/test/java/io/opencensus/internal/ProviderTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.internal; +package io.opencensus.internal; import static com.google.common.truth.Truth.assertThat; @@ -46,16 +46,14 @@ public MyInterfaceImpl() {} @Test public void testGoodClass() { assertThat( - Provider.newInstance( - "com.google.instrumentation.internal.ProviderTest$GoodClass", null)) + Provider.newInstance("io.opencensus.internal.ProviderTest$GoodClass", null)) .isNotNull(); } @Test public void testBadClass() { assertThat( - Provider.newInstance( - "com.google.instrumentation.internal.ProviderTest$BadClass", null)) + Provider.newInstance("io.opencensus.internal.ProviderTest$BadClass", null)) .isNull(); } @@ -63,7 +61,7 @@ public void testBadClass() { public void createInstance_ThrowsErrorWhenClassIsPrivate() throws ClassNotFoundException { Provider.createInstance( Class.forName( - "com.google.instrumentation.internal.ProviderTest$PrivateClass", + "io.opencensus.internal.ProviderTest$PrivateClass", true, Provider.getCorrectClassLoader(ProviderTest.class)), PrivateClass.class); @@ -74,7 +72,7 @@ public void createInstance_ThrowsErrorWhenClassHasPrivateConstructor() throws ClassNotFoundException { Provider.createInstance( Class.forName( - "com.google.instrumentation.internal.ProviderTest$PrivateConstructorClass", + "io.opencensus.internal.ProviderTest$PrivateConstructorClass", true, Provider.getCorrectClassLoader(ProviderTest.class)), PrivateConstructorClass.class); @@ -85,7 +83,7 @@ public void createInstance_ThrowsErrorWhenClassDoesNotHaveDefaultConstructor() throws ClassNotFoundException { Provider.createInstance( Class.forName( - "com.google.instrumentation.internal.ProviderTest$NoDefaultConstructorClass", + "io.opencensus.internal.ProviderTest$NoDefaultConstructorClass", true, Provider.getCorrectClassLoader(ProviderTest.class)), NoDefaultConstructorClass.class); @@ -95,7 +93,7 @@ public void createInstance_ThrowsErrorWhenClassDoesNotHaveDefaultConstructor() public void createInstance_ThrowsErrorWhenClassIsNotASubclass() throws ClassNotFoundException { Provider.createInstance( Class.forName( - "com.google.instrumentation.internal.ProviderTest$GoodClass", + "io.opencensus.internal.ProviderTest$GoodClass", true, Provider.getCorrectClassLoader(ProviderTest.class)), MyInterface.class); @@ -106,7 +104,7 @@ public void createInstance_GoodClass() throws ClassNotFoundException { assertThat( Provider.createInstance( Class.forName( - "com.google.instrumentation.internal.ProviderTest$GoodClass", + "io.opencensus.internal.ProviderTest$GoodClass", true, Provider.getCorrectClassLoader(ProviderTest.class)), GoodClass.class)) @@ -118,7 +116,7 @@ public void createInstance_GoodSubclass() throws ClassNotFoundException { assertThat( Provider.createInstance( Class.forName( - "com.google.instrumentation.internal.ProviderTest$MyInterfaceImpl", + "io.opencensus.internal.ProviderTest$MyInterfaceImpl", true, Provider.getCorrectClassLoader(ProviderTest.class)), MyInterface.class)) diff --git a/core/src/test/java/com/google/instrumentation/internal/StringUtilTest.java b/api/src/test/java/io/opencensus/internal/StringUtilTest.java similarity index 94% rename from core/src/test/java/com/google/instrumentation/internal/StringUtilTest.java rename to api/src/test/java/io/opencensus/internal/StringUtilTest.java index 26b99af955..1414439177 100644 --- a/core/src/test/java/com/google/instrumentation/internal/StringUtilTest.java +++ b/api/src/test/java/io/opencensus/internal/StringUtilTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.internal; +package io.opencensus.internal; import static com.google.common.truth.Truth.assertThat; @@ -20,9 +20,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link StringUtil}. - */ +/** Tests for {@link StringUtil}. */ @RunWith(JUnit4.class) public final class StringUtilTest { @Test diff --git a/core/src/test/java/com/google/instrumentation/internal/TestClockTest.java b/api/src/test/java/io/opencensus/internal/TestClockTest.java similarity index 91% rename from core/src/test/java/com/google/instrumentation/internal/TestClockTest.java rename to api/src/test/java/io/opencensus/internal/TestClockTest.java index 0fee071a11..fe3f80cb65 100644 --- a/core/src/test/java/com/google/instrumentation/internal/TestClockTest.java +++ b/api/src/test/java/io/opencensus/internal/TestClockTest.java @@ -11,19 +11,17 @@ * limitations under the License. */ -package com.google.instrumentation.internal; +package io.opencensus.internal; import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.Duration; -import com.google.instrumentation.common.Timestamp; +import io.opencensus.common.Duration; +import io.opencensus.common.Timestamp; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link TestClock}. - */ +/** Tests for {@link TestClock}. */ @RunWith(JUnit4.class) public final class TestClockTest { private static final int NUM_NANOS_PER_SECOND = 1000 * 1000 * 1000; diff --git a/core/src/test/java/io/opencensus/tags/TagKeyTest.java b/api/src/test/java/io/opencensus/tags/TagKeyTest.java similarity index 100% rename from core/src/test/java/io/opencensus/tags/TagKeyTest.java rename to api/src/test/java/io/opencensus/tags/TagKeyTest.java diff --git a/core/src/test/java/io/opencensus/tags/TagMapTest.java b/api/src/test/java/io/opencensus/tags/TagMapTest.java similarity index 100% rename from core/src/test/java/io/opencensus/tags/TagMapTest.java rename to api/src/test/java/io/opencensus/tags/TagMapTest.java diff --git a/core/src/test/java/com/google/instrumentation/trace/AnnotationTest.java b/api/src/test/java/io/opencensus/trace/AnnotationTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/trace/AnnotationTest.java rename to api/src/test/java/io/opencensus/trace/AnnotationTest.java index 4c43e0b52c..fbfe5fd354 100644 --- a/core/src/test/java/com/google/instrumentation/trace/AnnotationTest.java +++ b/api/src/test/java/io/opencensus/trace/AnnotationTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/trace/AttributeValueTest.java b/api/src/test/java/io/opencensus/trace/AttributeValueTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/trace/AttributeValueTest.java rename to api/src/test/java/io/opencensus/trace/AttributeValueTest.java index b609a5ce3f..7a999604e4 100644 --- a/core/src/test/java/com/google/instrumentation/trace/AttributeValueTest.java +++ b/api/src/test/java/io/opencensus/trace/AttributeValueTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/trace/BinaryPropagationHandlerTest.java b/api/src/test/java/io/opencensus/trace/BinaryPropagationHandlerTest.java similarity index 97% rename from core/src/test/java/com/google/instrumentation/trace/BinaryPropagationHandlerTest.java rename to api/src/test/java/io/opencensus/trace/BinaryPropagationHandlerTest.java index 080a58e3ef..d75effb695 100644 --- a/core/src/test/java/com/google/instrumentation/trace/BinaryPropagationHandlerTest.java +++ b/api/src/test/java/io/opencensus/trace/BinaryPropagationHandlerTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/trace/BlankSpanTest.java b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/trace/BlankSpanTest.java rename to api/src/test/java/io/opencensus/trace/BlankSpanTest.java index 036e02e84b..252d02ff9f 100644 --- a/core/src/test/java/com/google/instrumentation/trace/BlankSpanTest.java +++ b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/trace/ContextUtilsTest.java b/api/src/test/java/io/opencensus/trace/ContextUtilsTest.java similarity index 96% rename from core/src/test/java/com/google/instrumentation/trace/ContextUtilsTest.java rename to api/src/test/java/io/opencensus/trace/ContextUtilsTest.java index 4dabad2468..e4513d740d 100644 --- a/core/src/test/java/com/google/instrumentation/trace/ContextUtilsTest.java +++ b/api/src/test/java/io/opencensus/trace/ContextUtilsTest.java @@ -11,12 +11,12 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.NonThrowingCloseable; import io.grpc.Context; +import io.opencensus.common.NonThrowingCloseable; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core/src/test/java/com/google/instrumentation/trace/EndSpanOptionsTest.java b/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/trace/EndSpanOptionsTest.java rename to api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java index dc59808d95..d531fba551 100644 --- a/core/src/test/java/com/google/instrumentation/trace/EndSpanOptionsTest.java +++ b/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/trace/LinkTest.java b/api/src/test/java/io/opencensus/trace/LinkTest.java similarity index 96% rename from core/src/test/java/com/google/instrumentation/trace/LinkTest.java rename to api/src/test/java/io/opencensus/trace/LinkTest.java index e29cd2aab4..e1289f33a1 100644 --- a/core/src/test/java/com/google/instrumentation/trace/LinkTest.java +++ b/api/src/test/java/io/opencensus/trace/LinkTest.java @@ -11,12 +11,12 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import com.google.instrumentation.trace.Link.Type; +import io.opencensus.trace.Link.Type; import java.util.Random; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core/src/test/java/com/google/instrumentation/trace/NetworkEventTest.java b/api/src/test/java/io/opencensus/trace/NetworkEventTest.java similarity index 97% rename from core/src/test/java/com/google/instrumentation/trace/NetworkEventTest.java rename to api/src/test/java/io/opencensus/trace/NetworkEventTest.java index 1d6cee73b9..946e8ce142 100644 --- a/core/src/test/java/com/google/instrumentation/trace/NetworkEventTest.java +++ b/api/src/test/java/io/opencensus/trace/NetworkEventTest.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.Timestamp; +import io.opencensus.common.Timestamp; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core/src/test/java/com/google/instrumentation/trace/SamplersTest.java b/api/src/test/java/io/opencensus/trace/SamplersTest.java similarity index 97% rename from core/src/test/java/com/google/instrumentation/trace/SamplersTest.java rename to api/src/test/java/io/opencensus/trace/SamplersTest.java index aa361ef8ba..af7fcaf596 100644 --- a/core/src/test/java/com/google/instrumentation/trace/SamplersTest.java +++ b/api/src/test/java/io/opencensus/trace/SamplersTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; @@ -162,7 +162,6 @@ public void probabilitySamper_SamplesWithProbability() { @Test public void probabilitySampler_ToString() { - assertThat((Samplers.probabilitySampler(0.5)).toString()) - .contains("0.5"); + assertThat((Samplers.probabilitySampler(0.5)).toString()).contains("0.5"); } } diff --git a/core/src/test/java/com/google/instrumentation/trace/ScopedSpanHandleTest.java b/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java similarity index 93% rename from core/src/test/java/com/google/instrumentation/trace/ScopedSpanHandleTest.java rename to api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java index df04cd2ead..8922f4c2d2 100644 --- a/core/src/test/java/com/google/instrumentation/trace/ScopedSpanHandleTest.java +++ b/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java @@ -11,13 +11,13 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.same; import static org.mockito.Mockito.verify; -import com.google.instrumentation.common.NonThrowingCloseable; +import io.opencensus.common.NonThrowingCloseable; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core/src/test/java/com/google/instrumentation/trace/SpanBuilderTest.java b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/trace/SpanBuilderTest.java rename to api/src/test/java/io/opencensus/trace/SpanBuilderTest.java index 2044d87aa2..ccd3d80620 100644 --- a/core/src/test/java/com/google/instrumentation/trace/SpanBuilderTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.eq; @@ -20,7 +20,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.google.instrumentation.common.NonThrowingCloseable; +import io.opencensus.common.NonThrowingCloseable; import java.util.Arrays; import java.util.List; import java.util.Random; diff --git a/core/src/test/java/com/google/instrumentation/trace/SpanContextTest.java b/api/src/test/java/io/opencensus/trace/SpanContextTest.java similarity index 99% rename from core/src/test/java/com/google/instrumentation/trace/SpanContextTest.java rename to api/src/test/java/io/opencensus/trace/SpanContextTest.java index 22d1be2f85..c0eb5d407f 100644 --- a/core/src/test/java/com/google/instrumentation/trace/SpanContextTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanContextTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/trace/SpanDataTest.java b/api/src/test/java/io/opencensus/trace/SpanDataTest.java similarity index 96% rename from core/src/test/java/com/google/instrumentation/trace/SpanDataTest.java rename to api/src/test/java/io/opencensus/trace/SpanDataTest.java index 6303dc1b91..7a7f7899c5 100644 --- a/core/src/test/java/com/google/instrumentation/trace/SpanDataTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanDataTest.java @@ -11,17 +11,17 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import com.google.instrumentation.common.Timestamp; -import com.google.instrumentation.trace.Link.Type; -import com.google.instrumentation.trace.SpanData.Attributes; -import com.google.instrumentation.trace.SpanData.Links; -import com.google.instrumentation.trace.SpanData.TimedEvent; -import com.google.instrumentation.trace.SpanData.TimedEvents; +import io.opencensus.common.Timestamp; +import io.opencensus.trace.Link.Type; +import io.opencensus.trace.SpanData.Attributes; +import io.opencensus.trace.SpanData.Links; +import io.opencensus.trace.SpanData.TimedEvent; +import io.opencensus.trace.SpanData.TimedEvents; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; diff --git a/core/src/test/java/com/google/instrumentation/trace/SpanIdTest.java b/api/src/test/java/io/opencensus/trace/SpanIdTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/trace/SpanIdTest.java rename to api/src/test/java/io/opencensus/trace/SpanIdTest.java index d122bef6d0..a35fddce62 100644 --- a/core/src/test/java/com/google/instrumentation/trace/SpanIdTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanIdTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/trace/SpanTest.java b/api/src/test/java/io/opencensus/trace/SpanTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/trace/SpanTest.java rename to api/src/test/java/io/opencensus/trace/SpanTest.java index befe182dd6..c8f7cb503f 100644 --- a/core/src/test/java/com/google/instrumentation/trace/SpanTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.same; diff --git a/core/src/test/java/com/google/instrumentation/trace/StartSpanOptionsTest.java b/api/src/test/java/io/opencensus/trace/StartSpanOptionsTest.java similarity index 99% rename from core/src/test/java/com/google/instrumentation/trace/StartSpanOptionsTest.java rename to api/src/test/java/io/opencensus/trace/StartSpanOptionsTest.java index 48f24d343c..b91e78ee1c 100644 --- a/core/src/test/java/com/google/instrumentation/trace/StartSpanOptionsTest.java +++ b/api/src/test/java/io/opencensus/trace/StartSpanOptionsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/trace/StatusTest.java b/api/src/test/java/io/opencensus/trace/StatusTest.java similarity index 97% rename from core/src/test/java/com/google/instrumentation/trace/StatusTest.java rename to api/src/test/java/io/opencensus/trace/StatusTest.java index 42084cb816..c66a3428f4 100644 --- a/core/src/test/java/com/google/instrumentation/trace/StatusTest.java +++ b/api/src/test/java/io/opencensus/trace/StatusTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java b/api/src/test/java/io/opencensus/trace/TraceComponentTest.java similarity index 94% rename from core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java rename to api/src/test/java/io/opencensus/trace/TraceComponentTest.java index 9a0db1bf41..106cb965b6 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TraceComponentTest.java +++ b/api/src/test/java/io/opencensus/trace/TraceComponentTest.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.internal.ZeroTimeClock; +import io.opencensus.internal.ZeroTimeClock; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core/src/test/java/com/google/instrumentation/trace/TraceExporterTest.java b/api/src/test/java/io/opencensus/trace/TraceExporterTest.java similarity index 78% rename from core/src/test/java/com/google/instrumentation/trace/TraceExporterTest.java rename to api/src/test/java/io/opencensus/trace/TraceExporterTest.java index 03adacf75f..3837a1ada6 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TraceExporterTest.java +++ b/api/src/test/java/io/opencensus/trace/TraceExporterTest.java @@ -11,13 +11,13 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; -import com.google.instrumentation.trace.TraceExporter.LoggingServiceHandler; +import io.opencensus.trace.TraceExporter.LoggingServiceHandler; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -40,10 +40,8 @@ public void registerUnregisterLoggingService() { LoggingServiceHandler.registerService(traceExporter); verify(traceExporter) .registerServiceHandler( - eq("com.google.instrumentation.trace.LoggingServiceHandler"), - any(LoggingServiceHandler.class)); + eq("io.opencensus.trace.LoggingServiceHandler"), any(LoggingServiceHandler.class)); LoggingServiceHandler.unregisterService(traceExporter); - verify(traceExporter) - .unregisterServiceHandler(eq("com.google.instrumentation.trace.LoggingServiceHandler")); + verify(traceExporter).unregisterServiceHandler(eq("io.opencensus.trace.LoggingServiceHandler")); } } diff --git a/core/src/test/java/com/google/instrumentation/trace/TraceIdTest.java b/api/src/test/java/io/opencensus/trace/TraceIdTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/trace/TraceIdTest.java rename to api/src/test/java/io/opencensus/trace/TraceIdTest.java index ed675ef640..cd1b7c24f0 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TraceIdTest.java +++ b/api/src/test/java/io/opencensus/trace/TraceIdTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/trace/TraceOptionsTest.java b/api/src/test/java/io/opencensus/trace/TraceOptionsTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/trace/TraceOptionsTest.java rename to api/src/test/java/io/opencensus/trace/TraceOptionsTest.java index e1119337f5..fb24064662 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TraceOptionsTest.java +++ b/api/src/test/java/io/opencensus/trace/TraceOptionsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java b/api/src/test/java/io/opencensus/trace/TraceParamsTest.java similarity index 96% rename from core/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java rename to api/src/test/java/io/opencensus/trace/TraceParamsTest.java index 52e6aecc8e..60f40debd0 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TraceParamsTest.java +++ b/api/src/test/java/io/opencensus/trace/TraceParamsTest.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.trace.TraceConfig.TraceParams; +import io.opencensus.trace.TraceConfig.TraceParams; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core/src/test/java/com/google/instrumentation/trace/TracerTest.java b/api/src/test/java/io/opencensus/trace/TracerTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/trace/TracerTest.java rename to api/src/test/java/io/opencensus/trace/TracerTest.java index 7a19fda08b..cc46956cd5 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TracerTest.java +++ b/api/src/test/java/io/opencensus/trace/TracerTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.eq; @@ -20,8 +20,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.google.instrumentation.common.NonThrowingCloseable; import io.grpc.Context; +import io.opencensus.common.NonThrowingCloseable; import java.util.Random; import org.junit.Before; import org.junit.Rule; diff --git a/core/src/test/java/com/google/instrumentation/trace/TracingTest.java b/api/src/test/java/io/opencensus/trace/TracingTest.java similarity index 94% rename from core/src/test/java/com/google/instrumentation/trace/TracingTest.java rename to api/src/test/java/io/opencensus/trace/TracingTest.java index ab2669549c..b7c9be252d 100644 --- a/core/src/test/java/com/google/instrumentation/trace/TracingTest.java +++ b/api/src/test/java/io/opencensus/trace/TracingTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; @@ -52,7 +52,7 @@ public Class loadClass(String name) throws ClassNotFoundException { }) .getClass() .getName()) - .isEqualTo("com.google.instrumentation.trace.TraceComponent$NoopTraceComponent"); + .isEqualTo("io.opencensus.trace.TraceComponent$NoopTraceComponent"); } @Test diff --git a/benchmarks/src/jmh/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/BinaryPropagationHandlerImplBenchmark.java similarity index 98% rename from benchmarks/src/jmh/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplBenchmark.java rename to benchmarks/src/jmh/java/io/opencensus/trace/BinaryPropagationHandlerImplBenchmark.java index fc8d9846c2..85302d25db 100644 --- a/benchmarks/src/jmh/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/BinaryPropagationHandlerImplBenchmark.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import java.text.ParseException; import java.util.concurrent.TimeUnit; diff --git a/benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsNonSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java similarity index 98% rename from benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsNonSampledSpanBenchmark.java rename to benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java index ad9a66b5c0..0c3daa87a2 100644 --- a/benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsNonSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import java.util.HashMap; import java.util.concurrent.TimeUnit; diff --git a/benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java similarity index 98% rename from benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsSampledSpanBenchmark.java rename to benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java index e20af6ea90..78a587f45e 100644 --- a/benchmarks/src/jmh/java/com/google/instrumentation/trace/RecordTraceEventsSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import java.util.HashMap; import java.util.concurrent.TimeUnit; diff --git a/benchmarks/src/jmh/java/com/google/instrumentation/trace/StartEndSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java similarity index 98% rename from benchmarks/src/jmh/java/com/google/instrumentation/trace/StartEndSpanBenchmark.java rename to benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java index ee15ad014f..9a51ffbe42 100644 --- a/benchmarks/src/jmh/java/com/google/instrumentation/trace/StartEndSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; diff --git a/core/build.gradle b/core/build.gradle index 2520ff4cb4..333dea0a49 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -5,7 +5,8 @@ jar { } dependencies { - compile libraries.grpc_context, + compile project(':opencensus-api'), + libraries.grpc_context, libraries.guava compileOnly libraries.auto_value diff --git a/core/src/main/java/com/google/instrumentation/stats/ContextUtils.java b/core/src/main/java/com/google/instrumentation/stats/ContextUtils.java index b0f7e6c549..745db2d9cc 100644 --- a/core/src/main/java/com/google/instrumentation/stats/ContextUtils.java +++ b/core/src/main/java/com/google/instrumentation/stats/ContextUtils.java @@ -13,8 +13,8 @@ package com.google.instrumentation.stats; -import com.google.instrumentation.common.NonThrowingCloseable; import io.grpc.Context; +import io.opencensus.common.NonThrowingCloseable; /** * Util methods/functionality to interact with the {@link io.grpc.Context}. diff --git a/core/src/main/java/com/google/instrumentation/stats/IntervalAggregation.java b/core/src/main/java/com/google/instrumentation/stats/IntervalAggregation.java index 9bd2692318..97c8c6cdfb 100644 --- a/core/src/main/java/com/google/instrumentation/stats/IntervalAggregation.java +++ b/core/src/main/java/com/google/instrumentation/stats/IntervalAggregation.java @@ -13,7 +13,7 @@ package com.google.instrumentation.stats; -import com.google.instrumentation.common.Duration; +import io.opencensus.common.Duration; import java.util.ArrayList; import java.util.Collections; diff --git a/core/src/main/java/com/google/instrumentation/stats/IntervalAggregationDescriptor.java b/core/src/main/java/com/google/instrumentation/stats/IntervalAggregationDescriptor.java index ada61fb6c3..3af843bb90 100644 --- a/core/src/main/java/com/google/instrumentation/stats/IntervalAggregationDescriptor.java +++ b/core/src/main/java/com/google/instrumentation/stats/IntervalAggregationDescriptor.java @@ -13,7 +13,7 @@ package com.google.instrumentation.stats; -import com.google.instrumentation.common.Duration; +import io.opencensus.common.Duration; import java.util.ArrayList; import java.util.Collections; diff --git a/core/src/main/java/com/google/instrumentation/stats/MeasurementDescriptor.java b/core/src/main/java/com/google/instrumentation/stats/MeasurementDescriptor.java index d44c4eabec..e34c76fa1b 100644 --- a/core/src/main/java/com/google/instrumentation/stats/MeasurementDescriptor.java +++ b/core/src/main/java/com/google/instrumentation/stats/MeasurementDescriptor.java @@ -14,7 +14,7 @@ package com.google.instrumentation.stats; import com.google.auto.value.AutoValue; -import com.google.instrumentation.internal.StringUtil; +import io.opencensus.internal.StringUtil; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/com/google/instrumentation/stats/RpcConstants.java b/core/src/main/java/com/google/instrumentation/stats/RpcConstants.java index 5a89e564d5..c2663368a0 100644 --- a/core/src/main/java/com/google/instrumentation/stats/RpcConstants.java +++ b/core/src/main/java/com/google/instrumentation/stats/RpcConstants.java @@ -13,11 +13,11 @@ package com.google.instrumentation.stats; -import com.google.instrumentation.common.Duration; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.common.Duration; import java.util.Arrays; import java.util.Collections; diff --git a/core/src/main/java/com/google/instrumentation/stats/RpcViewConstants.java b/core/src/main/java/com/google/instrumentation/stats/RpcViewConstants.java index 72d6223683..2da8bc1cc3 100644 --- a/core/src/main/java/com/google/instrumentation/stats/RpcViewConstants.java +++ b/core/src/main/java/com/google/instrumentation/stats/RpcViewConstants.java @@ -39,9 +39,10 @@ import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES; import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_STATUS; -import com.google.instrumentation.common.Duration; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.common.Duration; + import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/com/google/instrumentation/stats/Stats.java b/core/src/main/java/com/google/instrumentation/stats/Stats.java index 31c2449e0b..90f366c897 100644 --- a/core/src/main/java/com/google/instrumentation/stats/Stats.java +++ b/core/src/main/java/com/google/instrumentation/stats/Stats.java @@ -13,7 +13,7 @@ package com.google.instrumentation.stats; -import com.google.instrumentation.internal.Provider; +import io.opencensus.internal.Provider; import javax.annotation.Nullable; /** diff --git a/core/src/main/java/com/google/instrumentation/stats/StatsContextFactory.java b/core/src/main/java/com/google/instrumentation/stats/StatsContextFactory.java index 238d122f47..88ac718e46 100644 --- a/core/src/main/java/com/google/instrumentation/stats/StatsContextFactory.java +++ b/core/src/main/java/com/google/instrumentation/stats/StatsContextFactory.java @@ -15,7 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.instrumentation.common.NonThrowingCloseable; +import io.opencensus.common.NonThrowingCloseable; import java.io.IOException; import java.io.InputStream; diff --git a/core/src/main/java/com/google/instrumentation/stats/TagKey.java b/core/src/main/java/com/google/instrumentation/stats/TagKey.java index 873202873b..c0531e77b2 100644 --- a/core/src/main/java/com/google/instrumentation/stats/TagKey.java +++ b/core/src/main/java/com/google/instrumentation/stats/TagKey.java @@ -14,7 +14,7 @@ package com.google.instrumentation.stats; import com.google.auto.value.AutoValue; -import com.google.instrumentation.internal.StringUtil; +import io.opencensus.internal.StringUtil; import javax.annotation.concurrent.Immutable; /** diff --git a/core/src/main/java/com/google/instrumentation/stats/TagValue.java b/core/src/main/java/com/google/instrumentation/stats/TagValue.java index f27003b45d..18cfd19275 100644 --- a/core/src/main/java/com/google/instrumentation/stats/TagValue.java +++ b/core/src/main/java/com/google/instrumentation/stats/TagValue.java @@ -14,7 +14,7 @@ package com.google.instrumentation.stats; import com.google.auto.value.AutoValue; -import com.google.instrumentation.internal.StringUtil; +import io.opencensus.internal.StringUtil; import javax.annotation.concurrent.Immutable; /** diff --git a/core/src/main/java/com/google/instrumentation/stats/View.java b/core/src/main/java/com/google/instrumentation/stats/View.java index 34ed8b95cd..56fbb767d4 100644 --- a/core/src/main/java/com/google/instrumentation/stats/View.java +++ b/core/src/main/java/com/google/instrumentation/stats/View.java @@ -14,10 +14,11 @@ package com.google.instrumentation.stats; import com.google.auto.value.AutoValue; -import com.google.instrumentation.common.Function; -import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.common.Function; +import io.opencensus.common.Timestamp; + import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java b/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java index 5550795fb9..99e408acad 100644 --- a/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java +++ b/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java @@ -14,7 +14,7 @@ package com.google.instrumentation.stats; import com.google.auto.value.AutoValue; -import com.google.instrumentation.common.Function; +import io.opencensus.common.Function; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/core/src/test/java/com/google/instrumentation/stats/ContextUtilsTest.java b/core/src/test/java/com/google/instrumentation/stats/ContextUtilsTest.java index a8a77be7b9..5affcf3f4f 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ContextUtilsTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/ContextUtilsTest.java @@ -15,7 +15,7 @@ import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.NonThrowingCloseable; +import io.opencensus.common.NonThrowingCloseable; import io.grpc.Context; import org.junit.Before; import org.junit.Test; diff --git a/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationDescriptorTest.java b/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationDescriptorTest.java index 3c8a5e4585..7becbc22ad 100644 --- a/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationDescriptorTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationDescriptorTest.java @@ -15,7 +15,7 @@ import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.Duration; +import io.opencensus.common.Duration; import java.util.Arrays; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationTest.java b/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationTest.java index a436ff0b3e..0f92035af1 100644 --- a/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationTest.java @@ -15,7 +15,7 @@ import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.Duration; +import io.opencensus.common.Duration; import com.google.instrumentation.stats.IntervalAggregation.Interval; import java.util.Arrays; import java.util.List; diff --git a/core/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorTest.java b/core/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorTest.java index ca3ddb8249..a34b9897bd 100644 --- a/core/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorTest.java @@ -16,7 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import com.google.instrumentation.internal.StringUtil; +import io.opencensus.internal.StringUtil; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; import java.util.Arrays; diff --git a/core/src/test/java/com/google/instrumentation/stats/TagKeyTest.java b/core/src/test/java/com/google/instrumentation/stats/TagKeyTest.java index 7f106f3d1b..c0c8657beb 100644 --- a/core/src/test/java/com/google/instrumentation/stats/TagKeyTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/TagKeyTest.java @@ -16,7 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import com.google.instrumentation.internal.StringUtil; +import io.opencensus.internal.StringUtil; import java.util.Arrays; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core/src/test/java/com/google/instrumentation/stats/TagValueTest.java b/core/src/test/java/com/google/instrumentation/stats/TagValueTest.java index 8f7e4a8d96..b3e663ec21 100644 --- a/core/src/test/java/com/google/instrumentation/stats/TagValueTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/TagValueTest.java @@ -16,7 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import com.google.instrumentation.internal.StringUtil; +import io.opencensus.internal.StringUtil; import java.util.Arrays; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java index 89f843c454..f9f3bc2d18 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java @@ -18,8 +18,8 @@ import static org.junit.Assert.assertTrue; import com.google.common.testing.EqualsTester; -import com.google.instrumentation.common.Duration; -import com.google.instrumentation.common.Function; +import io.opencensus.common.Duration; +import io.opencensus.common.Function; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; diff --git a/core/src/test/java/com/google/instrumentation/stats/ViewTest.java b/core/src/test/java/com/google/instrumentation/stats/ViewTest.java index 73462b1962..6f899f168c 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ViewTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/ViewTest.java @@ -17,9 +17,9 @@ import static org.junit.Assert.assertTrue; import com.google.common.testing.EqualsTester; -import com.google.instrumentation.common.Duration; -import com.google.instrumentation.common.Function; -import com.google.instrumentation.common.Timestamp; +import io.opencensus.common.Duration; +import io.opencensus.common.Function; +import io.opencensus.common.Timestamp; import com.google.instrumentation.stats.DistributionAggregation.Range; import com.google.instrumentation.stats.IntervalAggregation.Interval; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java index 19ca1ec75e..8bd35aaeb3 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java @@ -15,12 +15,13 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.Function; import com.google.instrumentation.stats.MutableView.MutableDistributionView; import com.google.instrumentation.stats.MutableView.MutableIntervalView; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.common.Clock; +import io.opencensus.common.Function; + import java.util.Collection; import java.util.HashMap; import java.util.Map; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java b/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java index 55636cd069..141c4a910f 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java @@ -14,11 +14,12 @@ package com.google.instrumentation.stats; import com.google.common.annotations.VisibleForTesting; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.Timestamp; import com.google.instrumentation.stats.View.DistributionView; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.common.Clock; +import io.opencensus.common.Timestamp; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java index e4bf1a413a..746ce8731b 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java @@ -13,8 +13,8 @@ package com.google.instrumentation.stats; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.EventQueue; +import io.opencensus.common.Clock; +import io.opencensus.common.EventQueue; /** * Base implementation of {@link StatsManager}. diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java index 108c961cb6..13e5450a82 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java @@ -15,7 +15,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.io.ByteStreams; -import com.google.instrumentation.internal.VarInt; +import io.opencensus.internal.VarInt; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java index 6cb242c89b..dc74a18593 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java @@ -13,9 +13,9 @@ package com.google.instrumentation.stats; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.EventQueue; import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; +import io.opencensus.common.Clock; +import io.opencensus.common.EventQueue; /** Object that stores all views and stats. */ final class ViewManager { diff --git a/core_impl/src/main/java/com/google/instrumentation/common/EventQueue.java b/core_impl/src/main/java/io/opencensus/common/EventQueue.java similarity index 82% rename from core_impl/src/main/java/com/google/instrumentation/common/EventQueue.java rename to core_impl/src/main/java/io/opencensus/common/EventQueue.java index e0585f1d43..6026d1049b 100644 --- a/core_impl/src/main/java/com/google/instrumentation/common/EventQueue.java +++ b/core_impl/src/main/java/io/opencensus/common/EventQueue.java @@ -11,17 +11,15 @@ * limitations under the License. */ -package com.google.instrumentation.common; +package io.opencensus.common; -/** - * A queue that processes events. See {@code DisruptorEventQueue} for an example. - */ +/** A queue that processes events. See {@code DisruptorEventQueue} for an example. */ public interface EventQueue { void enqueue(Entry entry); /** - * Base interface to be used for all entries in {@link EventQueue}. For example usage, - * see {@code DisruptorEventQueue}. + * Base interface to be used for all entries in {@link EventQueue}. For example usage, see {@code + * DisruptorEventQueue}. */ public interface Entry { /** diff --git a/core_impl/src/main/java/com/google/instrumentation/common/MillisClock.java b/core_impl/src/main/java/io/opencensus/common/MillisClock.java similarity index 88% rename from core_impl/src/main/java/com/google/instrumentation/common/MillisClock.java rename to core_impl/src/main/java/io/opencensus/common/MillisClock.java index a1be48ea70..fc1ac12174 100644 --- a/core_impl/src/main/java/com/google/instrumentation/common/MillisClock.java +++ b/core_impl/src/main/java/io/opencensus/common/MillisClock.java @@ -11,13 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.common; +package io.opencensus.common; import javax.annotation.concurrent.ThreadSafe; -/** - * A {@link Clock} that uses {@link System#currentTimeMillis()} and {@link System#nanoTime()}. - */ +/** A {@link Clock} that uses {@link System#currentTimeMillis()} and {@link System#nanoTime()}. */ @ThreadSafe public final class MillisClock extends Clock { private static final MillisClock INSTANCE = new MillisClock(); diff --git a/core_impl/src/main/java/com/google/instrumentation/common/SimpleEventQueue.java b/core_impl/src/main/java/io/opencensus/common/SimpleEventQueue.java similarity index 95% rename from core_impl/src/main/java/com/google/instrumentation/common/SimpleEventQueue.java rename to core_impl/src/main/java/io/opencensus/common/SimpleEventQueue.java index 3ec3caa5b6..b39a2590ff 100644 --- a/core_impl/src/main/java/com/google/instrumentation/common/SimpleEventQueue.java +++ b/core_impl/src/main/java/io/opencensus/common/SimpleEventQueue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.common; +package io.opencensus.common; /** * An {@link EventQueue} that processes events in the current thread. This class can be used for diff --git a/core_impl/src/main/java/com/google/instrumentation/internal/VarInt.java b/core_impl/src/main/java/io/opencensus/internal/VarInt.java similarity index 88% rename from core_impl/src/main/java/com/google/instrumentation/internal/VarInt.java rename to core_impl/src/main/java/io/opencensus/internal/VarInt.java index d3d85bf327..2ac5c4e06a 100644 --- a/core_impl/src/main/java/com/google/instrumentation/internal/VarInt.java +++ b/core_impl/src/main/java/io/opencensus/internal/VarInt.java @@ -11,34 +11,28 @@ * limitations under the License. */ -package com.google.instrumentation.internal; +package io.opencensus.internal; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; -/** - * Common methods to encode and decode varints and varlongs into ByteBuffers and - * arrays. - */ +/** Common methods to encode and decode varints and varlongs into ByteBuffers and arrays. */ // CHECKSTYLE:OFF public class VarInt { - /** - * Maximum encoded size of 32-bit positive integers (in bytes) - */ + /** Maximum encoded size of 32-bit positive integers (in bytes) */ public static final int MAX_VARINT_SIZE = 5; - /** - * maximum encoded size of 64-bit longs, and negative 32-bit ints (in bytes) - */ + /** maximum encoded size of 64-bit longs, and negative 32-bit ints (in bytes) */ public static final int MAX_VARLONG_SIZE = 10; - private VarInt() { } + private VarInt() {} /** * Returns the encoding size in bytes of its input value. + * * @param i the integer to be measured * @return the encoding size in bytes of its input value */ @@ -52,8 +46,8 @@ public static int varIntSize(int i) { } /** - * Reads a varint from src, places its values into the first element of - * dst and returns the offset in to src of the first byte after the varint. + * Reads a varint from src, places its values into the first element of dst and returns the offset + * in to src of the first byte after the varint. * * @param src source buffer to retrieve from * @param offset offset within src @@ -79,8 +73,8 @@ public static int getVarInt(byte[] src, int offset, int[] dst) { } /** - * Encodes an integer in a variable-length encoding, 7 bits per byte, into a - * destination byte[], following the protocol buffer convention. + * Encodes an integer in a variable-length encoding, 7 bits per byte, into a destination byte[], + * following the protocol buffer convention. * * @param v the int value to write to sink * @param sink the sink buffer to write to @@ -99,11 +93,10 @@ public static int putVarInt(int v, byte[] sink, int offset) { } /** - * Reads a varint from the current position of the given ByteBuffer and - * returns the decoded value as 32 bit integer. + * Reads a varint from the current position of the given ByteBuffer and returns the decoded value + * as 32 bit integer. * - *

              The position of the buffer is advanced to the first byte after the - * decoded varint. + *

              The position of the buffer is advanced to the first byte after the decoded varint. * * @param src the ByteBuffer to get the var int from * @return The integer value of the decoded varint @@ -140,8 +133,8 @@ public static int getVarInt(ByteBuffer src) { } /** - * Encodes an integer in a variable-length encoding, 7 bits per byte, to a - * ByteBuffer sink. + * Encodes an integer in a variable-length encoding, 7 bits per byte, to a ByteBuffer sink. + * * @param v the value to encode * @param sink the ByteBuffer to add the encoded value */ @@ -158,8 +151,7 @@ public static void putVarInt(int v, ByteBuffer sink) { } /** - * Reads a varint from the given InputStream and returns the decoded value - * as an int. + * Reads a varint from the given InputStream and returns the decoded value as an int. * * @param inputStream the InputStream to read from */ @@ -181,8 +173,8 @@ public static int getVarInt(InputStream inputStream) throws IOException { } /** - * Encodes an integer in a variable-length encoding, 7 bits per byte, and - * writes it to the given OutputStream. + * Encodes an integer in a variable-length encoding, 7 bits per byte, and writes it to the given + * OutputStream. * * @param v the value to encode * @param outputStream the OutputStream to write to @@ -209,11 +201,10 @@ public static int varLongSize(long v) { } /** - * Reads an up to 64 bit long varint from the current position of the - * given ByteBuffer and returns the decoded value as long. + * Reads an up to 64 bit long varint from the current position of the given ByteBuffer and returns + * the decoded value as long. * - *

              The position of the buffer is advanced to the first byte after the - * decoded varint. + *

              The position of the buffer is advanced to the first byte after the decoded varint. * * @param src the ByteBuffer to get the var int from * @return The integer value of the decoded long varint @@ -269,8 +260,8 @@ public static long getVarLong(ByteBuffer src) { } /** - * Encodes a long integer in a variable-length encoding, 7 bits per byte, to a - * ByteBuffer sink. + * Encodes a long integer in a variable-length encoding, 7 bits per byte, to a ByteBuffer sink. + * * @param v the value to encode * @param sink the ByteBuffer to add the encoded value */ diff --git a/core_impl/src/main/java/com/google/instrumentation/internal/package-info.java b/core_impl/src/main/java/io/opencensus/internal/package-info.java similarity index 84% rename from core_impl/src/main/java/com/google/instrumentation/internal/package-info.java rename to core_impl/src/main/java/io/opencensus/internal/package-info.java index 849397059d..5fe0010d41 100644 --- a/core_impl/src/main/java/com/google/instrumentation/internal/package-info.java +++ b/core_impl/src/main/java/io/opencensus/internal/package-info.java @@ -15,7 +15,7 @@ * Interfaces and implementations that are internal to opencensus. * *

              All the content under this package and its subpackages are considered annotated with {@link - * com.google.instrumentation.common.Internal}. + * io.opencensus.common.Internal}. */ -@com.google.instrumentation.common.Internal -package com.google.instrumentation.internal; +@io.opencensus.common.Internal +package io.opencensus.internal; diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/BinaryPropagationHandlerImpl.java b/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java similarity index 99% rename from core_impl/src/main/java/com/google/instrumentation/trace/BinaryPropagationHandlerImpl.java rename to core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java index 2a4532794b..7f51eb3ec2 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/BinaryPropagationHandlerImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/RandomHandler.java b/core_impl/src/main/java/io/opencensus/trace/RandomHandler.java similarity index 96% rename from core_impl/src/main/java/com/google/instrumentation/trace/RandomHandler.java rename to core_impl/src/main/java/io/opencensus/trace/RandomHandler.java index e5f4ea948e..b687881d73 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/RandomHandler.java +++ b/core_impl/src/main/java/io/opencensus/trace/RandomHandler.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import java.security.SecureRandom; import java.util.Random; diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java similarity index 94% rename from core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java rename to core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java index 38c1c5f8a8..695a2215d7 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java @@ -11,14 +11,14 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.trace.Link.Type; -import com.google.instrumentation.trace.Span.Options; -import com.google.instrumentation.trace.TraceConfig.TraceParams; +import io.opencensus.common.Clock; +import io.opencensus.trace.Link.Type; +import io.opencensus.trace.Span.Options; +import io.opencensus.trace.TraceConfig.TraceParams; import java.util.EnumSet; import java.util.List; import java.util.Random; diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java similarity index 98% rename from core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java rename to core_impl/src/main/java/io/opencensus/trace/SpanImpl.java index 4ba7f0d442..2fcb7cb7ef 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/SpanImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java @@ -11,15 +11,15 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import com.google.common.collect.EvictingQueue; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.trace.SpanData.TimedEvent; -import com.google.instrumentation.trace.TraceConfig.TraceParams; +import io.opencensus.common.Clock; +import io.opencensus.trace.SpanData.TimedEvent; +import io.opencensus.trace.TraceConfig.TraceParams; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TimestampConverter.java b/core_impl/src/main/java/io/opencensus/trace/TimestampConverter.java similarity index 91% rename from core_impl/src/main/java/com/google/instrumentation/trace/TimestampConverter.java rename to core_impl/src/main/java/io/opencensus/trace/TimestampConverter.java index 5a01588748..2e8982ac43 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TimestampConverter.java +++ b/core_impl/src/main/java/io/opencensus/trace/TimestampConverter.java @@ -11,10 +11,10 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.Timestamp; +import io.opencensus.common.Clock; +import io.opencensus.common.Timestamp; import javax.annotation.concurrent.Immutable; /** diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java similarity index 86% rename from core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java rename to core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java index 6b0c693b80..7e25dadac1 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java @@ -11,10 +11,10 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.EventQueue; +import io.opencensus.common.Clock; +import io.opencensus.common.EventQueue; /** Base implementation of the {@link TraceComponent}. */ class TraceComponentImplBase extends TraceComponent { @@ -30,8 +30,9 @@ class TraceComponentImplBase extends TraceComponent { TraceComponentImplBase(Clock clock, RandomHandler randomHandler, EventQueue eventQueue) { this.clock = clock; - TraceExporterImpl traceExporterImpl = TraceExporterImpl.create(TRACE_EXPORTER_BUFFER_SIZE, - TRACE_EXPORTER_SCHEDULE_DELAY_MS, eventQueue); + TraceExporterImpl traceExporterImpl = + TraceExporterImpl.create( + TRACE_EXPORTER_BUFFER_SIZE, TRACE_EXPORTER_SCHEDULE_DELAY_MS, eventQueue); traceExporter = traceExporterImpl; tracer = new TracerImpl(randomHandler, traceExporterImpl, clock, traceConfig); } diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceConfigImpl.java b/core_impl/src/main/java/io/opencensus/trace/TraceConfigImpl.java similarity index 96% rename from core_impl/src/main/java/com/google/instrumentation/trace/TraceConfigImpl.java rename to core_impl/src/main/java/io/opencensus/trace/TraceConfigImpl.java index c7b40d272d..eef2be799e 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceConfigImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/TraceConfigImpl.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; /** * Global configuration of the trace service. This allows users to change configs for the default diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java b/core_impl/src/main/java/io/opencensus/trace/TraceExporterImpl.java similarity index 98% rename from core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java rename to core_impl/src/main/java/io/opencensus/trace/TraceExporterImpl.java index 1057d8b40a..d42c2c3474 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TraceExporterImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/TraceExporterImpl.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import com.google.common.annotations.VisibleForTesting; -import com.google.instrumentation.common.EventQueue; -import com.google.instrumentation.trace.SpanImpl.StartEndHandler; +import io.opencensus.common.EventQueue; +import io.opencensus.trace.SpanImpl.StartEndHandler; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; diff --git a/core_impl/src/main/java/com/google/instrumentation/trace/TracerImpl.java b/core_impl/src/main/java/io/opencensus/trace/TracerImpl.java similarity index 91% rename from core_impl/src/main/java/com/google/instrumentation/trace/TracerImpl.java rename to core_impl/src/main/java/io/opencensus/trace/TracerImpl.java index 218124bb9d..996607ce5f 100644 --- a/core_impl/src/main/java/com/google/instrumentation/trace/TracerImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/TracerImpl.java @@ -11,9 +11,9 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; -import com.google.instrumentation.common.Clock; +import io.opencensus.common.Clock; /** Implementation of the {@link Tracer}. */ final class TracerImpl extends Tracer { diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java index 1efc5949bd..1b4bdf7bbc 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java @@ -16,9 +16,9 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; -import com.google.instrumentation.common.Function; -import com.google.instrumentation.common.Timestamp; -import com.google.instrumentation.internal.TestClock; +import io.opencensus.common.Function; +import io.opencensus.common.Timestamp; +import io.opencensus.internal.TestClock; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; import com.google.instrumentation.stats.View.DistributionView; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java index 217695a2e0..72d880f687 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java @@ -15,10 +15,10 @@ import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.NonThrowingCloseable; -import com.google.instrumentation.common.SimpleEventQueue; -import com.google.instrumentation.internal.TestClock; -import com.google.instrumentation.internal.VarInt; +import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.SimpleEventQueue; +import io.opencensus.internal.TestClock; +import io.opencensus.internal.VarInt; import io.grpc.Context; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java index 818e328c29..9b68f942f6 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java @@ -18,10 +18,10 @@ import com.google.common.collect.Collections2; import com.google.common.testing.EqualsTester; -import com.google.instrumentation.common.Function; -import com.google.instrumentation.common.SimpleEventQueue; -import com.google.instrumentation.internal.TestClock; -import com.google.instrumentation.internal.VarInt; +import io.opencensus.common.Function; +import io.opencensus.common.SimpleEventQueue; +import io.opencensus.internal.TestClock; +import io.opencensus.internal.VarInt; import com.google.instrumentation.stats.View.DistributionView; import com.google.instrumentation.stats.View.IntervalView; import java.io.ByteArrayInputStream; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index 0bd23d97eb..bdd98ca170 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -16,10 +16,10 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.instrumentation.stats.StatsTestUtil.createContext; -import com.google.instrumentation.common.Duration; -import com.google.instrumentation.common.SimpleEventQueue; -import com.google.instrumentation.common.Timestamp; -import com.google.instrumentation.internal.TestClock; +import io.opencensus.common.Duration; +import io.opencensus.common.SimpleEventQueue; +import io.opencensus.common.Timestamp; +import io.opencensus.internal.TestClock; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; import com.google.instrumentation.stats.View.DistributionView; diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplTest.java b/core_impl/src/test/java/io/opencensus/trace/BinaryPropagationHandlerImplTest.java similarity index 99% rename from core_impl/src/test/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplTest.java rename to core_impl/src/test/java/io/opencensus/trace/BinaryPropagationHandlerImplTest.java index 20c11c6f38..c6ea04e6b0 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/BinaryPropagationHandlerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/BinaryPropagationHandlerImplTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/SpanFactoryImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java similarity index 96% rename from core_impl/src/test/java/com/google/instrumentation/trace/SpanFactoryImplTest.java rename to core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java index 7411920fb9..bc2bbfb2c3 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/SpanFactoryImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java @@ -11,15 +11,15 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; -import com.google.instrumentation.internal.TestClock; -import com.google.instrumentation.trace.Span.Options; -import com.google.instrumentation.trace.SpanImpl.StartEndHandler; -import com.google.instrumentation.trace.TraceConfig.TraceParams; +import io.opencensus.internal.TestClock; +import io.opencensus.trace.Span.Options; +import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.TraceConfig.TraceParams; import java.util.Random; import org.junit.Before; import org.junit.Test; diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java similarity index 98% rename from core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java rename to core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java index 26742032a9..6c9d57fc31 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/SpanImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java @@ -11,16 +11,16 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.Duration; -import com.google.instrumentation.common.Timestamp; -import com.google.instrumentation.internal.TestClock; -import com.google.instrumentation.trace.Span.Options; -import com.google.instrumentation.trace.SpanImpl.StartEndHandler; -import com.google.instrumentation.trace.TraceConfig.TraceParams; +import io.opencensus.common.Duration; +import io.opencensus.common.Timestamp; +import io.opencensus.internal.TestClock; +import io.opencensus.trace.Span.Options; +import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.TraceConfig.TraceParams; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TimestampConverterTest.java b/core_impl/src/test/java/io/opencensus/trace/TimestampConverterTest.java similarity index 92% rename from core_impl/src/test/java/com/google/instrumentation/trace/TimestampConverterTest.java rename to core_impl/src/test/java/io/opencensus/trace/TimestampConverterTest.java index b1e486315d..e6f48a9ff2 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TimestampConverterTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/TimestampConverterTest.java @@ -11,13 +11,13 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; -import com.google.instrumentation.common.Clock; -import com.google.instrumentation.common.Timestamp; +import io.opencensus.common.Clock; +import io.opencensus.common.Timestamp; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java b/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java similarity index 87% rename from core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java rename to core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java index 8f739d2847..7bae0e54a4 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceComponentImplBaseTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java @@ -11,13 +11,13 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.MillisClock; -import com.google.instrumentation.common.SimpleEventQueue; -import com.google.instrumentation.trace.RandomHandler.SecureRandomHandler; +import io.opencensus.common.MillisClock; +import io.opencensus.common.SimpleEventQueue; +import io.opencensus.trace.RandomHandler.SecureRandomHandler; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceConfigImplTest.java b/core_impl/src/test/java/io/opencensus/trace/TraceConfigImplTest.java similarity index 94% rename from core_impl/src/test/java/com/google/instrumentation/trace/TraceConfigImplTest.java rename to core_impl/src/test/java/io/opencensus/trace/TraceConfigImplTest.java index 1535f5738a..6e43cbb4f7 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceConfigImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/TraceConfigImplTest.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.trace.TraceConfig.TraceParams; +import io.opencensus.trace.TraceConfig.TraceParams; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java b/core_impl/src/test/java/io/opencensus/trace/TraceExporterImplTest.java similarity index 96% rename from core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java rename to core_impl/src/test/java/io/opencensus/trace/TraceExporterImplTest.java index 03f0e408ed..4684bef8dd 100644 --- a/core_impl/src/test/java/com/google/instrumentation/trace/TraceExporterImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/TraceExporterImplTest.java @@ -11,17 +11,17 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyListOf; import static org.mockito.Mockito.doThrow; -import com.google.instrumentation.common.MillisClock; -import com.google.instrumentation.common.SimpleEventQueue; -import com.google.instrumentation.trace.Span.Options; -import com.google.instrumentation.trace.TraceConfig.TraceParams; -import com.google.instrumentation.trace.TraceExporter.ServiceHandler; +import io.opencensus.common.MillisClock; +import io.opencensus.common.SimpleEventQueue; +import io.opencensus.trace.Span.Options; +import io.opencensus.trace.TraceConfig.TraceParams; +import io.opencensus.trace.TraceExporter.ServiceHandler; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; diff --git a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java index 998777bfb5..af0214d1a3 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -13,8 +13,8 @@ package com.google.instrumentation.stats; -import com.google.instrumentation.common.MillisClock; -import com.google.instrumentation.common.SimpleEventQueue; +import io.opencensus.common.MillisClock; +import io.opencensus.common.SimpleEventQueue; /** * Android-compatible implementation of {@link StatsManager}. diff --git a/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_android/src/main/java/io/opencensus/trace/TraceComponentImpl.java similarity index 78% rename from core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java rename to core_impl_android/src/main/java/io/opencensus/trace/TraceComponentImpl.java index 0712590041..b4e2e49ecc 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl_android/src/main/java/io/opencensus/trace/TraceComponentImpl.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; -import com.google.instrumentation.common.MillisClock; -import com.google.instrumentation.common.SimpleEventQueue; -import com.google.instrumentation.trace.RandomHandler.SecureRandomHandler; +import io.opencensus.common.MillisClock; +import io.opencensus.common.SimpleEventQueue; +import io.opencensus.trace.RandomHandler.SecureRandomHandler; /** Android-compatible implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplBase { diff --git a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java b/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java similarity index 93% rename from core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java rename to core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java index a4f8b4f97d..80580cc01e 100644 --- a/core_impl_android/src/test/java/com/google/instrumentation/trace/TraceComponentImplTest.java +++ b/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.MillisClock; +import io.opencensus.common.MillisClock; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java index 1e0e8bdac8..53650a9603 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -13,8 +13,8 @@ package com.google.instrumentation.stats; -import com.google.instrumentation.common.DisruptorEventQueue; -import com.google.instrumentation.common.MillisClock; +import io.opencensus.common.DisruptorEventQueue; +import io.opencensus.common.MillisClock; /** Java 7 and 8 implementation of {@link StatsManager}. */ public final class StatsManagerImpl extends StatsManagerImplBase { diff --git a/core_impl_java/src/main/java/com/google/instrumentation/common/DisruptorEventQueue.java b/core_impl_java/src/main/java/io/opencensus/common/DisruptorEventQueue.java similarity index 99% rename from core_impl_java/src/main/java/com/google/instrumentation/common/DisruptorEventQueue.java rename to core_impl_java/src/main/java/io/opencensus/common/DisruptorEventQueue.java index 1e54d283ea..4c9c0c6239 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/common/DisruptorEventQueue.java +++ b/core_impl_java/src/main/java/io/opencensus/common/DisruptorEventQueue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.common; +package io.opencensus.common; import com.lmax.disruptor.EventFactory; import com.lmax.disruptor.EventHandler; diff --git a/core_impl_java/src/main/java/com/google/instrumentation/trace/ThreadLocalRandomHandler.java b/core_impl_java/src/main/java/io/opencensus/trace/ThreadLocalRandomHandler.java similarity index 95% rename from core_impl_java/src/main/java/com/google/instrumentation/trace/ThreadLocalRandomHandler.java rename to core_impl_java/src/main/java/io/opencensus/trace/ThreadLocalRandomHandler.java index c467a897c6..156ae08432 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/trace/ThreadLocalRandomHandler.java +++ b/core_impl_java/src/main/java/io/opencensus/trace/ThreadLocalRandomHandler.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; diff --git a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java b/core_impl_java/src/main/java/io/opencensus/trace/TraceComponentImpl.java similarity index 85% rename from core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java rename to core_impl_java/src/main/java/io/opencensus/trace/TraceComponentImpl.java index 3a2db7caa9..4aecbbc6ca 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/trace/TraceComponentImpl.java +++ b/core_impl_java/src/main/java/io/opencensus/trace/TraceComponentImpl.java @@ -11,10 +11,10 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; -import com.google.instrumentation.common.DisruptorEventQueue; -import com.google.instrumentation.common.MillisClock; +import io.opencensus.common.DisruptorEventQueue; +import io.opencensus.common.MillisClock; /** Java 7 and 8 implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplBase { diff --git a/core_impl_java/src/test/java/com/google/instrumentation/common/DisruptorEventQueueTest.java b/core_impl_java/src/test/java/io/opencensus/common/DisruptorEventQueueTest.java similarity index 98% rename from core_impl_java/src/test/java/com/google/instrumentation/common/DisruptorEventQueueTest.java rename to core_impl_java/src/test/java/io/opencensus/common/DisruptorEventQueueTest.java index c3ebe5efbf..725b751dcf 100644 --- a/core_impl_java/src/test/java/com/google/instrumentation/common/DisruptorEventQueueTest.java +++ b/core_impl_java/src/test/java/io/opencensus/common/DisruptorEventQueueTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.common; +package io.opencensus.common; import static com.google.common.truth.Truth.assertThat; diff --git a/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java b/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java similarity index 93% rename from core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java rename to core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java index ba550e73e8..1496d4d3c6 100644 --- a/core_impl_java/src/test/java/com/google/instrumentation/trace/TracingTest.java +++ b/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.trace; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; -import com.google.instrumentation.common.MillisClock; +import io.opencensus.common.MillisClock; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/examples/build.gradle b/examples/build.gradle index 711f3bd85b..aac3619ef0 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -24,21 +24,21 @@ task statsRunner(type: CreateStartScripts) { } task multiSpansTracing(type: CreateStartScripts) { - mainClassName = 'com.google.instrumentation.examples.trace.MultiSpansTracing' + mainClassName = 'io.opencensus.examples.trace.MultiSpansTracing' applicationName = 'MultiSpansTracing' outputDir = new File(project.buildDir, 'tmp') classpath = jar.outputs.files + project.configurations.runtime } task multiSpansScopedTracing(type: CreateStartScripts) { - mainClassName = 'com.google.instrumentation.examples.trace.MultiSpansScopedTracing' + mainClassName = 'io.opencensus.examples.trace.MultiSpansScopedTracing' applicationName = 'MultiSpansScopedTracing' outputDir = new File(project.buildDir, 'tmp') classpath = jar.outputs.files + project.configurations.runtime } task multiSpansContextTracing(type: CreateStartScripts) { - mainClassName = 'com.google.instrumentation.examples.trace.MultiSpansContextTracing' + mainClassName = 'io.opencensus.examples.trace.MultiSpansContextTracing' applicationName = 'MultiSpansContextTracing' outputDir = new File(project.buildDir, 'tmp') classpath = jar.outputs.files + project.configurations.runtime diff --git a/examples/src/main/java/com/google/instrumentation/examples/stats/StatsRunner.java b/examples/src/main/java/com/google/instrumentation/examples/stats/StatsRunner.java index a7e901df1c..831ce59169 100644 --- a/examples/src/main/java/com/google/instrumentation/examples/stats/StatsRunner.java +++ b/examples/src/main/java/com/google/instrumentation/examples/stats/StatsRunner.java @@ -13,7 +13,6 @@ package com.google.instrumentation.examples.stats; -import com.google.instrumentation.common.NonThrowingCloseable; import com.google.instrumentation.stats.MeasurementDescriptor; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; @@ -23,6 +22,8 @@ import com.google.instrumentation.stats.StatsContextFactory; import com.google.instrumentation.stats.TagKey; import com.google.instrumentation.stats.TagValue; +import io.opencensus.common.NonThrowingCloseable; + import java.util.Arrays; /** Simple program that uses Stats contexts. */ diff --git a/examples/src/main/java/com/google/instrumentation/examples/trace/BasicContextTracing.java b/examples/src/main/java/com/google/instrumentation/examples/trace/BasicContextTracing.java deleted file mode 100644 index 11a37dfe6c..0000000000 --- a/examples/src/main/java/com/google/instrumentation/examples/trace/BasicContextTracing.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.examples.trace; - -import com.google.instrumentation.common.NonThrowingCloseable; -import com.google.instrumentation.trace.Span; -import com.google.instrumentation.trace.Tracer; -import com.google.instrumentation.trace.Tracing; - -/** - * Example showing how to create a {@link Span}, install it to the current context and add - * annotations. - */ -public final class BasicContextTracing { - // Per class Tracer. - private static final Tracer tracer = Tracing.getTracer(); - - private static void doWork() { - // Add an annotation to the current Span. - tracer.getCurrentSpan().addAnnotation("This is a doWork() annotation."); - } - - /** Main method. */ - public static void main(String[] args) { - Span span = tracer.spanBuilder("MyRootSpan").becomeRoot().startSpan(); - try (NonThrowingCloseable ws = tracer.withSpan(span)) { - doWork(); - } - span.end(); - } -} diff --git a/examples/src/main/java/com/google/instrumentation/examples/trace/BasicScopedTracing.java b/examples/src/main/java/com/google/instrumentation/examples/trace/BasicScopedTracing.java deleted file mode 100644 index 4eddf800f0..0000000000 --- a/examples/src/main/java/com/google/instrumentation/examples/trace/BasicScopedTracing.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.examples.trace; - -import com.google.instrumentation.common.NonThrowingCloseable; -import com.google.instrumentation.trace.Span; -import com.google.instrumentation.trace.Tracer; -import com.google.instrumentation.trace.Tracing; - -/** - * Example showing how to create a {@link Span} using scoped Span, install it in the current - * context, and add annotations. - */ -public final class BasicScopedTracing { - // Per class Tracer. - private static final Tracer tracer = Tracing.getTracer(); - - private static void doWork() { - // Add an annotation to the current Span. - tracer.getCurrentSpan().addAnnotation("This is a doWork() annotation."); - } - - /** Main method. */ - public static void main(String[] args) { - try (NonThrowingCloseable ss = - tracer.spanBuilder("MyRootSpan").becomeRoot().startScopedSpan()) { - doWork(); - } - } -} diff --git a/examples/src/main/java/com/google/instrumentation/examples/trace/BasicTracing.java b/examples/src/main/java/com/google/instrumentation/examples/trace/BasicTracing.java deleted file mode 100644 index 1a78aebe5b..0000000000 --- a/examples/src/main/java/com/google/instrumentation/examples/trace/BasicTracing.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.instrumentation.examples.trace; - -import com.google.instrumentation.trace.Span; -import com.google.instrumentation.trace.Tracer; -import com.google.instrumentation.trace.Tracing; - -/** Example showing how to create a {@link Span} and add annotations. */ -public final class BasicTracing { - // Per class Tracer. - private static final Tracer tracer = Tracing.getTracer(); - - private static void doWork() { - Span span = tracer.spanBuilder(null, "MyRootSpan").startSpan(); - span.addAnnotation("This annotation is added directly to the span."); - span.end(); - } - - /** Main method. */ - public static void main(String[] args) { - doWork(); - } -} diff --git a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansContextTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java similarity index 85% rename from examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansContextTracing.java rename to examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java index c83b11d96e..ef497d7e7b 100644 --- a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansContextTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java @@ -11,13 +11,13 @@ * limitations under the License. */ -package com.google.instrumentation.examples.trace; +package io.opencensus.examples.trace; -import com.google.instrumentation.common.NonThrowingCloseable; -import com.google.instrumentation.trace.Span; -import com.google.instrumentation.trace.TraceExporter; -import com.google.instrumentation.trace.Tracer; -import com.google.instrumentation.trace.Tracing; +import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.Span; +import io.opencensus.trace.TraceExporter; +import io.opencensus.trace.Tracer; +import io.opencensus.trace.Tracing; /** * Example showing how to create a child {@link Span}, install it to the current context and add diff --git a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansScopedTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java similarity index 84% rename from examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansScopedTracing.java rename to examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java index be7672d7a5..267fb639bc 100644 --- a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansScopedTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java @@ -11,13 +11,13 @@ * limitations under the License. */ -package com.google.instrumentation.examples.trace; +package io.opencensus.examples.trace; -import com.google.instrumentation.common.NonThrowingCloseable; -import com.google.instrumentation.trace.Span; -import com.google.instrumentation.trace.TraceExporter; -import com.google.instrumentation.trace.Tracer; -import com.google.instrumentation.trace.Tracing; +import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.Span; +import io.opencensus.trace.TraceExporter; +import io.opencensus.trace.Tracer; +import io.opencensus.trace.Tracing; /** * Example showing how to create a child {@link Span} using scoped Spans, install it in the current diff --git a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java similarity index 85% rename from examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansTracing.java rename to examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java index 5268a7974a..036d3684ec 100644 --- a/examples/src/main/java/com/google/instrumentation/examples/trace/MultiSpansTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java @@ -11,12 +11,12 @@ * limitations under the License. */ -package com.google.instrumentation.examples.trace; +package io.opencensus.examples.trace; -import com.google.instrumentation.trace.Span; -import com.google.instrumentation.trace.TraceExporter; -import com.google.instrumentation.trace.Tracer; -import com.google.instrumentation.trace.Tracing; +import io.opencensus.trace.Span; +import io.opencensus.trace.TraceExporter; +import io.opencensus.trace.Tracer; +import io.opencensus.trace.Tracing; /** Example showing how to directly create a child {@link Span} and add annotations. */ public final class MultiSpansTracing { diff --git a/settings.gradle b/settings.gradle index e7881b0f19..ade14ea5e3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,14 @@ rootProject.name = "instrumentation-java" + +include ":opencensus-api" include ":all" include ":core" include ":core_impl" include ":core_impl_java" include ":core_impl_android" +project(':opencensus-api').projectDir = "$rootDir/api" as File + // Java8 projects only if (JavaVersion.current().isJava8Compatible()) { include ":examples" From e9c1373c29df2a7b3426c2f71c94a2467f1129ed Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 5 Jun 2017 12:03:39 -0700 Subject: [PATCH 0149/1581] Define latency buckets boundaries in the API to allow UIs to use them when display data. --- .../io/opencensus/trace/TraceExporter.java | 230 +++++++++--------- 1 file changed, 110 insertions(+), 120 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/TraceExporter.java b/api/src/main/java/io/opencensus/trace/TraceExporter.java index 7da2d60408..4328e80dcc 100644 --- a/api/src/main/java/io/opencensus/trace/TraceExporter.java +++ b/api/src/main/java/io/opencensus/trace/TraceExporter.java @@ -22,8 +22,8 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -172,6 +172,99 @@ public abstract Collection getErrorBasedSampledSpans( */ public abstract void unregisterSpanNamesForCollection(Collection spanNames); + /** + * The latency buckets boundaries. Samples based on latency for successful spans (the status of + * the span has a canonical code different than {@link CanonicalCode#OK}) are collected in one + * of these latency buckets. + */ + public enum LatencyBucketsBoundaries { + // Stores finished successful requests of duration within the interval [0, 10us) + ZERO_MICROSx10(0, TimeUnit.MICROSECONDS.toNanos(10), "0", "10us)"), + // Stores finished successful requests of duration within the interval [10us, 100us) + MICROSx10_MICROSx100( + TimeUnit.MICROSECONDS.toNanos(10), TimeUnit.MICROSECONDS.toNanos(100), "10us", "100us"), + // Stores finished successful requests of duration within the interval [100us, 1ms) + MICROSx100_MILLIx1( + TimeUnit.MICROSECONDS.toNanos(100), TimeUnit.MILLISECONDS.toNanos(1), "100us", "1ms"), + // Stores finished successful requests of duration within the interval [1ms, 10ms) + MILLIx1_MILLIx10( + TimeUnit.MILLISECONDS.toNanos(1), TimeUnit.MILLISECONDS.toNanos(10), "1ms", "10ms"), + // Stores finished successful requests of duration within the interval [10ms, 100ms) + MILLIx10_MILLIx100( + TimeUnit.MILLISECONDS.toNanos(10), TimeUnit.MILLISECONDS.toNanos(100), "10ms", "100ms"), + // Stores finished successful requests of duration within the interval [100ms, 1sec) + MILLIx100_SECONDx1( + TimeUnit.MILLISECONDS.toNanos(100), TimeUnit.SECONDS.toNanos(1), "100ms", "1sec"), + // Stores finished successful requests of duration within the interval [1sec, 10sec) + SECONDx1_SECONDx10( + TimeUnit.SECONDS.toNanos(1), TimeUnit.SECONDS.toNanos(10), "1sec", "10sec"), + // Stores finished successful requests of duration within the interval [10sec, 100sec) + SECONDx10_SECONDx100( + TimeUnit.SECONDS.toNanos(10), TimeUnit.SECONDS.toNanos(100), "10sec", "100sec"), + // Stores finished successful requests of duration >= 100sec + SECONDx100_MAX(TimeUnit.SECONDS.toNanos(100), Long.MAX_VALUE, "100sec", "INF"); + + /** + * Constructs a {@code LatencyBucketsBoundaries} with the given boundaries and label. + * + * @param latencyLowerNs the latency lower bound of the bucket. + * @param latencyUpperNs the latency upper bound of the bucket. + * @param latencyLowerString the human readable string of the {@code latencyLowerNs} value. + * @param latencyUpperString the human readable string of the {@code latencyUpperNs} value. + */ + LatencyBucketsBoundaries( + long latencyLowerNs, + long latencyUpperNs, + String latencyLowerString, + String latencyUpperString) { + this.latencyLowerNs = latencyLowerNs; + this.latencyUpperNs = latencyUpperNs; + this.latencyLowerString = latencyLowerString; + this.latencyUpperString = latencyUpperString; + } + + /** + * Returns the latency lower bound of the bucket. + * + * @return the latency lower bound of the bucket. + */ + public long getLatencyLowerNs() { + return latencyLowerNs; + } + + /** + * Returns the latency upper bound of the bucket. + * + * @return the latency upper bound of the bucket. + */ + public long getLatencyUpperNs() { + return latencyUpperNs; + } + + /** + * Returns the human readable string of the {@code getLatencyLowerNs()} value. + * + * @return the human readable string of the {@code getLatencyLowerNs()} value. + */ + public String getLatencyLowerString() { + return latencyLowerString; + } + + /** + * Returns the human readable string of the {@code getLatencyUpperNs()} value. + * + * @return the human readable string of the {@code getLatencyUpperNs()} value. + */ + public String getLatencyUpperString() { + return latencyUpperString; + } + + private final long latencyLowerNs; + private final long latencyUpperNs; + private final String latencyLowerString; + private final String latencyUpperString; + } + /** The summary of all in-process debugging information. */ @AutoValue @Immutable @@ -211,8 +304,8 @@ public abstract static class PerSpanNameSummary { * Returns a new instance of {@code PerSpanNameSummary}. * * @param numActiveSpans the number of sampled spans. - * @param latencyBucketSummaries the summary for the latency buckets. - * @param errorBucketSummaries the summary for the error buckets. + * @param latencyBucketsSummaries the summary for the latency buckets. + * @param errorBucketsSummaries the summary for the error buckets. * @return a new instance of {@code PerSpanNameSummary}. * @throws NullPointerException if {@code latencyBucketSummaries} or {@code * errorBucketSummaries} are {@code null}. @@ -220,17 +313,17 @@ public abstract static class PerSpanNameSummary { */ public static PerSpanNameSummary create( int numActiveSpans, - List latencyBucketSummaries, - List errorBucketSummaries) { + Map latencyBucketsSummaries, + Map errorBucketsSummaries) { checkArgument(numActiveSpans >= 0, "Negative numActiveSpans."); return new AutoValue_TraceExporter_InProcessDebuggingHandler_Summary_PerSpanNameSummary( numActiveSpans, - Collections.unmodifiableList( - new ArrayList( - checkNotNull(latencyBucketSummaries, "latencyBucketSummaries"))), - Collections.unmodifiableList( - new ArrayList( - checkNotNull(errorBucketSummaries, "errorBucketSummaries")))); + Collections.unmodifiableMap( + new HashMap( + checkNotNull(latencyBucketsSummaries, "latencyBucketsSummaries"))), + Collections.unmodifiableMap( + new HashMap( + checkNotNull(errorBucketsSummaries, "errorBucketsSummaries")))); } /** @@ -241,121 +334,18 @@ public static PerSpanNameSummary create( public abstract int getNumActiveSpans(); /** - * Returns the list of all latency based sampled buckets summary. - * - *

              The list is sorted based on the lower latency boundary, and the upper bound of one - * match the lower bound of the next. Every bucket contains samples with latency within the - * interval [lowerBoundary, upperBoundary). + * Returns the number of samples for each latency based sampled bucket. * - * @return the list of all latency based sampled buckets summary. + * @return the number of samples for each latency based sampled bucket. */ - public abstract List getLatencyBucketSummaries(); + public abstract Map getLatencyBucketsSummaries(); /** - * Returns the list of all error based sampled buckets summary. - * - *

              The list is sorted based on the {@link CanonicalCode#value()} and contains an entry - * for each of the values other than {@link CanonicalCode#OK}. + * Returns the number of samples for each error based sampled bucket. * - * @return the list of all error based sampled buckets summary. + * @return the number of samples for each error based sampled bucket. */ - public abstract List getErrorBucketSummaries(); - - /** - * Summary of a latency based sampled spans bucket. Contains {@code Span} samples with - * latency between [latencyLowerNs, latencyUpperNs). - */ - @AutoValue - @Immutable - public abstract static class LatencyBucketSummary { - - LatencyBucketSummary() {} - - /** - * Returns a new instance of {@code LatencyBucketSummary}. The latency of the samples is - * in the interval [latencyLowerNs, latencyUpperNs). - * - * @param numSamples the number of sampled spans. - * @param latencyLowerNs the latency lower bound. - * @param latencyUpperNs the latency upper bound. - * @return a new instance of {@code LatencyBucketSummary}. - * @throws IllegalArgumentException if {@code numSamples} or {@code latencyLowerNs} or - * {@code latencyUpperNs} are negative. - */ - public static LatencyBucketSummary create( - int numSamples, long latencyLowerNs, long latencyUpperNs) { - checkArgument(numSamples >= 0, "Negative numSamples."); - checkArgument(latencyLowerNs >= 0, "Negative latencyLowerNs"); - checkArgument(latencyUpperNs >= 0, "Negative latencyUpperNs"); - //CHECKSTYLE:OFF: Long class name. - return new AutoValue_TraceExporter_InProcessDebuggingHandler_Summary_PerSpanNameSummary_LatencyBucketSummary( - numSamples, latencyLowerNs, latencyUpperNs); - //CHECKSTYLE:ON: Long class name. - } - - /** - * Returns the number of sampled spans in this bucket. - * - * @return the number of sampled spans in this bucket. - */ - public abstract int getNumSamples(); - - /** - * Returns the latency lower bound of this bucket (inclusive). - * - * @return the latency lower bound of this bucket. - */ - public abstract long getLatencyLowerNs(); - - /** - * Returns the latency upper bound of this bucket (exclusive). - * - * @return the latency upper bound of this bucket. - */ - public abstract long getLatencyUpperNs(); - } - - /** Summary of an error based sampled spans bucket. */ - @AutoValue - @Immutable - public abstract static class ErrorBucketSummary { - - ErrorBucketSummary() {} - - /** - * Returns a new instance of {@code ErrorBucketSummary}. - * - * @param numSamples the number of sampled spans. - * @param canonicalCode the error code of the bucket. - * @return a new instance of {@code ErrorBucketSummary}. - * @throws NullPointerException if {@code canonicalCode} is {@code null}. - * @throws IllegalArgumentException if {@code canonicalCode} is {@link CanonicalCode#OK} - * or {@code numSamples} is negative. - */ - public static ErrorBucketSummary create(int numSamples, CanonicalCode canonicalCode) { - checkArgument(numSamples >= 0, "Negative numSamples."); - checkArgument(canonicalCode != CanonicalCode.OK, "Invalid canonical code."); - //CHECKSTYLE:OFF: Long class name. - return new AutoValue_TraceExporter_InProcessDebuggingHandler_Summary_PerSpanNameSummary_ErrorBucketSummary( - numSamples, canonicalCode); - //CHECKSTYLE:ON: Long class name. - } - - /** - * Returns the number of sampled spans in this bucket. - * - * @return the number of sampled spans in this bucket. - */ - public abstract int getNumSamples(); - - /** - * Returns the {@code CanonicalCode} for this bucket. Always different than {@link - * CanonicalCode#OK}. - * - * @return the {@code CanonicalCode} for this bucket. - */ - public abstract CanonicalCode getCanonicalCode(); - } + public abstract Map getErrorBucketsSummaries(); } } From 2130f8ab51d49e10d6dabd91a2512fef1ff51cb2 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Tue, 6 Jun 2017 14:24:14 -0700 Subject: [PATCH 0150/1581] Add a link to JIRA bug for releasing instruction. (#338) * Add a link to JIRA bug for releasing instruction. * Add a list on getting permissons. --- RELEASING.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RELEASING.md b/RELEASING.md index e21b6cbf1e..dffbb2456c 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -19,8 +19,11 @@ your OSSRH (OSS Repository Hosting) account and signing keys. page](http://central.sonatype.org/pages/ossrh-guide.html) to set up an account with OSSRH. - You only need to create the account, not set up a new project - - Contact a Instrumentation Java maintainer to add your account after you + - Contact a Instrumentation Java maintainer on JIRA to add your account after you have created it. + - Comment under [this JIRA bug](https://issues.sonatype.org/browse/OSSRH-27038?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel) + for release permission to com.google.instrumentation. + - Request release permission to io.opencensus. - (For release deployment only) [Install GnuPG](http://central.sonatype.org/pages/working-with-pgp-signatures.html#installing-gnupg) and [generate your key From 63377c818802f072380b04fef798a50385bc49de Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 6 Jun 2017 14:01:35 -0700 Subject: [PATCH 0151/1581] Remove string format of the boundaries. Rename the enum to LatencyBucketBoundaries. --- .../io/opencensus/trace/TraceExporter.java | 63 ++++++------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/TraceExporter.java b/api/src/main/java/io/opencensus/trace/TraceExporter.java index 4328e80dcc..7d6c8c7f2a 100644 --- a/api/src/main/java/io/opencensus/trace/TraceExporter.java +++ b/api/src/main/java/io/opencensus/trace/TraceExporter.java @@ -18,7 +18,6 @@ import com.google.auto.value.AutoValue; import io.opencensus.trace.Status.CanonicalCode; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -174,53 +173,47 @@ public abstract Collection getErrorBasedSampledSpans( /** * The latency buckets boundaries. Samples based on latency for successful spans (the status of - * the span has a canonical code different than {@link CanonicalCode#OK}) are collected in one - * of these latency buckets. + * the span has a canonical code equal to {@link CanonicalCode#OK}) are collected in one of + * these latency buckets. */ - public enum LatencyBucketsBoundaries { + public enum LatencyBucketBoundaries { // Stores finished successful requests of duration within the interval [0, 10us) - ZERO_MICROSx10(0, TimeUnit.MICROSECONDS.toNanos(10), "0", "10us)"), + ZERO_MICROSx10(0, TimeUnit.MICROSECONDS.toNanos(10)), // Stores finished successful requests of duration within the interval [10us, 100us) MICROSx10_MICROSx100( - TimeUnit.MICROSECONDS.toNanos(10), TimeUnit.MICROSECONDS.toNanos(100), "10us", "100us"), + TimeUnit.MICROSECONDS.toNanos(10), TimeUnit.MICROSECONDS.toNanos(100)), // Stores finished successful requests of duration within the interval [100us, 1ms) MICROSx100_MILLIx1( - TimeUnit.MICROSECONDS.toNanos(100), TimeUnit.MILLISECONDS.toNanos(1), "100us", "1ms"), + TimeUnit.MICROSECONDS.toNanos(100), TimeUnit.MILLISECONDS.toNanos(1)), // Stores finished successful requests of duration within the interval [1ms, 10ms) MILLIx1_MILLIx10( - TimeUnit.MILLISECONDS.toNanos(1), TimeUnit.MILLISECONDS.toNanos(10), "1ms", "10ms"), + TimeUnit.MILLISECONDS.toNanos(1), TimeUnit.MILLISECONDS.toNanos(10)), // Stores finished successful requests of duration within the interval [10ms, 100ms) MILLIx10_MILLIx100( - TimeUnit.MILLISECONDS.toNanos(10), TimeUnit.MILLISECONDS.toNanos(100), "10ms", "100ms"), + TimeUnit.MILLISECONDS.toNanos(10), TimeUnit.MILLISECONDS.toNanos(100)), // Stores finished successful requests of duration within the interval [100ms, 1sec) MILLIx100_SECONDx1( - TimeUnit.MILLISECONDS.toNanos(100), TimeUnit.SECONDS.toNanos(1), "100ms", "1sec"), + TimeUnit.MILLISECONDS.toNanos(100), TimeUnit.SECONDS.toNanos(1)), // Stores finished successful requests of duration within the interval [1sec, 10sec) SECONDx1_SECONDx10( - TimeUnit.SECONDS.toNanos(1), TimeUnit.SECONDS.toNanos(10), "1sec", "10sec"), + TimeUnit.SECONDS.toNanos(1), TimeUnit.SECONDS.toNanos(10)), // Stores finished successful requests of duration within the interval [10sec, 100sec) SECONDx10_SECONDx100( - TimeUnit.SECONDS.toNanos(10), TimeUnit.SECONDS.toNanos(100), "10sec", "100sec"), + TimeUnit.SECONDS.toNanos(10), TimeUnit.SECONDS.toNanos(100)), // Stores finished successful requests of duration >= 100sec - SECONDx100_MAX(TimeUnit.SECONDS.toNanos(100), Long.MAX_VALUE, "100sec", "INF"); + SECONDx100_MAX(TimeUnit.SECONDS.toNanos(100), Long.MAX_VALUE); /** - * Constructs a {@code LatencyBucketsBoundaries} with the given boundaries and label. + * Constructs a {@code LatencyBucketBoundaries} with the given boundaries and label. * * @param latencyLowerNs the latency lower bound of the bucket. * @param latencyUpperNs the latency upper bound of the bucket. - * @param latencyLowerString the human readable string of the {@code latencyLowerNs} value. - * @param latencyUpperString the human readable string of the {@code latencyUpperNs} value. */ - LatencyBucketsBoundaries( + LatencyBucketBoundaries( long latencyLowerNs, - long latencyUpperNs, - String latencyLowerString, - String latencyUpperString) { + long latencyUpperNs) { this.latencyLowerNs = latencyLowerNs; this.latencyUpperNs = latencyUpperNs; - this.latencyLowerString = latencyLowerString; - this.latencyUpperString = latencyUpperString; } /** @@ -241,28 +234,8 @@ public long getLatencyUpperNs() { return latencyUpperNs; } - /** - * Returns the human readable string of the {@code getLatencyLowerNs()} value. - * - * @return the human readable string of the {@code getLatencyLowerNs()} value. - */ - public String getLatencyLowerString() { - return latencyLowerString; - } - - /** - * Returns the human readable string of the {@code getLatencyUpperNs()} value. - * - * @return the human readable string of the {@code getLatencyUpperNs()} value. - */ - public String getLatencyUpperString() { - return latencyUpperString; - } - private final long latencyLowerNs; private final long latencyUpperNs; - private final String latencyLowerString; - private final String latencyUpperString; } /** The summary of all in-process debugging information. */ @@ -313,13 +286,13 @@ public abstract static class PerSpanNameSummary { */ public static PerSpanNameSummary create( int numActiveSpans, - Map latencyBucketsSummaries, + Map latencyBucketsSummaries, Map errorBucketsSummaries) { checkArgument(numActiveSpans >= 0, "Negative numActiveSpans."); return new AutoValue_TraceExporter_InProcessDebuggingHandler_Summary_PerSpanNameSummary( numActiveSpans, Collections.unmodifiableMap( - new HashMap( + new HashMap( checkNotNull(latencyBucketsSummaries, "latencyBucketsSummaries"))), Collections.unmodifiableMap( new HashMap( @@ -338,7 +311,7 @@ public static PerSpanNameSummary create( * * @return the number of samples for each latency based sampled bucket. */ - public abstract Map getLatencyBucketsSummaries(); + public abstract Map getLatencyBucketsSummaries(); /** * Returns the number of samples for each error based sampled bucket. From 9f0e5d3cb6b80357dabc3ee9771335096cd35437 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 7 Jun 2017 14:23:30 -0700 Subject: [PATCH 0152/1581] Move TraceConfig into its own package, extract inner class TraceParams. (#340) --- .../io/opencensus/trace/TraceComponent.java | 1 + .../java/io/opencensus/trace/TraceConfig.java | 213 ------------------ .../java/io/opencensus/trace/Tracing.java | 1 + .../opencensus/trace/config/TraceConfig.java | 67 ++++++ .../opencensus/trace/config/TraceParams.java | 165 ++++++++++++++ .../opencensus/trace/TraceComponentTest.java | 1 + .../io/opencensus/trace/TraceParamsTest.java | 2 +- .../java/io/opencensus/trace/TracingTest.java | 1 + .../io/opencensus/trace/SpanFactoryImpl.java | 3 +- .../java/io/opencensus/trace/SpanImpl.java | 2 +- .../trace/TraceComponentImplBase.java | 1 + .../io/opencensus/trace/TraceConfigImpl.java | 3 + .../java/io/opencensus/trace/TracerImpl.java | 1 + .../opencensus/trace/SpanFactoryImplTest.java | 3 +- .../io/opencensus/trace/SpanImplTest.java | 2 +- .../opencensus/trace/TraceConfigImplTest.java | 2 +- .../trace/TraceExporterImplTest.java | 2 +- 17 files changed, 250 insertions(+), 220 deletions(-) delete mode 100644 api/src/main/java/io/opencensus/trace/TraceConfig.java create mode 100644 api/src/main/java/io/opencensus/trace/config/TraceConfig.java create mode 100644 api/src/main/java/io/opencensus/trace/config/TraceParams.java diff --git a/api/src/main/java/io/opencensus/trace/TraceComponent.java b/api/src/main/java/io/opencensus/trace/TraceComponent.java index 1829417f5a..bee02daea7 100644 --- a/api/src/main/java/io/opencensus/trace/TraceComponent.java +++ b/api/src/main/java/io/opencensus/trace/TraceComponent.java @@ -15,6 +15,7 @@ import io.opencensus.common.Clock; import io.opencensus.internal.ZeroTimeClock; +import io.opencensus.trace.config.TraceConfig; /** * Class that holds the implementation instances for {@link Tracer}, {@link diff --git a/api/src/main/java/io/opencensus/trace/TraceConfig.java b/api/src/main/java/io/opencensus/trace/TraceConfig.java deleted file mode 100644 index 41fa75b802..0000000000 --- a/api/src/main/java/io/opencensus/trace/TraceConfig.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.trace; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.auto.value.AutoValue; -import javax.annotation.concurrent.Immutable; - -/** - * Global configuration of the trace service. This allows users to change configs for the default - * sampler, maximum events to be kept, etc. (see {@link TraceParams} for details). - */ -public abstract class TraceConfig { - private static final NoopTraceConfig noopTraceConfig = new NoopTraceConfig(); - - /** - * Returns the active {@code TraceParams}. - * - * @return the active {@code TraceParams}. - */ - public abstract TraceParams getActiveTraceParams(); - - /** - * Updates the active {@link TraceParams}. - * - * @param traceParams the new active {@code TraceParams}. - */ - public abstract void updateActiveTraceParams(TraceParams traceParams); - - /** - * Temporary updates the active {@link TraceParams} for {@code durationNs} nanoseconds. - * - * @param traceParams the new active {@code TraceParams}. - * @param durationNs the duration for how long the new params will be active. - */ - public abstract void temporaryUpdateActiveTraceParams(TraceParams traceParams, long durationNs); - - /** - * Returns the no-op implementation of the {@code TraceConfig}. - * - * @return the no-op implementation of the {@code TraceConfig}. - */ - static TraceConfig getNoopTraceConfig() { - return noopTraceConfig; - } - - /** Class that holds global trace parameters. */ - @AutoValue - @Immutable - public abstract static class TraceParams { - // These values are the default values for all the global parameters. - private static final double DEFAULT_PROBABILITY = 1e-4; - private static final Sampler DEFAULT_SAMPLER = Samplers.probabilitySampler(DEFAULT_PROBABILITY); - private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES = 32; - private static final int DEFAULT_SPAN_MAX_NUM_ANNOTATIONS = 32; - private static final int DEFAULT_SPAN_MAX_NUM_NETWORK_EVENTS = 128; - private static final int DEFAULT_SPAN_MAX_NUM_LINKS = 128; - - public static final TraceParams DEFAULT = - TraceParams.builder() - .setSampler(DEFAULT_SAMPLER) - .setMaxNumberOfAttributes(DEFAULT_SPAN_MAX_NUM_ATTRIBUTES) - .setMaxNumberOfAnnotations(DEFAULT_SPAN_MAX_NUM_ANNOTATIONS) - .setMaxNumberOfNetworkEvents(DEFAULT_SPAN_MAX_NUM_NETWORK_EVENTS) - .setMaxNumberOfLinks(DEFAULT_SPAN_MAX_NUM_LINKS) - .build(); - - /** - * Returns the global default {@code Sampler}. Used if no {@code Sampler} is provided in {@link - * StartSpanOptions}. - * - * @return the global default {@code Sampler}. - */ - public abstract Sampler getSampler(); - - /** - * Returns the global default max number of attributes per {@link Span}. - * - * @return the global default max number of attributes per {@link Span}. - */ - public abstract int getMaxNumberOfAttributes(); - - /** - * Returns the global default max number of {@link Annotation} events per {@link Span}. - * - * @return the global default max number of {@code Annotation} events per {@code Span}. - */ - public abstract int getMaxNumberOfAnnotations(); - - /** - * Returns the global default max number of {@link NetworkEvent} events per {@link Span}. - * - * @return the global default max number of {@code NetworkEvent} events per {@code Span}. - */ - public abstract int getMaxNumberOfNetworkEvents(); - - /** - * Returns the global default max number of {@link Link} entries per {@link Span}. - * - * @return the global default max number of {@code Link} entries per {@code Span}. - */ - public abstract int getMaxNumberOfLinks(); - - private static Builder builder() { - return new AutoValue_TraceConfig_TraceParams.Builder(); - } - - /** - * Returns a {@link Builder} initialized to the same property values as the current instance. - * - * @return a {@link Builder} initialized to the same property values as the current instance. - */ - public abstract Builder toBuilder(); - - /** A {@code Builder} class for {@link TraceParams}. */ - @AutoValue.Builder - public abstract static class Builder { - - /** - * Sets the global default {@code Sampler}. It must be not {@code null} otherwise {@link - * #build()} will throw an exception. - * - * @param sampler the global default {@code Sampler}. - * @return this. - */ - public abstract Builder setSampler(Sampler sampler); - - /** - * Sets the global default max number of attributes per {@link Span}. - * - * @param maxNumberOfAttributes the global default max number of attributes per {@link Span}. - * It must be positive otherwise {@link #build()} will throw an exception. - * @return this. - */ - public abstract Builder setMaxNumberOfAttributes(int maxNumberOfAttributes); - - /** - * Sets the global default max number of {@link Annotation} events per {@link Span}. - * - * @param maxNumberOfAnnotations the global default max number of {@link Annotation} events - * per {@link Span}. It must be positive otherwise {@link #build()} will throw an - * exception. - * @return this. - */ - public abstract Builder setMaxNumberOfAnnotations(int maxNumberOfAnnotations); - - /** - * Sets the global default max number of {@link NetworkEvent} events per {@link Span}. - * - * @param maxNumberOfNetworkEvents the global default max number of {@link NetworkEvent} - * events per {@link Span}. It must be positive otherwise {@link #build()} will throw an - * exception. - * @return this. - */ - public abstract Builder setMaxNumberOfNetworkEvents(int maxNumberOfNetworkEvents); - - /** - * Sets the global default max number of {@link Link} entries per {@link Span}. - * - * @param maxNumberOfLinks the global default max number of {@link Link} entries per {@link - * Span}. It must be positive otherwise {@link #build()} will throw an exception. - * @return this. - */ - public abstract Builder setMaxNumberOfLinks(int maxNumberOfLinks); - - abstract TraceParams autoBuild(); - - /** - * Builds and returns a {@code TraceParams} with the desired values. - * - * @return a {@code TraceParams} with the desired values. - * @throws NullPointerException if the sampler is {@code null}. - * @throws IllegalArgumentException if any of the max numbers are not positive. - */ - public TraceParams build() { - TraceParams traceParams = autoBuild(); - checkNotNull(traceParams.getSampler(), "sampler"); - checkArgument(traceParams.getMaxNumberOfAttributes() > 0, "maxNumberOfAttributes"); - checkArgument(traceParams.getMaxNumberOfAnnotations() > 0, "maxNumberOfAnnotations"); - checkArgument(traceParams.getMaxNumberOfNetworkEvents() > 0, "maxNumberOfNetworkEvents"); - checkArgument(traceParams.getMaxNumberOfLinks() > 0, "maxNumberOfLinks"); - return traceParams; - } - } - } - - private static final class NoopTraceConfig extends TraceConfig { - - @Override - public TraceParams getActiveTraceParams() { - return TraceParams.DEFAULT; - } - - @Override - public void updateActiveTraceParams(TraceParams traceParams) {} - - @Override - public void temporaryUpdateActiveTraceParams(TraceParams traceParams, long durationNs) {} - } -} diff --git a/api/src/main/java/io/opencensus/trace/Tracing.java b/api/src/main/java/io/opencensus/trace/Tracing.java index e6d34a45f4..771b8553c7 100644 --- a/api/src/main/java/io/opencensus/trace/Tracing.java +++ b/api/src/main/java/io/opencensus/trace/Tracing.java @@ -16,6 +16,7 @@ import com.google.common.annotations.VisibleForTesting; import io.opencensus.common.Clock; import io.opencensus.internal.Provider; +import io.opencensus.trace.config.TraceConfig; import java.util.logging.Level; import java.util.logging.Logger; diff --git a/api/src/main/java/io/opencensus/trace/config/TraceConfig.java b/api/src/main/java/io/opencensus/trace/config/TraceConfig.java new file mode 100644 index 0000000000..80f206c951 --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/config/TraceConfig.java @@ -0,0 +1,67 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.config; + +/** + * Global configuration of the trace service. This allows users to change configs for the default + * sampler, maximum events to be kept, etc. (see {@link TraceParams} for details). + */ +public abstract class TraceConfig { + private static final NoopTraceConfig NOOP_TRACE_CONFIG = new NoopTraceConfig(); + + /** + * Returns the active {@code TraceParams}. + * + * @return the active {@code TraceParams}. + */ + public abstract TraceParams getActiveTraceParams(); + + /** + * Updates the active {@link TraceParams}. + * + * @param traceParams the new active {@code TraceParams}. + */ + public abstract void updateActiveTraceParams(TraceParams traceParams); + + /** + * Temporary updates the active {@link TraceParams} for {@code durationNs} nanoseconds. + * + * @param traceParams the new active {@code TraceParams}. + * @param durationNs the duration for how long the new params will be active. + */ + public abstract void temporaryUpdateActiveTraceParams(TraceParams traceParams, long durationNs); + + /** + * Returns the no-op implementation of the {@code TraceConfig}. + * + * @return the no-op implementation of the {@code TraceConfig}. + */ + public static TraceConfig getNoopTraceConfig() { + return NOOP_TRACE_CONFIG; + } + + private static final class NoopTraceConfig extends TraceConfig { + + @Override + public TraceParams getActiveTraceParams() { + return TraceParams.DEFAULT; + } + + @Override + public void updateActiveTraceParams(TraceParams traceParams) {} + + @Override + public void temporaryUpdateActiveTraceParams(TraceParams traceParams, long durationNs) {} + } +} diff --git a/api/src/main/java/io/opencensus/trace/config/TraceParams.java b/api/src/main/java/io/opencensus/trace/config/TraceParams.java new file mode 100644 index 0000000000..c446334265 --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/config/TraceParams.java @@ -0,0 +1,165 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.config; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.auto.value.AutoValue; +import io.opencensus.trace.Annotation; +import io.opencensus.trace.Link; +import io.opencensus.trace.NetworkEvent; +import io.opencensus.trace.Sampler; +import io.opencensus.trace.Samplers; +import io.opencensus.trace.Span; +import io.opencensus.trace.StartSpanOptions; +import javax.annotation.concurrent.Immutable; + +/** Class that holds global trace parameters. */ +@AutoValue +@Immutable +public abstract class TraceParams { + // These values are the default values for all the global parameters. + private static final double DEFAULT_PROBABILITY = 1e-4; + private static final Sampler DEFAULT_SAMPLER = Samplers.probabilitySampler(DEFAULT_PROBABILITY); + private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES = 32; + private static final int DEFAULT_SPAN_MAX_NUM_ANNOTATIONS = 32; + private static final int DEFAULT_SPAN_MAX_NUM_NETWORK_EVENTS = 128; + private static final int DEFAULT_SPAN_MAX_NUM_LINKS = 128; + + public static final TraceParams DEFAULT = + TraceParams.builder() + .setSampler(DEFAULT_SAMPLER) + .setMaxNumberOfAttributes(DEFAULT_SPAN_MAX_NUM_ATTRIBUTES) + .setMaxNumberOfAnnotations(DEFAULT_SPAN_MAX_NUM_ANNOTATIONS) + .setMaxNumberOfNetworkEvents(DEFAULT_SPAN_MAX_NUM_NETWORK_EVENTS) + .setMaxNumberOfLinks(DEFAULT_SPAN_MAX_NUM_LINKS) + .build(); + + /** + * Returns the global default {@code Sampler}. Used if no {@code Sampler} is provided in {@link + * StartSpanOptions}. + * + * @return the global default {@code Sampler}. + */ + public abstract Sampler getSampler(); + + /** + * Returns the global default max number of attributes per {@link Span}. + * + * @return the global default max number of attributes per {@link Span}. + */ + public abstract int getMaxNumberOfAttributes(); + + /** + * Returns the global default max number of {@link Annotation} events per {@link Span}. + * + * @return the global default max number of {@code Annotation} events per {@code Span}. + */ + public abstract int getMaxNumberOfAnnotations(); + + /** + * Returns the global default max number of {@link NetworkEvent} events per {@link Span}. + * + * @return the global default max number of {@code NetworkEvent} events per {@code Span}. + */ + public abstract int getMaxNumberOfNetworkEvents(); + + /** + * Returns the global default max number of {@link Link} entries per {@link Span}. + * + * @return the global default max number of {@code Link} entries per {@code Span}. + */ + public abstract int getMaxNumberOfLinks(); + + private static Builder builder() { + return new AutoValue_TraceParams.Builder(); + } + + /** + * Returns a {@link Builder} initialized to the same property values as the current instance. + * + * @return a {@link Builder} initialized to the same property values as the current instance. + */ + public abstract Builder toBuilder(); + + /** A {@code Builder} class for {@link TraceParams}. */ + @AutoValue.Builder + public abstract static class Builder { + + /** + * Sets the global default {@code Sampler}. It must be not {@code null} otherwise {@link + * #build()} will throw an exception. + * + * @param sampler the global default {@code Sampler}. + * @return this. + */ + public abstract Builder setSampler(Sampler sampler); + + /** + * Sets the global default max number of attributes per {@link Span}. + * + * @param maxNumberOfAttributes the global default max number of attributes per {@link Span}. + * It must be positive otherwise {@link #build()} will throw an exception. + * @return this. + */ + public abstract Builder setMaxNumberOfAttributes(int maxNumberOfAttributes); + + /** + * Sets the global default max number of {@link Annotation} events per {@link Span}. + * + * @param maxNumberOfAnnotations the global default max number of {@link Annotation} events + * per {@link Span}. It must be positive otherwise {@link #build()} will throw an + * exception. + * @return this. + */ + public abstract Builder setMaxNumberOfAnnotations(int maxNumberOfAnnotations); + + /** + * Sets the global default max number of {@link NetworkEvent} events per {@link Span}. + * + * @param maxNumberOfNetworkEvents the global default max number of {@link NetworkEvent} + * events per {@link Span}. It must be positive otherwise {@link #build()} will throw an + * exception. + * @return this. + */ + public abstract Builder setMaxNumberOfNetworkEvents(int maxNumberOfNetworkEvents); + + /** + * Sets the global default max number of {@link Link} entries per {@link Span}. + * + * @param maxNumberOfLinks the global default max number of {@link Link} entries per {@link + * Span}. It must be positive otherwise {@link #build()} will throw an exception. + * @return this. + */ + public abstract Builder setMaxNumberOfLinks(int maxNumberOfLinks); + + abstract TraceParams autoBuild(); + + /** + * Builds and returns a {@code TraceParams} with the desired values. + * + * @return a {@code TraceParams} with the desired values. + * @throws NullPointerException if the sampler is {@code null}. + * @throws IllegalArgumentException if any of the max numbers are not positive. + */ + public TraceParams build() { + TraceParams traceParams = autoBuild(); + checkArgument(traceParams.getMaxNumberOfAttributes() > 0, "maxNumberOfAttributes"); + checkArgument(traceParams.getMaxNumberOfAnnotations() > 0, "maxNumberOfAnnotations"); + checkArgument(traceParams.getMaxNumberOfNetworkEvents() > 0, "maxNumberOfNetworkEvents"); + checkArgument(traceParams.getMaxNumberOfLinks() > 0, "maxNumberOfLinks"); + return traceParams; + } + } +} diff --git a/api/src/test/java/io/opencensus/trace/TraceComponentTest.java b/api/src/test/java/io/opencensus/trace/TraceComponentTest.java index 106cb965b6..cd42a98a59 100644 --- a/api/src/test/java/io/opencensus/trace/TraceComponentTest.java +++ b/api/src/test/java/io/opencensus/trace/TraceComponentTest.java @@ -16,6 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.opencensus.internal.ZeroTimeClock; +import io.opencensus.trace.config.TraceConfig; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/api/src/test/java/io/opencensus/trace/TraceParamsTest.java b/api/src/test/java/io/opencensus/trace/TraceParamsTest.java index 60f40debd0..e21485e151 100644 --- a/api/src/test/java/io/opencensus/trace/TraceParamsTest.java +++ b/api/src/test/java/io/opencensus/trace/TraceParamsTest.java @@ -15,7 +15,7 @@ import static com.google.common.truth.Truth.assertThat; -import io.opencensus.trace.TraceConfig.TraceParams; +import io.opencensus.trace.config.TraceParams; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/api/src/test/java/io/opencensus/trace/TracingTest.java b/api/src/test/java/io/opencensus/trace/TracingTest.java index b7c9be252d..c23e7c6f7f 100644 --- a/api/src/test/java/io/opencensus/trace/TracingTest.java +++ b/api/src/test/java/io/opencensus/trace/TracingTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import io.opencensus.trace.config.TraceConfig; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java index 695a2215d7..703b5b3b2b 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java @@ -18,7 +18,8 @@ import io.opencensus.common.Clock; import io.opencensus.trace.Link.Type; import io.opencensus.trace.Span.Options; -import io.opencensus.trace.TraceConfig.TraceParams; +import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.config.TraceParams; import java.util.EnumSet; import java.util.List; import java.util.Random; diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java index 2fcb7cb7ef..6eab0ccc30 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java @@ -19,7 +19,7 @@ import com.google.common.collect.EvictingQueue; import io.opencensus.common.Clock; import io.opencensus.trace.SpanData.TimedEvent; -import io.opencensus.trace.TraceConfig.TraceParams; +import io.opencensus.trace.config.TraceParams; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; diff --git a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java index 7e25dadac1..c313d1e1fe 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java @@ -15,6 +15,7 @@ import io.opencensus.common.Clock; import io.opencensus.common.EventQueue; +import io.opencensus.trace.config.TraceConfig; /** Base implementation of the {@link TraceComponent}. */ class TraceComponentImplBase extends TraceComponent { diff --git a/core_impl/src/main/java/io/opencensus/trace/TraceConfigImpl.java b/core_impl/src/main/java/io/opencensus/trace/TraceConfigImpl.java index eef2be799e..673c4c8a2d 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TraceConfigImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/TraceConfigImpl.java @@ -13,6 +13,9 @@ package io.opencensus.trace; +import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.config.TraceParams; + /** * Global configuration of the trace service. This allows users to change configs for the default * sampler, maximum events to be kept, etc. diff --git a/core_impl/src/main/java/io/opencensus/trace/TracerImpl.java b/core_impl/src/main/java/io/opencensus/trace/TracerImpl.java index 996607ce5f..7b550cc158 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TracerImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/TracerImpl.java @@ -14,6 +14,7 @@ package io.opencensus.trace; import io.opencensus.common.Clock; +import io.opencensus.trace.config.TraceConfig; /** Implementation of the {@link Tracer}. */ final class TracerImpl extends Tracer { diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java index bc2bbfb2c3..e93d30c24f 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java @@ -19,7 +19,8 @@ import io.opencensus.internal.TestClock; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; -import io.opencensus.trace.TraceConfig.TraceParams; +import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.config.TraceParams; import java.util.Random; import org.junit.Before; import org.junit.Test; diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java index 6c9d57fc31..81fd831620 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java @@ -20,7 +20,7 @@ import io.opencensus.internal.TestClock; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; -import io.opencensus.trace.TraceConfig.TraceParams; +import io.opencensus.trace.config.TraceParams; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; diff --git a/core_impl/src/test/java/io/opencensus/trace/TraceConfigImplTest.java b/core_impl/src/test/java/io/opencensus/trace/TraceConfigImplTest.java index 6e43cbb4f7..9872dd61dd 100644 --- a/core_impl/src/test/java/io/opencensus/trace/TraceConfigImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/TraceConfigImplTest.java @@ -15,7 +15,7 @@ import static com.google.common.truth.Truth.assertThat; -import io.opencensus.trace.TraceConfig.TraceParams; +import io.opencensus.trace.config.TraceParams; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core_impl/src/test/java/io/opencensus/trace/TraceExporterImplTest.java b/core_impl/src/test/java/io/opencensus/trace/TraceExporterImplTest.java index 4684bef8dd..4c181e5f0a 100644 --- a/core_impl/src/test/java/io/opencensus/trace/TraceExporterImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/TraceExporterImplTest.java @@ -20,7 +20,7 @@ import io.opencensus.common.MillisClock; import io.opencensus.common.SimpleEventQueue; import io.opencensus.trace.Span.Options; -import io.opencensus.trace.TraceConfig.TraceParams; +import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.TraceExporter.ServiceHandler; import java.util.ArrayList; import java.util.Collection; From f3930443b38c92b4775a25756b1fb30d49660234 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 7 Jun 2017 16:00:18 -0700 Subject: [PATCH 0153/1581] Split TraceExporter class into ExportComponent and all the sub-components in an export package. (#332) --- .../io/opencensus/trace/TraceComponent.java | 13 +- .../io/opencensus/trace/TraceExporter.java | 572 ------------------ .../java/io/opencensus/trace/Tracing.java | 7 +- .../trace/export/ExportComponent.java | 69 +++ .../export/InProcessDebuggingHandler.java | 417 +++++++++++++ .../opencensus/trace/export/SpanExporter.java | 127 ++++ .../opencensus/trace/TraceComponentTest.java | 3 +- .../java/io/opencensus/trace/TracingTest.java | 3 +- .../SpanExporterTest.java} | 24 +- .../trace/BinaryPropagationHandlerImpl.java | 53 +- .../opencensus/trace/ExportComponentImpl.java | 50 ++ ...xporterImpl.java => SpanExporterImpl.java} | 105 +--- .../opencensus/trace/StartEndHandlerImpl.java | 62 ++ .../trace/TraceComponentImplBase.java | 17 +- ...mplTest.java => SpanExporterImplTest.java} | 30 +- .../trace/TraceComponentImplBaseTest.java | 2 +- .../trace/TraceComponentImplTest.java | 2 +- .../java/io/opencensus/trace/TracingTest.java | 2 +- .../trace/MultiSpansContextTracing.java | 4 +- .../trace/MultiSpansScopedTracing.java | 4 +- .../examples/trace/MultiSpansTracing.java | 4 +- 21 files changed, 843 insertions(+), 727 deletions(-) delete mode 100644 api/src/main/java/io/opencensus/trace/TraceExporter.java create mode 100644 api/src/main/java/io/opencensus/trace/export/ExportComponent.java create mode 100644 api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java create mode 100644 api/src/main/java/io/opencensus/trace/export/SpanExporter.java rename api/src/test/java/io/opencensus/trace/{TraceExporterTest.java => export/SpanExporterTest.java} (64%) create mode 100644 core_impl/src/main/java/io/opencensus/trace/ExportComponentImpl.java rename core_impl/src/main/java/io/opencensus/trace/{TraceExporterImpl.java => SpanExporterImpl.java} (61%) create mode 100644 core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java rename core_impl/src/test/java/io/opencensus/trace/{TraceExporterImplTest.java => SpanExporterImplTest.java} (88%) diff --git a/api/src/main/java/io/opencensus/trace/TraceComponent.java b/api/src/main/java/io/opencensus/trace/TraceComponent.java index bee02daea7..54c2c8a153 100644 --- a/api/src/main/java/io/opencensus/trace/TraceComponent.java +++ b/api/src/main/java/io/opencensus/trace/TraceComponent.java @@ -16,10 +16,11 @@ import io.opencensus.common.Clock; import io.opencensus.internal.ZeroTimeClock; import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.export.ExportComponent; /** * Class that holds the implementation instances for {@link Tracer}, {@link - * BinaryPropagationHandler}, {@link Clock}, {@link TraceExporter} and {@link TraceConfig}. + * BinaryPropagationHandler}, {@link Clock}, {@link ExportComponent} and {@link TraceConfig}. * *

              Unless otherwise noted all methods (on component) results are cacheable. */ @@ -50,12 +51,12 @@ public abstract class TraceComponent { public abstract Clock getClock(); /** - * Returns the {@link TraceExporter} with the provided implementation. If no implementation is + * Returns the {@link ExportComponent} with the provided implementation. If no implementation is * provided then no-op implementations will be used. * - * @return the {@link TraceExporter} implementation. + * @return the {@link ExportComponent} implementation. */ - public abstract TraceExporter getTraceExporter(); + public abstract ExportComponent getTraceExporter(); /** * Returns the {@link TraceConfig} with the provided implementation. If no implementation is @@ -94,8 +95,8 @@ public Clock getClock() { } @Override - public TraceExporter getTraceExporter() { - return TraceExporter.getNoopTraceExporter(); + public ExportComponent getTraceExporter() { + return ExportComponent.getNoopExportComponent(); } @Override diff --git a/api/src/main/java/io/opencensus/trace/TraceExporter.java b/api/src/main/java/io/opencensus/trace/TraceExporter.java deleted file mode 100644 index 7d6c8c7f2a..0000000000 --- a/api/src/main/java/io/opencensus/trace/TraceExporter.java +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.trace; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.auto.value.AutoValue; -import io.opencensus.trace.Status.CanonicalCode; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; -import javax.annotation.concurrent.ThreadSafe; - -/** - * The main exporting API for the trace library. - * - *

              Implementation MUST ensure that all functions are thread safe. - */ -@ThreadSafe -public abstract class TraceExporter { - - private static final NoopTraceExporter noopTraceExporter = new NoopTraceExporter(); - - /** - * Returns the no-op implementation of the {@code TraceExporter}. - * - * @return the no-op implementation of the {@code TraceExporter}. - */ - static TraceExporter getNoopTraceExporter() { - return noopTraceExporter; - } - - /** - * Registers a new service handler that is used by the library to export {@code SpanData} for - * sampled spans (see {@link TraceOptions#isSampled()}). - * - *

              Example of usage: - * - *

              {@code
              -   * public static void main(String[] args) {
              -   *   Tracing.getTraceExporter().registerServiceHandler(
              -   *       "com.google.stackdriver.tracing", new StackdriverTracingServiceHandler());
              -   *   // ...
              -   * }
              -   * }
              - * - * @param name the name of the service handler. Must be unique for each service. - * @param serviceHandler the service handler that is called for each ended sampled span. - */ - public abstract void registerServiceHandler(String name, ServiceHandler serviceHandler); - - /** - * Unregisters the service handler with the provided name. - * - * @param name the name of the service handler that will be unregistered. - */ - public abstract void unregisterServiceHandler(String name); - - /** - * Returns the {@code InProcessDebuggingHandler} that can be used to get useful debugging - * information such as (active spans, latency based sampled spans, error based sampled spans). - * - * @return the {@code InProcessDebuggingHandler} or {@code null} if in-process debugging is not - * supported. - */ - @Nullable - public abstract InProcessDebuggingHandler getInProcessDebuggingHandler(); - - /** - * This class allows users to access in-process debugging information such as (getting access to - * all active spans, support latency based sampled spans and error based sampled spans). - * - *

              The active spans tracking is available for all the spans with the option {@link - * Span.Options#RECORD_EVENTS}. This functionality allows users to debug stuck operations or long - * living operations. - * - *

              For all completed spans with the option {@link Span.Options#RECORD_EVENTS} the library can - * store samples based on latency for succeeded operations or based on error code for failed - * operations. To activate this, users MUST manually configure all the span names for which - * samples will be collected (see {@link #registerSpanNamesForCollection(Collection)}). - */ - public abstract static class InProcessDebuggingHandler { - - InProcessDebuggingHandler() {} - - /** - * Returns the summary of all available in-process debugging data such as number of active - * spans, number of sampled spans in the latency based samples or error based samples. - * - *

              Latency based sampled summary buckets and error based sampled summary buckets are - * available only for span names registered using {@link - * #registerSpanNamesForCollection(Collection)}. - * - * @return the summary of all available in-process debugging data. - */ - public abstract Summary getSummary(); - - /** - * Returns a list of active spans that match the {@code filter}. - * - *

              Active spans are available for all the span names. - * - * @param filter used to filter the returned spans. - * @return a list of active spans that match the {@code filter}. - */ - public abstract Collection getActiveSpans(ActiveSpansFilter filter); - - /** - * Returns a list of succeeded spans (spans with {@link Status} equal to {@link Status#OK}) that - * match the {@code filter}. - * - *

              Latency based sampled spans are available only for span names registered using {@link - * #registerSpanNamesForCollection(Collection)}. - * - * @param filter used to filter the returned sampled spans. - * @return a list of succeeded spans that match the {@code filter}. - */ - public abstract Collection getLatencyBasedSampledSpans( - LatencyBasedSampledSpansFilter filter); - - /** - * Returns a list of failed spans (spans with {@link Status} other than {@link Status#OK}) that - * match the {@code filter}. - * - *

              Error based sampled spans are available only for span names registered using {@link - * #registerSpanNamesForCollection(Collection)}. - * - * @param filter used to filter the returned sampled spans. - * @return a list of failed spans that match the {@code filter}. - */ - public abstract Collection getErrorBasedSampledSpans( - ErrorBasedSampledSpansFilter filter); - - /** - * Appends a list of span names for which the library will collect latency based sampled spans - * and error based sampled spans. - * - *

              If called multiple times the library keeps the list of unique span names from all the - * calls. - * - * @param spanNames list of span names for which the library will collect samples. - */ - public abstract void registerSpanNamesForCollection(Collection spanNames); - - /** - * Removes a list of span names for which the library will collect latency based sampled spans - * and error based sampled spans. - * - *

              The library keeps the list of unique registered span names for which samples will be - * called. This method allows users to remove span names from that list. - * - * @param spanNames list of span names for which the library will no longer collect samples. - */ - public abstract void unregisterSpanNamesForCollection(Collection spanNames); - - /** - * The latency buckets boundaries. Samples based on latency for successful spans (the status of - * the span has a canonical code equal to {@link CanonicalCode#OK}) are collected in one of - * these latency buckets. - */ - public enum LatencyBucketBoundaries { - // Stores finished successful requests of duration within the interval [0, 10us) - ZERO_MICROSx10(0, TimeUnit.MICROSECONDS.toNanos(10)), - // Stores finished successful requests of duration within the interval [10us, 100us) - MICROSx10_MICROSx100( - TimeUnit.MICROSECONDS.toNanos(10), TimeUnit.MICROSECONDS.toNanos(100)), - // Stores finished successful requests of duration within the interval [100us, 1ms) - MICROSx100_MILLIx1( - TimeUnit.MICROSECONDS.toNanos(100), TimeUnit.MILLISECONDS.toNanos(1)), - // Stores finished successful requests of duration within the interval [1ms, 10ms) - MILLIx1_MILLIx10( - TimeUnit.MILLISECONDS.toNanos(1), TimeUnit.MILLISECONDS.toNanos(10)), - // Stores finished successful requests of duration within the interval [10ms, 100ms) - MILLIx10_MILLIx100( - TimeUnit.MILLISECONDS.toNanos(10), TimeUnit.MILLISECONDS.toNanos(100)), - // Stores finished successful requests of duration within the interval [100ms, 1sec) - MILLIx100_SECONDx1( - TimeUnit.MILLISECONDS.toNanos(100), TimeUnit.SECONDS.toNanos(1)), - // Stores finished successful requests of duration within the interval [1sec, 10sec) - SECONDx1_SECONDx10( - TimeUnit.SECONDS.toNanos(1), TimeUnit.SECONDS.toNanos(10)), - // Stores finished successful requests of duration within the interval [10sec, 100sec) - SECONDx10_SECONDx100( - TimeUnit.SECONDS.toNanos(10), TimeUnit.SECONDS.toNanos(100)), - // Stores finished successful requests of duration >= 100sec - SECONDx100_MAX(TimeUnit.SECONDS.toNanos(100), Long.MAX_VALUE); - - /** - * Constructs a {@code LatencyBucketBoundaries} with the given boundaries and label. - * - * @param latencyLowerNs the latency lower bound of the bucket. - * @param latencyUpperNs the latency upper bound of the bucket. - */ - LatencyBucketBoundaries( - long latencyLowerNs, - long latencyUpperNs) { - this.latencyLowerNs = latencyLowerNs; - this.latencyUpperNs = latencyUpperNs; - } - - /** - * Returns the latency lower bound of the bucket. - * - * @return the latency lower bound of the bucket. - */ - public long getLatencyLowerNs() { - return latencyLowerNs; - } - - /** - * Returns the latency upper bound of the bucket. - * - * @return the latency upper bound of the bucket. - */ - public long getLatencyUpperNs() { - return latencyUpperNs; - } - - private final long latencyLowerNs; - private final long latencyUpperNs; - } - - /** The summary of all in-process debugging information. */ - @AutoValue - @Immutable - public abstract static class Summary { - - Summary() {} - - /** - * Returns a new instance of {@code Summary}. - * - * @param perSpanNameSummary a map with summary for each different span name. - * @return a new instance of {@code Summary}. - * @throws NullPointerException if {@code perSpanNameSummary} is {@code null}. - */ - public static Summary create(Map perSpanNameSummary) { - return new AutoValue_TraceExporter_InProcessDebuggingHandler_Summary( - Collections.unmodifiableMap( - new HashMap( - checkNotNull(perSpanNameSummary, "perSpanNameSummary")))); - } - - /** - * Returns a map with summary of available data for each different span name. - * - * @return a map with all the span names and the summary. - */ - public abstract Map getPerSpanNameSummary(); - - /** Summary of all available data for a span name. */ - @AutoValue - @Immutable - public abstract static class PerSpanNameSummary { - - PerSpanNameSummary() {} - - /** - * Returns a new instance of {@code PerSpanNameSummary}. - * - * @param numActiveSpans the number of sampled spans. - * @param latencyBucketsSummaries the summary for the latency buckets. - * @param errorBucketsSummaries the summary for the error buckets. - * @return a new instance of {@code PerSpanNameSummary}. - * @throws NullPointerException if {@code latencyBucketSummaries} or {@code - * errorBucketSummaries} are {@code null}. - * @throws IllegalArgumentException if {@code numActiveSpans} is negative. - */ - public static PerSpanNameSummary create( - int numActiveSpans, - Map latencyBucketsSummaries, - Map errorBucketsSummaries) { - checkArgument(numActiveSpans >= 0, "Negative numActiveSpans."); - return new AutoValue_TraceExporter_InProcessDebuggingHandler_Summary_PerSpanNameSummary( - numActiveSpans, - Collections.unmodifiableMap( - new HashMap( - checkNotNull(latencyBucketsSummaries, "latencyBucketsSummaries"))), - Collections.unmodifiableMap( - new HashMap( - checkNotNull(errorBucketsSummaries, "errorBucketsSummaries")))); - } - - /** - * Returns the number of active spans. - * - * @return the number of active spans. - */ - public abstract int getNumActiveSpans(); - - /** - * Returns the number of samples for each latency based sampled bucket. - * - * @return the number of samples for each latency based sampled bucket. - */ - public abstract Map getLatencyBucketsSummaries(); - - /** - * Returns the number of samples for each error based sampled bucket. - * - * @return the number of samples for each error based sampled bucket. - */ - public abstract Map getErrorBucketsSummaries(); - } - } - - /** - * Filter for active spans. Used to filter results returned by the {@link - * #getActiveSpans(ActiveSpansFilter)} request. - */ - @AutoValue - @Immutable - public abstract static class ActiveSpansFilter { - - ActiveSpansFilter() {} - - /** - * Returns a new instance of {@code ActiveSpansFilter}. - * - *

              Filters all the spans based on {@code spanName} and returns a maximum of {@code - * maxSpansToReturn}. - * - * @param spanName the name of the span. - * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. - * @return a new instance of {@code ActiveSpansFilter}. - * @throws NullPointerException if {@code spanName} is {@code null}. - * @throws IllegalArgumentException if {@code maxSpansToReturn} is negative. - */ - public static ActiveSpansFilter create(String spanName, int maxSpansToReturn) { - checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); - return new AutoValue_TraceExporter_InProcessDebuggingHandler_ActiveSpansFilter( - spanName, maxSpansToReturn); - } - - /** - * Returns the span name. - * - * @return the span name. - */ - public abstract String getSpanName(); - - /** - * Returns the maximum number of spans to be returned. {@code 0} means all. - * - * @return the maximum number of spans to be returned. - */ - public abstract int getMaxSpansToReturn(); - } - - /** - * Filter for latency based sampled spans. Used to filter results returned by the {@link - * #getLatencyBasedSampledSpans(LatencyBasedSampledSpansFilter)} request. - */ - @AutoValue - @Immutable - public abstract static class LatencyBasedSampledSpansFilter { - - LatencyBasedSampledSpansFilter() {} - - /** - * Returns a new instance of {@code LatencyBasedSampledSpansFilter}. - * - *

              Filters all the spans based on {@code spanName} and latency in the interval - * [latencyLowerNs, latencyUpperNs) and returns a maximum of {@code maxSpansToReturn}. - * - * @param spanName the name of the span. - * @param latencyLowerNs the latency lower bound. - * @param latencyUpperNs the latency upper bound. - * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. - * @return a new instance of {@code LatencyBasedSampledSpansFilter}. - * @throws NullPointerException if {@code spanName} is {@code null}. - * @throws IllegalArgumentException if {@code maxSpansToReturn} or {@code latencyLowerNs} or - * {@code latencyUpperNs} are negative. - */ - public static LatencyBasedSampledSpansFilter create( - String spanName, long latencyLowerNs, long latencyUpperNs, int maxSpansToReturn) { - checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); - checkArgument(latencyLowerNs >= 0, "Negative latencyLowerNs"); - checkArgument(latencyUpperNs >= 0, "Negative latencyUpperNs"); - return new AutoValue_TraceExporter_InProcessDebuggingHandler_LatencyBasedSampledSpansFilter( - spanName, latencyLowerNs, latencyUpperNs, maxSpansToReturn); - } - - /** - * Returns the span name used by this filter. - * - * @return the span name used by this filter. - */ - public abstract String getSpanName(); - - /** - * Returns the latency lower bound of this bucket (inclusive). - * - * @return the latency lower bound of this bucket. - */ - public abstract long getLatencyLowerNs(); - - /** - * Returns the latency upper bound of this bucket (exclusive). - * - * @return the latency upper bound of this bucket. - */ - public abstract long getLatencyUpperNs(); - - /** - * Returns the maximum number of spans to be returned. {@code 0} means all. - * - * @return the maximum number of spans to be returned. - */ - public abstract int getMaxSpansToReturn(); - } - - /** Filter for error based sampled spans. */ - @AutoValue - @Immutable - public abstract static class ErrorBasedSampledSpansFilter { - - ErrorBasedSampledSpansFilter() {} - - /** - * Returns a new instance of {@code ErrorBasedSampledSpansFilter}. - * - *

              Filters all the spans based on {@code spanName} and {@code canonicalCode} and returns a - * maximum of {@code maxSpansToReturn}. - * - * @param spanName the name of the span. - * @param canonicalCode the error code of the span. - * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. - * @return a new instance of {@code ErrorBasedSampledSpansFilter}. - * @throws NullPointerException if {@code spanName} or {@code canonicalCode} are {@code null}. - * @throws IllegalArgumentException if {@code canonicalCode} is {@link CanonicalCode#OK} or - * {@code maxSpansToReturn} is negative. - */ - public static ErrorBasedSampledSpansFilter create( - String spanName, CanonicalCode canonicalCode, int maxSpansToReturn) { - checkArgument(canonicalCode != CanonicalCode.OK, "Invalid canonical code."); - checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); - return new AutoValue_TraceExporter_InProcessDebuggingHandler_ErrorBasedSampledSpansFilter( - spanName, canonicalCode, maxSpansToReturn); - } - - /** - * Returns the span name used by this filter. - * - * @return the span name used by this filter. - */ - public abstract String getSpanName(); - - /** - * Returns the canonical code used by this filter. Always different than {@link - * CanonicalCode#OK}. - * - * @return the canonical code used by this filter. - */ - public abstract CanonicalCode getCanonicalCode(); - - /** - * Returns the maximum number of spans to be returned. Used to enforce the number of returned - * {@code SpanData}. {@code 0} means all. - * - * @return the maximum number of spans to be returned. - */ - public abstract int getMaxSpansToReturn(); - } - } - - /** - * An abstract class that allows different tracing services to export recorded data for sampled - * spans in their own format. - * - *

              To export data this MUST be register to to the TraceExporter using {@link - * #registerServiceHandler(String, ServiceHandler)}. - */ - public abstract static class ServiceHandler { - - /** - * Exports a list of sampled (see {@link TraceOptions#isSampled()}) {@link Span}s using the - * immutable representation {@link SpanData}. - * - *

              This may be called from a different thread than the one that called {@link Span#end()}. - * - *

              Implementation SHOULD not block the calling thread. It should execute the export on a - * different thread if possible. - * - * @param spanDataList a list of {@code SpanData} objects to be exported. - */ - public abstract void export(Collection spanDataList); - } - - /** - * Implementation of the {@link ServiceHandler} which logs all the exported {@link SpanData}. - * - *

              Example of usage: - * - *

              {@code
              -   * public static void main(String[] args) {
              -   *   Tracing.getTraceExporter().registerServiceHandler(
              -   *       "io.opencensus.LoggingServiceHandler", LoggingServiceHandler.getInstance());
              -   *   // ...
              -   * }
              -   * }
              - */ - @ThreadSafe - public static final class LoggingServiceHandler extends ServiceHandler { - - private static final Logger logger = Logger.getLogger(LoggingServiceHandler.class.getName()); - private static final String SERVICE_NAME = "io.opencensus.trace.LoggingServiceHandler"; - private static final LoggingServiceHandler INSTANCE = new LoggingServiceHandler(); - - private LoggingServiceHandler() {} - - /** - * Registers the {@code LoggingServiceHandler} to the {@code TraceExporter}. - * - * @param traceExporter the instance of the {@code TraceExporter} where this service is - * registered. - */ - public static void registerService(TraceExporter traceExporter) { - traceExporter.registerServiceHandler(SERVICE_NAME, INSTANCE); - } - - /** - * Unregisters the {@code LoggingServiceHandler} from the {@code TraceExporter}. - * - * @param traceExporter the instance of the {@code TraceExporter} from where this service is - * unregistered. - */ - public static void unregisterService(TraceExporter traceExporter) { - traceExporter.unregisterServiceHandler(SERVICE_NAME); - } - - @Override - public void export(Collection spanDataList) { - for (SpanData spanData : spanDataList) { - logger.log(Level.INFO, spanData.toString()); - } - } - } - - private static final class NoopTraceExporter extends TraceExporter { - - @Override - public void registerServiceHandler(String name, @Nullable ServiceHandler serviceHandler) {} - - @Override - public void unregisterServiceHandler(String name) {} - - @Nullable - @Override - public InProcessDebuggingHandler getInProcessDebuggingHandler() { - return null; - } - } -} diff --git a/api/src/main/java/io/opencensus/trace/Tracing.java b/api/src/main/java/io/opencensus/trace/Tracing.java index 771b8553c7..daf5b3c994 100644 --- a/api/src/main/java/io/opencensus/trace/Tracing.java +++ b/api/src/main/java/io/opencensus/trace/Tracing.java @@ -17,6 +17,7 @@ import io.opencensus.common.Clock; import io.opencensus.internal.Provider; import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.export.ExportComponent; import java.util.logging.Level; import java.util.logging.Logger; @@ -54,11 +55,11 @@ public static Clock getClock() { } /** - * Returns the global {@link TraceExporter}. + * Returns the global {@link ExportComponent}. * - * @return the global {@code TraceExporter}. + * @return the global {@code ExportComponent}. */ - public static TraceExporter getTraceExporter() { + public static ExportComponent getTraceExporter() { return traceComponent.getTraceExporter(); } diff --git a/api/src/main/java/io/opencensus/trace/export/ExportComponent.java b/api/src/main/java/io/opencensus/trace/export/ExportComponent.java new file mode 100644 index 0000000000..5407c46b02 --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/export/ExportComponent.java @@ -0,0 +1,69 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.export; + +import io.opencensus.trace.TraceOptions; +import javax.annotation.Nullable; + +/** + * Class that holds the implementation instances for {@link SpanExporter} and {@link + * InProcessDebuggingHandler}. + * + *

              Unless otherwise noted all methods (on component) results are cacheable. + */ +public abstract class ExportComponent { + + private static final NoopExportComponent NOOP_EXPORT_COMPONENT = new NoopExportComponent(); + + /** + * Returns the no-op implementation of the {@code ExportComponent}. + * + * @return the no-op implementation of the {@code ExportComponent}. + */ + public static ExportComponent getNoopExportComponent() { + return NOOP_EXPORT_COMPONENT; + } + + /** + * Returns the {@link SpanExporter} which can be used to register handlers to export all the spans + * that are part of a distributed sampled trace (see {@link TraceOptions#isSampled()}). + * + * @return the implementation of the {@code SpanExporter} or no-op if no implementation linked in + * the binary. + */ + public abstract SpanExporter getSpanExporter(); + + /** + * Returns the {@link InProcessDebuggingHandler} that can be used to get useful debugging + * information such as (active spans, latency based sampled spans, error based sampled spans). + * + * @return the {@code InProcessDebuggingHandler} or {@code null} if in-process debugging is not + * supported. + */ + @Nullable + public abstract InProcessDebuggingHandler getInProcessDebuggingHandler(); + + private static final class NoopExportComponent extends ExportComponent { + @Override + public SpanExporter getSpanExporter() { + return SpanExporter.getNoopSpanExporter(); + } + + @Nullable + @Override + public InProcessDebuggingHandler getInProcessDebuggingHandler() { + return null; + } + } +} diff --git a/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java b/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java new file mode 100644 index 0000000000..56318bd9d4 --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java @@ -0,0 +1,417 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.export; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.auto.value.AutoValue; +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanData; +import io.opencensus.trace.Status; +import io.opencensus.trace.Status.CanonicalCode; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.annotation.concurrent.Immutable; +import javax.annotation.concurrent.ThreadSafe; + +/** + * This class allows users to access in-process debugging information such as (getting access to all + * active spans, support latency based sampled spans and error based sampled spans). + * + *

              The active spans tracking is available for all the spans with the option {@link + * Span.Options#RECORD_EVENTS}. This functionality allows users to debug stuck operations or long + * living operations. + * + *

              For all completed spans with the option {@link Span.Options#RECORD_EVENTS} the library can + * store samples based on latency for succeeded operations or based on error code for failed + * operations. To activate this, users MUST manually configure all the span names for which samples + * will be collected (see {@link #registerSpanNamesForCollection(Collection)}). + */ +@ThreadSafe +public abstract class InProcessDebuggingHandler { + + InProcessDebuggingHandler() {} + + /** + * Returns the summary of all available in-process debugging data such as number of active spans, + * number of sampled spans in the latency based samples or error based samples. + * + *

              Latency based sampled summary buckets and error based sampled summary buckets are available + * only for span names registered using {@link #registerSpanNamesForCollection(Collection)}. + * + * @return the summary of all available in-process debugging data. + */ + public abstract Summary getSummary(); + + /** + * Returns a list of active spans that match the {@code filter}. + * + *

              Active spans are available for all the span names. + * + * @param filter used to filter the returned spans. + * @return a list of active spans that match the {@code filter}. + */ + public abstract Collection getActiveSpans(ActiveSpansFilter filter); + + /** + * Returns a list of succeeded spans (spans with {@link Status} equal to {@link Status#OK}) that + * match the {@code filter}. + * + *

              Latency based sampled spans are available only for span names registered using {@link + * #registerSpanNamesForCollection(Collection)}. + * + * @param filter used to filter the returned sampled spans. + * @return a list of succeeded spans that match the {@code filter}. + */ + public abstract Collection getLatencyBasedSampledSpans( + LatencyBasedSampledSpansFilter filter); + + /** + * Returns a list of failed spans (spans with {@link Status} other than {@link Status#OK}) that + * match the {@code filter}. + * + *

              Error based sampled spans are available only for span names registered using {@link + * #registerSpanNamesForCollection(Collection)}. + * + * @param filter used to filter the returned sampled spans. + * @return a list of failed spans that match the {@code filter}. + */ + public abstract Collection getErrorBasedSampledSpans( + ErrorBasedSampledSpansFilter filter); + + /** + * Appends a list of span names for which the library will collect latency based sampled spans and + * error based sampled spans. + * + *

              If called multiple times the library keeps the list of unique span names from all the calls. + * + * @param spanNames list of span names for which the library will collect samples. + */ + public abstract void registerSpanNamesForCollection(Collection spanNames); + + /** + * Removes a list of span names for which the library will collect latency based sampled spans and + * error based sampled spans. + * + *

              The library keeps the list of unique registered span names for which samples will be called. + * This method allows users to remove span names from that list. + * + * @param spanNames list of span names for which the library will no longer collect samples. + */ + public abstract void unregisterSpanNamesForCollection(Collection spanNames); + + /** + * The latency buckets boundaries. Samples based on latency for successful spans (the status of + * the span has a canonical code equal to {@link CanonicalCode#OK}) are collected in one of these + * latency buckets. + */ + public enum LatencyBucketBoundaries { + // Stores finished successful requests of duration within the interval [0, 10us) + ZERO_MICROSx10(0, TimeUnit.MICROSECONDS.toNanos(10)), + // Stores finished successful requests of duration within the interval [10us, 100us) + MICROSx10_MICROSx100(TimeUnit.MICROSECONDS.toNanos(10), TimeUnit.MICROSECONDS.toNanos(100)), + // Stores finished successful requests of duration within the interval [100us, 1ms) + MICROSx100_MILLIx1(TimeUnit.MICROSECONDS.toNanos(100), TimeUnit.MILLISECONDS.toNanos(1)), + // Stores finished successful requests of duration within the interval [1ms, 10ms) + MILLIx1_MILLIx10(TimeUnit.MILLISECONDS.toNanos(1), TimeUnit.MILLISECONDS.toNanos(10)), + // Stores finished successful requests of duration within the interval [10ms, 100ms) + MILLIx10_MILLIx100(TimeUnit.MILLISECONDS.toNanos(10), TimeUnit.MILLISECONDS.toNanos(100)), + // Stores finished successful requests of duration within the interval [100ms, 1sec) + MILLIx100_SECONDx1(TimeUnit.MILLISECONDS.toNanos(100), TimeUnit.SECONDS.toNanos(1)), + // Stores finished successful requests of duration within the interval [1sec, 10sec) + SECONDx1_SECONDx10(TimeUnit.SECONDS.toNanos(1), TimeUnit.SECONDS.toNanos(10)), + // Stores finished successful requests of duration within the interval [10sec, 100sec) + SECONDx10_SECONDx100(TimeUnit.SECONDS.toNanos(10), TimeUnit.SECONDS.toNanos(100)), + // Stores finished successful requests of duration >= 100sec + SECONDx100_MAX(TimeUnit.SECONDS.toNanos(100), Long.MAX_VALUE); + + /** + * Constructs a {@code LatencyBucketBoundaries} with the given boundaries and label. + * + * @param latencyLowerNs the latency lower bound of the bucket. + * @param latencyUpperNs the latency upper bound of the bucket. + */ + LatencyBucketBoundaries(long latencyLowerNs, long latencyUpperNs) { + this.latencyLowerNs = latencyLowerNs; + this.latencyUpperNs = latencyUpperNs; + } + + /** + * Returns the latency lower bound of the bucket. + * + * @return the latency lower bound of the bucket. + */ + public long getLatencyLowerNs() { + return latencyLowerNs; + } + + /** + * Returns the latency upper bound of the bucket. + * + * @return the latency upper bound of the bucket. + */ + public long getLatencyUpperNs() { + return latencyUpperNs; + } + + private final long latencyLowerNs; + private final long latencyUpperNs; + } + + /** The summary of all in-process debugging information. */ + @AutoValue + @Immutable + public abstract static class Summary { + + Summary() {} + + /** + * Returns a new instance of {@code Summary}. + * + * @param perSpanNameSummary a map with summary for each different span name. + * @return a new instance of {@code Summary}. + * @throws NullPointerException if {@code perSpanNameSummary} is {@code null}. + */ + public static Summary create(Map perSpanNameSummary) { + return new AutoValue_InProcessDebuggingHandler_Summary( + Collections.unmodifiableMap( + new HashMap( + checkNotNull(perSpanNameSummary, "perSpanNameSummary")))); + } + + /** + * Returns a map with summary of available data for each different span name. + * + * @return a map with all the span names and the summary. + */ + public abstract Map getPerSpanNameSummary(); + + /** Summary of all available data for a span name. */ + @AutoValue + @Immutable + public abstract static class PerSpanNameSummary { + + PerSpanNameSummary() {} + + /** + * Returns a new instance of {@code PerSpanNameSummary}. + * + * @param numActiveSpans the number of sampled spans. + * @param latencyBucketsSummaries the summary for the latency buckets. + * @param errorBucketsSummaries the summary for the error buckets. + * @return a new instance of {@code PerSpanNameSummary}. + * @throws NullPointerException if {@code latencyBucketSummaries} or {@code + * errorBucketSummaries} are {@code null}. + * @throws IllegalArgumentException if {@code numActiveSpans} is negative. + */ + public static Summary.PerSpanNameSummary create( + int numActiveSpans, + Map latencyBucketsSummaries, + Map errorBucketsSummaries) { + checkArgument(numActiveSpans >= 0, "Negative numActiveSpans."); + return new AutoValue_InProcessDebuggingHandler_Summary_PerSpanNameSummary( + numActiveSpans, + Collections.unmodifiableMap( + new HashMap( + checkNotNull(latencyBucketsSummaries, "latencyBucketsSummaries"))), + Collections.unmodifiableMap( + new HashMap( + checkNotNull(errorBucketsSummaries, "errorBucketsSummaries")))); + } + + /** + * Returns the number of active spans. + * + * @return the number of active spans. + */ + public abstract int getNumActiveSpans(); + + /** + * Returns the number of samples for each latency based sampled bucket. + * + * @return the number of samples for each latency based sampled bucket. + */ + public abstract Map getLatencyBucketsSummaries(); + + /** + * Returns the number of samples for each error based sampled bucket. + * + * @return the number of samples for each error based sampled bucket. + */ + public abstract Map getErrorBucketsSummaries(); + } + } + + /** + * Filter for active spans. Used to filter results returned by the {@link + * #getActiveSpans(ActiveSpansFilter)} request. + */ + @AutoValue + @Immutable + public abstract static class ActiveSpansFilter { + + ActiveSpansFilter() {} + + /** + * Returns a new instance of {@code ActiveSpansFilter}. + * + *

              Filters all the spans based on {@code spanName} and returns a maximum of {@code + * maxSpansToReturn}. + * + * @param spanName the name of the span. + * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. + * @return a new instance of {@code ActiveSpansFilter}. + * @throws NullPointerException if {@code spanName} is {@code null}. + * @throws IllegalArgumentException if {@code maxSpansToReturn} is negative. + */ + public static ActiveSpansFilter create(String spanName, int maxSpansToReturn) { + checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); + return new AutoValue_InProcessDebuggingHandler_ActiveSpansFilter(spanName, maxSpansToReturn); + } + + /** + * Returns the span name. + * + * @return the span name. + */ + public abstract String getSpanName(); + + /** + * Returns the maximum number of spans to be returned. {@code 0} means all. + * + * @return the maximum number of spans to be returned. + */ + public abstract int getMaxSpansToReturn(); + } + + /** + * Filter for latency based sampled spans. Used to filter results returned by the {@link + * #getLatencyBasedSampledSpans(LatencyBasedSampledSpansFilter)} request. + */ + @AutoValue + @Immutable + public abstract static class LatencyBasedSampledSpansFilter { + + LatencyBasedSampledSpansFilter() {} + + /** + * Returns a new instance of {@code LatencyBasedSampledSpansFilter}. + * + *

              Filters all the spans based on {@code spanName} and latency in the interval + * [latencyLowerNs, latencyUpperNs) and returns a maximum of {@code maxSpansToReturn}. + * + * @param spanName the name of the span. + * @param latencyLowerNs the latency lower bound. + * @param latencyUpperNs the latency upper bound. + * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. + * @return a new instance of {@code LatencyBasedSampledSpansFilter}. + * @throws NullPointerException if {@code spanName} is {@code null}. + * @throws IllegalArgumentException if {@code maxSpansToReturn} or {@code latencyLowerNs} or + * {@code latencyUpperNs} are negative. + */ + public static LatencyBasedSampledSpansFilter create( + String spanName, long latencyLowerNs, long latencyUpperNs, int maxSpansToReturn) { + checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); + checkArgument(latencyLowerNs >= 0, "Negative latencyLowerNs"); + checkArgument(latencyUpperNs >= 0, "Negative latencyUpperNs"); + return new AutoValue_InProcessDebuggingHandler_LatencyBasedSampledSpansFilter( + spanName, latencyLowerNs, latencyUpperNs, maxSpansToReturn); + } + + /** + * Returns the span name used by this filter. + * + * @return the span name used by this filter. + */ + public abstract String getSpanName(); + + /** + * Returns the latency lower bound of this bucket (inclusive). + * + * @return the latency lower bound of this bucket. + */ + public abstract long getLatencyLowerNs(); + + /** + * Returns the latency upper bound of this bucket (exclusive). + * + * @return the latency upper bound of this bucket. + */ + public abstract long getLatencyUpperNs(); + + /** + * Returns the maximum number of spans to be returned. {@code 0} means all. + * + * @return the maximum number of spans to be returned. + */ + public abstract int getMaxSpansToReturn(); + } + + /** Filter for error based sampled spans. */ + @AutoValue + @Immutable + public abstract static class ErrorBasedSampledSpansFilter { + + ErrorBasedSampledSpansFilter() {} + + /** + * Returns a new instance of {@code ErrorBasedSampledSpansFilter}. + * + *

              Filters all the spans based on {@code spanName} and {@code canonicalCode} and returns a + * maximum of {@code maxSpansToReturn}. + * + * @param spanName the name of the span. + * @param canonicalCode the error code of the span. + * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. + * @return a new instance of {@code ErrorBasedSampledSpansFilter}. + * @throws NullPointerException if {@code spanName} or {@code canonicalCode} are {@code null}. + * @throws IllegalArgumentException if {@code canonicalCode} is {@link CanonicalCode#OK} or + * {@code maxSpansToReturn} is negative. + */ + public static ErrorBasedSampledSpansFilter create( + String spanName, CanonicalCode canonicalCode, int maxSpansToReturn) { + checkArgument(canonicalCode != CanonicalCode.OK, "Invalid canonical code."); + checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); + return new AutoValue_InProcessDebuggingHandler_ErrorBasedSampledSpansFilter( + spanName, canonicalCode, maxSpansToReturn); + } + + /** + * Returns the span name used by this filter. + * + * @return the span name used by this filter. + */ + public abstract String getSpanName(); + + /** + * Returns the canonical code used by this filter. Always different than {@link + * CanonicalCode#OK}. + * + * @return the canonical code used by this filter. + */ + public abstract CanonicalCode getCanonicalCode(); + + /** + * Returns the maximum number of spans to be returned. Used to enforce the number of returned + * {@code SpanData}. {@code 0} means all. + * + * @return the maximum number of spans to be returned. + */ + public abstract int getMaxSpansToReturn(); + } +} diff --git a/api/src/main/java/io/opencensus/trace/export/SpanExporter.java b/api/src/main/java/io/opencensus/trace/export/SpanExporter.java new file mode 100644 index 0000000000..5e10d8be9a --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/export/SpanExporter.java @@ -0,0 +1,127 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.export; + +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanData; +import io.opencensus.trace.TraceOptions; +import java.util.Collection; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.concurrent.ThreadSafe; + +/** + * A service that is used by the library to export {@code SpanData} for all the spans that are part + * of a distributed sampled trace (see {@link TraceOptions#isSampled()}). + */ +@ThreadSafe +public abstract class SpanExporter { + private static final SpanExporter NOOP_SPAN_EXPORTER = new NoopSpanExporter(); + + /** + * Returns the no-op implementation of the {@code ExportComponent}. + * + * @return the no-op implementation of the {@code ExportComponent}. + */ + public static SpanExporter getNoopSpanExporter() { + return NOOP_SPAN_EXPORTER; + } + + /** + * Registers a new service handler that is used by the library to export {@code SpanData} for + * sampled spans (see {@link TraceOptions#isSampled()}). + * + * @param name the name of the service handler. Must be unique for each service. + * @param handler the service handler that is called for each ended sampled span. + */ + public abstract void registerHandler(String name, Handler handler); + + /** + * Unregisters the service handler with the provided name. + * + * @param name the name of the service handler that will be unregistered. + */ + public abstract void unregisterHandler(String name); + + /** + * An abstract class that allows different tracing services to export recorded data for sampled + * spans in their own format. + * + *

              To export data this MUST be register to to the ExportComponent using {@link + * #registerHandler(String, Handler)}. + */ + public abstract static class Handler { + + /** + * Exports a list of sampled (see {@link TraceOptions#isSampled()}) {@link Span}s using the + * immutable representation {@link SpanData}. + * + *

              This may be called from a different thread than the one that called {@link Span#end()}. + * + *

              Implementation SHOULD not block the calling thread. It should execute the export on a + * different thread if possible. + * + * @param spanDataList a list of {@code SpanData} objects to be exported. + */ + public abstract void export(Collection spanDataList); + } + + private static final class NoopSpanExporter extends SpanExporter { + + @Override + public void registerHandler(String name, Handler handler) {} + + @Override + public void unregisterHandler(String name) {} + } + + /** Implementation of the {@link Handler} which logs all the exported {@link SpanData}. */ + @ThreadSafe + public static final class LoggingHandler extends Handler { + + private static final Logger logger = Logger.getLogger(LoggingHandler.class.getName()); + private static final String REGISTER_NAME = + "io.opencensus.trace.export.SpanExporter$LoggingHandler"; + private static final LoggingHandler INSTANCE = new LoggingHandler(); + + private LoggingHandler() {} + + /** + * Registers the {@code LoggingHandler} to the {@code ExportComponent}. + * + * @param spanExporter the instance of the {@code SpanExporter} where this service is + * registered. + */ + public static void register(SpanExporter spanExporter) { + spanExporter.registerHandler(REGISTER_NAME, INSTANCE); + } + + /** + * Unregisters the {@code LoggingHandler} from the {@code ExportComponent}. + * + * @param spanExporter the instance of the {@code SpanExporter} from where this service is + * unregistered. + */ + public static void unregister(SpanExporter spanExporter) { + spanExporter.unregisterHandler(REGISTER_NAME); + } + + @Override + public void export(Collection spanDataList) { + for (SpanData spanData : spanDataList) { + logger.log(Level.INFO, spanData.toString()); + } + } + } +} diff --git a/api/src/test/java/io/opencensus/trace/TraceComponentTest.java b/api/src/test/java/io/opencensus/trace/TraceComponentTest.java index cd42a98a59..4a0c35947f 100644 --- a/api/src/test/java/io/opencensus/trace/TraceComponentTest.java +++ b/api/src/test/java/io/opencensus/trace/TraceComponentTest.java @@ -17,6 +17,7 @@ import io.opencensus.internal.ZeroTimeClock; import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.export.ExportComponent; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -43,7 +44,7 @@ public void defaultClock() { @Test public void defaultTraceExporter() { assertThat(TraceComponent.getNoopTraceComponent().getTraceExporter()) - .isSameAs(TraceExporter.getNoopTraceExporter()); + .isSameAs(ExportComponent.getNoopExportComponent()); } @Test diff --git a/api/src/test/java/io/opencensus/trace/TracingTest.java b/api/src/test/java/io/opencensus/trace/TracingTest.java index c23e7c6f7f..0076cc77ae 100644 --- a/api/src/test/java/io/opencensus/trace/TracingTest.java +++ b/api/src/test/java/io/opencensus/trace/TracingTest.java @@ -16,6 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.export.ExportComponent; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -69,7 +70,7 @@ public void defaultBinaryPropagationHandler() { @Test public void defaultTraceExporter() { - assertThat(Tracing.getTraceExporter()).isSameAs(TraceExporter.getNoopTraceExporter()); + assertThat(Tracing.getTraceExporter()).isSameAs(ExportComponent.getNoopExportComponent()); } @Test diff --git a/api/src/test/java/io/opencensus/trace/TraceExporterTest.java b/api/src/test/java/io/opencensus/trace/export/SpanExporterTest.java similarity index 64% rename from api/src/test/java/io/opencensus/trace/TraceExporterTest.java rename to api/src/test/java/io/opencensus/trace/export/SpanExporterTest.java index 3837a1ada6..464806881a 100644 --- a/api/src/test/java/io/opencensus/trace/TraceExporterTest.java +++ b/api/src/test/java/io/opencensus/trace/export/SpanExporterTest.java @@ -11,13 +11,13 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.export; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; -import io.opencensus.trace.TraceExporter.LoggingServiceHandler; +import io.opencensus.trace.export.SpanExporter.LoggingHandler; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -25,10 +25,10 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -/** Unit tests for {@link TraceExporter}. */ +/** Unit tests for {@link ExportComponent}. */ @RunWith(JUnit4.class) -public class TraceExporterTest { - @Mock private TraceExporter traceExporter; +public class SpanExporterTest { + @Mock private SpanExporter spanExporter; @Before public void setUp() { @@ -37,11 +37,13 @@ public void setUp() { @Test public void registerUnregisterLoggingService() { - LoggingServiceHandler.registerService(traceExporter); - verify(traceExporter) - .registerServiceHandler( - eq("io.opencensus.trace.LoggingServiceHandler"), any(LoggingServiceHandler.class)); - LoggingServiceHandler.unregisterService(traceExporter); - verify(traceExporter).unregisterServiceHandler(eq("io.opencensus.trace.LoggingServiceHandler")); + LoggingHandler.register(spanExporter); + verify(spanExporter) + .registerHandler( + eq("io.opencensus.trace.export.SpanExporter$LoggingHandler"), + any(LoggingHandler.class)); + LoggingHandler.unregister(spanExporter); + verify(spanExporter) + .unregisterHandler(eq("io.opencensus.trace.export.SpanExporter$LoggingHandler")); } } diff --git a/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java b/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java index 7f51eb3ec2..943f32112c 100644 --- a/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java @@ -23,33 +23,32 @@ *

              Binary format: * *

                - *
              • Binary value: <version_id><version_format> - *
              • version_id: 1-byte representing the version id. - *
              • For version_id = 0: - *
                  - *
                • version_format: <field><field> - *
                • field_format: <field_id><field_format> - *
                • Fields: - *
                    - *
                  • TraceId: (field_id = 0, len = 16, default = "0000000000000000") - 16-byte - * array representing the trace_id. - *
                  • SpanId: (field_id = 1, len = 8, default = "00000000") - 8-byte array - * representing the span_id. - *
                  • TraceOptions: (field_id = 2, len = 1, default = "0") - 1-byte array - * representing the trace_options. - *
                  - *
                • Fields MUST be encoded using the field id order (smaller to higher). - *
                • Valid value example: - *
                    - *
                  • {0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1, 97, 98, 99, - * 100, 101, 102, 103, 104, 2, 1} - *
                  • version_id = 0; - *
                  • trace_id = {64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79} - *
                  • span_id = {97, 98, 99, 100, 101, 102, 103, 104}; - *
                  • trace_options = {1}; - *
                  - *
                - * + *
              • Binary value: <version_id><version_format> + *
              • version_id: 1-byte representing the version id. + *
              • For version_id = 0: + *
                  + *
                • version_format: <field><field> + *
                • field_format: <field_id><field_format> + *
                • Fields: + *
                    + *
                  • TraceId: (field_id = 0, len = 16, default = "0000000000000000") - + * 16-byte array representing the trace_id. + *
                  • SpanId: (field_id = 1, len = 8, default = "00000000") - 8-byte array + * representing the span_id. + *
                  • TraceOptions: (field_id = 2, len = 1, default = "0") - 1-byte array + * representing the trace_options. + *
                  + *
                • Fields MUST be encoded using the field id order (smaller to higher). + *
                • Valid value example: + *
                    + *
                  • {0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1, 97, + * 98, 99, 100, 101, 102, 103, 104, 2, 1} + *
                  • version_id = 0; + *
                  • trace_id = {64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79} + *
                  • span_id = {97, 98, 99, 100, 101, 102, 103, 104}; + *
                  • trace_options = {1}; + *
                  + *
                *
              */ final class BinaryPropagationHandlerImpl extends BinaryPropagationHandler { diff --git a/core_impl/src/main/java/io/opencensus/trace/ExportComponentImpl.java b/core_impl/src/main/java/io/opencensus/trace/ExportComponentImpl.java new file mode 100644 index 0000000000..168acbba5c --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/trace/ExportComponentImpl.java @@ -0,0 +1,50 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace; + +import io.opencensus.common.EventQueue; +import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.export.InProcessDebuggingHandler; +import javax.annotation.Nullable; + +/** + * Implementation of the {@link ExportComponent}, implements also {@link StartEndHandler}. + * + *

              Uses the provided {@link EventQueue} to defer processing/exporting of the {@link SpanData} to + * avoid impacting the critical path. + */ +final class ExportComponentImpl extends ExportComponent { + private static final int EXPORTER_BUFFER_SIZE = 32; + // Enforces that trace export exports data at least once every 2 seconds. + private static final long EXPORTER_SCHEDULE_DELAY_MS = 2000; + + private final SpanExporterImpl spanExporter; + + @Override + public SpanExporterImpl getSpanExporter() { + return spanExporter; + } + + @Nullable + @Override + public InProcessDebuggingHandler getInProcessDebuggingHandler() { + // TODO(bdrutu): Implement this. + return null; + } + + ExportComponentImpl() { + this.spanExporter = SpanExporterImpl.create(EXPORTER_BUFFER_SIZE, EXPORTER_SCHEDULE_DELAY_MS); + } +} diff --git a/core_impl/src/main/java/io/opencensus/trace/TraceExporterImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanExporterImpl.java similarity index 61% rename from core_impl/src/main/java/io/opencensus/trace/TraceExporterImpl.java rename to core_impl/src/main/java/io/opencensus/trace/SpanExporterImpl.java index d42c2c3474..5428c60dd3 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TraceExporterImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanExporterImpl.java @@ -14,8 +14,8 @@ package io.opencensus.trace; import com.google.common.annotations.VisibleForTesting; -import io.opencensus.common.EventQueue; -import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.export.SpanExporter; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; @@ -24,23 +24,16 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; -import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; -/** - * Implementation of the {@link TraceExporter}, implements also {@link StartEndHandler}. - * - *

              Uses the provided {@link EventQueue} to defer processing/exporting of the {@link SpanData} to - * avoid impacting the critical path. - */ -final class TraceExporterImpl extends TraceExporter implements StartEndHandler { - private static final Logger logger = Logger.getLogger(TraceExporter.class.getName()); +/** Implementation of the {@link SpanExporter}. */ +public final class SpanExporterImpl extends SpanExporter { + private static final Logger logger = Logger.getLogger(ExportComponent.class.getName()); - private final ServiceExporterThread serviceExporterThread; - private final EventQueue eventQueue; + private final WorkerThread workerThread; /** - * Constructs a {@code TraceExporterImpl} that exports the {@link SpanData} asynchronously. + * Constructs a {@code SpanExporterImpl} that exports the {@link SpanData} asynchronously. * *

              Starts a separate thread that wakes up every {@code scheduleDelay} and exports any available * spans data. If the number of buffered SpanData objects is greater than {@code bufferSize} then @@ -49,52 +42,35 @@ final class TraceExporterImpl extends TraceExporter implements StartEndHandler { * @param bufferSize the size of the buffered span data. * @param scheduleDelayMillis the maximum delay in milliseconds. */ - static TraceExporterImpl create(int bufferSize, long scheduleDelayMillis, EventQueue eventQueue) { - ServiceExporterThread workerThread = new ServiceExporterThread(bufferSize, scheduleDelayMillis); - workerThread.start(); - return new TraceExporterImpl(workerThread, eventQueue); + static SpanExporterImpl create(int bufferSize, long scheduleDelayMillis) { // TODO(bdrutu): Consider to add a shutdown hook to not avoid dropping data. + WorkerThread workerThread = new WorkerThread(bufferSize, scheduleDelayMillis); + workerThread.start(); + return new SpanExporterImpl(workerThread); } - @Override - public void registerServiceHandler(String name, ServiceHandler serviceHandler) { - serviceExporterThread.registerServiceHandler(name, serviceHandler); - } - - @Override - public void unregisterServiceHandler(String name) { - serviceExporterThread.unregisterServiceHandler(name); + // Adds a Span to the exporting service. + void addSpan(SpanImpl span) { + workerThread.addSpan(span); } - @Nullable @Override - public InProcessDebuggingHandler getInProcessDebuggingHandler() { - // TODO(bdrutu): Implement this. - return null; + public void registerHandler(String name, Handler handler) { + workerThread.registerHandler(name, handler); } @Override - public void onStart(SpanImpl span) { - // Do nothing. When ActiveSpans functionality is implemented this will change to record the - // Span into the ActiveSpans list. + public void unregisterHandler(String name) { + workerThread.unregisterHandler(name); } - @Override - public void onEnd(SpanImpl span) { - // TODO(bdrutu): Change to RECORD_EVENTS option when active/samples is supported. - if (span.getContext().getTraceOptions().isSampled()) { - eventQueue.enqueue(new SpanEndEvent(span, serviceExporterThread)); - } + private SpanExporterImpl(WorkerThread workerThread) { + this.workerThread = workerThread; } @VisibleForTesting Thread getServiceExporterThread() { - return serviceExporterThread; - } - - private TraceExporterImpl(ServiceExporterThread serviceExporterThread, EventQueue eventQueue) { - this.serviceExporterThread = serviceExporterThread; - this.eventQueue = eventQueue; + return workerThread; } // Worker thread that batches multiple span data and calls the registered services to export @@ -106,18 +82,17 @@ private TraceExporterImpl(ServiceExporterThread serviceExporterThread, EventQueu // // The list of batched data is protected by an explicit monitor object which ensures full // concurrency. - private static final class ServiceExporterThread extends Thread { + private static final class WorkerThread extends Thread { private final Object monitor = new Object(); @GuardedBy("monitor") private final List spans; - private final Map serviceHandlers = - new ConcurrentHashMap(); + private final Map serviceHandlers = new ConcurrentHashMap(); private final int bufferSize; private final long scheduleDelayMillis; - // See TraceExporterImpl#addSpan. + // See SpanExporterImpl#addSpan. private void addSpan(SpanImpl span) { synchronized (monitor) { this.spans.add(span); @@ -127,13 +102,13 @@ private void addSpan(SpanImpl span) { } } - // See TraceExporterImpl#registerServiceHandler. - private void registerServiceHandler(String name, ServiceHandler serviceHandler) { + // See SpanExporter#registerHandler. + private void registerHandler(String name, Handler serviceHandler) { serviceHandlers.put(name, serviceHandler); } - // See TraceExporterImpl#unregisterServiceHandler. - private void unregisterServiceHandler(String name) { + // See SpanExporter#unregisterHandler. + private void unregisterHandler(String name) { serviceHandlers.remove(name); } @@ -144,22 +119,22 @@ private void onBatchExport(List spanDataList) { // ConcurrentModificationException, and guarantees to traverse elements as they existed // upon construction of the iterator, and may (but is not guaranteed to) reflect any // modifications subsequent to construction. - for (Map.Entry it : serviceHandlers.entrySet()) { + for (Map.Entry it : serviceHandlers.entrySet()) { // In case of any exception thrown by the service handlers continue to run. try { it.getValue().export(spanDataList); } catch (Throwable e) { - logger.log(Level.WARNING, "Exception thrown by the service exporter " + it.getKey(), e); + logger.log(Level.WARNING, "Exception thrown by the service export " + it.getKey(), e); } } } - private ServiceExporterThread(int bufferSize, long scheduleDelayMillis) { + private WorkerThread(int bufferSize, long scheduleDelayMillis) { spans = new LinkedList(); this.bufferSize = bufferSize; this.scheduleDelayMillis = scheduleDelayMillis; setDaemon(true); - setName("TraceExporter.ServiceExporterThread"); + setName("ExportComponent.ServiceExporterThread"); } // Returns an unmodifiable list of all buffered spans data to ensure that any registered @@ -203,20 +178,4 @@ public void run() { } } } - - // An EventQueue entry that records the end of the span event. - private static final class SpanEndEvent implements EventQueue.Entry { - private final SpanImpl span; - private final ServiceExporterThread serviceExporterThread; - - SpanEndEvent(SpanImpl span, ServiceExporterThread serviceExporterThread) { - this.span = span; - this.serviceExporterThread = serviceExporterThread; - } - - @Override - public void process() { - serviceExporterThread.addSpan(span); - } - } } diff --git a/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java b/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java new file mode 100644 index 0000000000..8360f69838 --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java @@ -0,0 +1,62 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace; + +import io.opencensus.common.EventQueue; +import io.opencensus.trace.SpanImpl.StartEndHandler; + +/** + * Uses the provided {@link EventQueue} to defer processing/exporting of the {@link SpanData} to + * avoid impacting the critical path. + */ +final class StartEndHandlerImpl implements StartEndHandler { + private final EventQueue eventQueue; + private final SpanExporterImpl sampledSpansServiceExporter; + + StartEndHandlerImpl( + SpanExporterImpl sampledSpansServiceExporter, EventQueue eventQueue) { + this.sampledSpansServiceExporter = sampledSpansServiceExporter; + this.eventQueue = eventQueue; + } + + @Override + public void onStart(SpanImpl span) { + // Do nothing. When ActiveSpans functionality is implemented this will change to record the + // Span into the ActiveSpans list. + } + + @Override + public void onEnd(SpanImpl span) { + // TODO(bdrutu): Change to RECORD_EVENTS option when active/samples is supported. + if (span.getContext().getTraceOptions().isSampled()) { + eventQueue.enqueue(new SpanEndEvent(span, sampledSpansServiceExporter)); + } + } + + // An EventQueue entry that records the end of the span event. + private static final class SpanEndEvent implements EventQueue.Entry { + private final SpanImpl span; + private final SpanExporterImpl sampledSpansServiceExporter; + + SpanEndEvent(SpanImpl span, SpanExporterImpl sampledSpansServiceExporter) { + this.span = span; + this.sampledSpansServiceExporter = sampledSpansServiceExporter; + } + + @Override + public void process() { + sampledSpansServiceExporter.addSpan(span); + } + } +} diff --git a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java index c313d1e1fe..88eb193102 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java @@ -15,27 +15,24 @@ import io.opencensus.common.Clock; import io.opencensus.common.EventQueue; +import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.export.ExportComponent; /** Base implementation of the {@link TraceComponent}. */ class TraceComponentImplBase extends TraceComponent { - private static final int TRACE_EXPORTER_BUFFER_SIZE = 32; - // Enforces that trace exporter exports data at least once every 2 seconds. - private static final long TRACE_EXPORTER_SCHEDULE_DELAY_MS = 2000; private final BinaryPropagationHandler binaryPropagationHandler = new BinaryPropagationHandlerImpl(); + private final ExportComponentImpl traceExporter = new ExportComponentImpl(); private final Clock clock; - private final TraceExporter traceExporter; + private final StartEndHandler startEndHandler; private final TraceConfig traceConfig = new TraceConfigImpl(); private final Tracer tracer; TraceComponentImplBase(Clock clock, RandomHandler randomHandler, EventQueue eventQueue) { this.clock = clock; - TraceExporterImpl traceExporterImpl = - TraceExporterImpl.create( - TRACE_EXPORTER_BUFFER_SIZE, TRACE_EXPORTER_SCHEDULE_DELAY_MS, eventQueue); - traceExporter = traceExporterImpl; - tracer = new TracerImpl(randomHandler, traceExporterImpl, clock, traceConfig); + startEndHandler = new StartEndHandlerImpl(traceExporter.getSpanExporter(), eventQueue); + tracer = new TracerImpl(randomHandler, startEndHandler, clock, traceConfig); } @Override @@ -54,7 +51,7 @@ public final Clock getClock() { } @Override - public TraceExporter getTraceExporter() { + public ExportComponent getTraceExporter() { return traceExporter; } diff --git a/core_impl/src/test/java/io/opencensus/trace/TraceExporterImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java similarity index 88% rename from core_impl/src/test/java/io/opencensus/trace/TraceExporterImplTest.java rename to core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java index 4c181e5f0a..46256c9de5 100644 --- a/core_impl/src/test/java/io/opencensus/trace/TraceExporterImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java @@ -20,8 +20,9 @@ import io.opencensus.common.MillisClock; import io.opencensus.common.SimpleEventQueue; import io.opencensus.trace.Span.Options; +import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.config.TraceParams; -import io.opencensus.trace.TraceExporter.ServiceHandler; +import io.opencensus.trace.export.SpanExporter.Handler; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; @@ -36,9 +37,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -/** Unit tests for {@link TraceExporterImpl}. */ +/** Unit tests for {@link ExportComponentImpl}. */ @RunWith(JUnit4.class) -public class TraceExporterImplTest { +public class SpanExporterImplTest { private static final String SPAN_NAME_1 = "MySpanName/1"; private static final String SPAN_NAME_2 = "MySpanName/2"; private final Random random = new Random(1234); @@ -50,16 +51,17 @@ public class TraceExporterImplTest { private final SpanContext notSampledSpanContext = SpanContext.create( TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); - private final TraceExporterImpl traceExporter = - TraceExporterImpl.create(4, 1000, new SimpleEventQueue()); + private final SpanExporterImpl sampledSpansServiceExporter = SpanExporterImpl.create(4, 1000); + private final StartEndHandler startEndHandler = + new StartEndHandlerImpl(sampledSpansServiceExporter, new SimpleEventQueue()); private EnumSet recordSpanOptions = EnumSet.of(Options.RECORD_EVENTS); private final FakeServiceHandler serviceHandler = new FakeServiceHandler(); - @Mock private ServiceHandler mockServiceHandler; + @Mock private Handler mockServiceHandler; @Before public void setUp() { MockitoAnnotations.initMocks(this); - traceExporter.registerServiceHandler("test.service", serviceHandler); + sampledSpansServiceExporter.registerHandler("test.service", serviceHandler); } private final SpanImpl createSampledEndedSpan(String spanName) { @@ -71,7 +73,7 @@ private final SpanImpl createSampledEndedSpan(String spanName) { null, false, TraceParams.DEFAULT, - traceExporter, + startEndHandler, null, MillisClock.getInstance()); span.end(); @@ -87,7 +89,7 @@ private final SpanImpl createNotSampledEndedSpan(String spanName) { null, false, TraceParams.DEFAULT, - traceExporter, + startEndHandler, null, MillisClock.getInstance()); span.end(); @@ -124,7 +126,7 @@ public void exportMoreSpansThanTheBufferSize() { @Test public void interruptWorkerThreadStops() throws InterruptedException { - Thread serviceExporterThread = traceExporter.getServiceExporterThread(); + Thread serviceExporterThread = sampledSpansServiceExporter.getServiceExporterThread(); serviceExporterThread.interrupt(); // Test that the worker thread will stop. serviceExporterThread.join(); @@ -135,7 +137,7 @@ public void serviceHandlerThrowsException() { doThrow(new IllegalArgumentException("No export for you.")) .when(mockServiceHandler) .export(anyListOf(SpanData.class)); - traceExporter.registerServiceHandler("mock.service", mockServiceHandler); + sampledSpansServiceExporter.registerHandler("mock.service", mockServiceHandler); SpanImpl span1 = createSampledEndedSpan(SPAN_NAME_1); List exported = serviceHandler.waitForExport(1); assertThat(exported.size()).isEqualTo(1); @@ -150,7 +152,7 @@ public void serviceHandlerThrowsException() { @Test public void exportSpansToMultipleServices() { FakeServiceHandler serviceHandler2 = new FakeServiceHandler(); - traceExporter.registerServiceHandler("test.service2", serviceHandler2); + sampledSpansServiceExporter.registerHandler("test.service2", serviceHandler2); SpanImpl span1 = createSampledEndedSpan(SPAN_NAME_1); SpanImpl span2 = createSampledEndedSpan(SPAN_NAME_2); List exported1 = serviceHandler.waitForExport(2); @@ -177,8 +179,8 @@ public void exportNotSampledSpans() { assertThat(exported.get(0)).isEqualTo(span2.toSpanData()); } - /** Fake {@link ServiceHandler} for testing only. */ - private static final class FakeServiceHandler extends ServiceHandler { + /** Fake {@link Handler} for testing only. */ + private static final class FakeServiceHandler extends Handler { private final Object monitor = new Object(); @GuardedBy("monitor") diff --git a/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java b/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java index 7bae0e54a4..cbcac487ba 100644 --- a/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java @@ -47,6 +47,6 @@ public void implementationOfClock() { @Test public void implementationOfTraceExporter() { - assertThat(traceComponent.getTraceExporter()).isInstanceOf(TraceExporterImpl.class); + assertThat(traceComponent.getTraceExporter()).isInstanceOf(ExportComponentImpl.class); } } diff --git a/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java b/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java index 80580cc01e..b8393ec46d 100644 --- a/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java +++ b/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java @@ -41,6 +41,6 @@ public void implementationOfClock() { @Test public void implementationOfTraceExporter() { - assertThat(Tracing.getTraceExporter()).isInstanceOf(TraceExporterImpl.class); + assertThat(Tracing.getTraceExporter()).isInstanceOf(ExportComponentImpl.class); } } diff --git a/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java b/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java index 1496d4d3c6..85db9898bd 100644 --- a/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java +++ b/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java @@ -41,6 +41,6 @@ public void implementationOfClock() { @Test public void implementationOfTraceExporter() { - assertThat(Tracing.getTraceExporter()).isInstanceOf(TraceExporterImpl.class); + assertThat(Tracing.getTraceExporter()).isInstanceOf(ExportComponentImpl.class); } } diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java index ef497d7e7b..c98f3fa7ce 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java @@ -15,9 +15,9 @@ import io.opencensus.common.NonThrowingCloseable; import io.opencensus.trace.Span; -import io.opencensus.trace.TraceExporter; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; +import io.opencensus.trace.export.SpanExporter.LoggingHandler; /** * Example showing how to create a child {@link Span}, install it to the current context and add @@ -48,7 +48,7 @@ private static void doWork() { /** Main method. */ public static void main(String[] args) { - TraceExporter.LoggingServiceHandler.registerService(Tracing.getTraceExporter()); + LoggingHandler.register(Tracing.getTraceExporter().getSpanExporter()); Span span = tracer.spanBuilder("MyRootSpan").becomeRoot().startSpan(); try (NonThrowingCloseable ws = tracer.withSpan(span)) { doWork(); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java index 267fb639bc..ef57bf57da 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java @@ -15,9 +15,9 @@ import io.opencensus.common.NonThrowingCloseable; import io.opencensus.trace.Span; -import io.opencensus.trace.TraceExporter; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; +import io.opencensus.trace.export.SpanExporter.LoggingHandler; /** * Example showing how to create a child {@link Span} using scoped Spans, install it in the current @@ -46,7 +46,7 @@ private static void doWork() { /** Main method. */ public static void main(String[] args) { - TraceExporter.LoggingServiceHandler.registerService(Tracing.getTraceExporter()); + LoggingHandler.register(Tracing.getTraceExporter().getSpanExporter()); try (NonThrowingCloseable ss = tracer.spanBuilder("MyRootSpan").becomeRoot().startScopedSpan()) { doWork(); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java index 036d3684ec..785a213570 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java @@ -14,9 +14,9 @@ package io.opencensus.examples.trace; import io.opencensus.trace.Span; -import io.opencensus.trace.TraceExporter; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; +import io.opencensus.trace.export.SpanExporter.LoggingHandler; /** Example showing how to directly create a child {@link Span} and add annotations. */ public final class MultiSpansTracing { @@ -35,7 +35,7 @@ private static void doWork() { /** Main method. */ public static void main(String[] args) { - TraceExporter.LoggingServiceHandler.registerService(Tracing.getTraceExporter()); + LoggingHandler.register(Tracing.getTraceExporter().getSpanExporter()); doWork(); } } From 95870ac86d5e2164b7872b1f17a1ba748fa619e0 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 7 Jun 2017 18:41:15 -0700 Subject: [PATCH 0154/1581] Fix all javadocs warnings and errors and re-enable javadoc for api module. (#344) --- api/build.gradle | 2 +- .../java/io/opencensus/common/Duration.java | 19 ++++++++++++++++--- .../java/io/opencensus/common/Function.java | 5 +++-- .../java/io/opencensus/common/Timestamp.java | 3 +-- .../main/java/io/opencensus/tags/TagKey.java | 1 + .../java/io/opencensus/trace/SpanContext.java | 1 + 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/api/build.gradle b/api/build.gradle index 7cfb33b26a..99000c2c60 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -8,4 +8,4 @@ dependencies { signature "org.codehaus.mojo.signature:java16:+@signature" } -javadoc.exclude 'io/opencensus/**' \ No newline at end of file +javadoc.exclude 'io/opencensus/internal/**' \ No newline at end of file diff --git a/api/src/main/java/io/opencensus/common/Duration.java b/api/src/main/java/io/opencensus/common/Duration.java index c0e9f1bc70..bf490c39f4 100644 --- a/api/src/main/java/io/opencensus/common/Duration.java +++ b/api/src/main/java/io/opencensus/common/Duration.java @@ -45,19 +45,32 @@ public static Duration create(long seconds, int nanos) { return new Duration(seconds, nanos); } - /** Creates a new {@link Duration} from given milliseconds. */ + /** + * Creates a new {@link Duration} from given milliseconds. + * + * @param millis the duration in milliseconds. + * @return a new {@link Duration} from given milliseconds. + */ public static Duration fromMillis(long millis) { long seconds = millis / NUM_MILLIS_PER_SECOND; int nanos = (int) (millis % NUM_MILLIS_PER_SECOND) * NUM_NANOS_PER_MILLI; return new Duration(seconds, nanos); } - /** Returns the number of seconds in the {@link Duration}. */ + /** + * Returns the number of seconds in the {@link Duration}. + * + * @return the number of seconds in the {@link Duration}. + */ public long getSeconds() { return seconds; } - /** Returns the number of nanoseconds in the {@link Duration}. */ + /** + * Returns the number of nanoseconds in the {@link Duration}. + * + * @return the number of nanoseconds in the {@link Duration}. + */ public int getNanos() { return nanos; } diff --git a/api/src/main/java/io/opencensus/common/Function.java b/api/src/main/java/io/opencensus/common/Function.java index 51bf845caf..6105c3e674 100644 --- a/api/src/main/java/io/opencensus/common/Function.java +++ b/api/src/main/java/io/opencensus/common/Function.java @@ -14,12 +14,13 @@ package io.opencensus.common; /** - * Used to specify matching functions for use encoding tagged unions (i.e. sum types) in Java. See - * {@link io.opencensus.stats.ViewDescriptor} for an example of it's use. + * Used to specify matching functions for use encoding tagged unions (i.e. sum types) in Java. * *

              Note: This class is based on the java.util.Function class added in Java 1.8. We cannot use the * Function from Java 1.8 because this library is Java 1.6 compatible. */ +// TODO(bdrutu): Add back "See {@link io.opencensus.stats.ViewDescriptor} for an example of its +// use." public interface Function { B apply(A arg); } diff --git a/api/src/main/java/io/opencensus/common/Timestamp.java b/api/src/main/java/io/opencensus/common/Timestamp.java index 34c4c851dd..9a1dd8bbeb 100644 --- a/api/src/main/java/io/opencensus/common/Timestamp.java +++ b/api/src/main/java/io/opencensus/common/Timestamp.java @@ -37,8 +37,6 @@ private Timestamp(long seconds, int nanos) { this.nanos = nanos; } - // TODO(bdrutu): Make create and fromMillis package-protected. - /** * Creates a new timestamp from given seconds and nanoseconds. * @@ -63,6 +61,7 @@ public static Timestamp create(long seconds, int nanos) { /** * Creates a new timestamp from the given milliseconds. * + * @param millis the timestamp represented in milliseconds since epoch. * @return a new timestamp from the given milliseconds. */ public static Timestamp fromMillis(long millis) { diff --git a/api/src/main/java/io/opencensus/tags/TagKey.java b/api/src/main/java/io/opencensus/tags/TagKey.java index 970ee9250c..efd3e6e9e9 100644 --- a/api/src/main/java/io/opencensus/tags/TagKey.java +++ b/api/src/main/java/io/opencensus/tags/TagKey.java @@ -53,6 +53,7 @@ enum TagType { *

            * * @param name the name of the key. + * @return a {@code TagKey} with the given name. * @throws IllegalArgumentException if the name is not valid. */ public static TagKey createStringKey(String name) { diff --git a/api/src/main/java/io/opencensus/trace/SpanContext.java b/api/src/main/java/io/opencensus/trace/SpanContext.java index 4902f15f3c..56a046f183 100644 --- a/api/src/main/java/io/opencensus/trace/SpanContext.java +++ b/api/src/main/java/io/opencensus/trace/SpanContext.java @@ -39,6 +39,7 @@ public final class SpanContext { * @param traceId the trace identifier of the span context. * @param spanId the span identifier of the span context. * @param traceOptions the trace options for the span context. + * @return a new {@code SpanContext} with the given identifiers and options. */ public static SpanContext create(TraceId traceId, SpanId spanId, TraceOptions traceOptions) { return new SpanContext(traceId, spanId, traceOptions); From 1258b41748672df306155dd694ee55b744ae9359 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 8 Jun 2017 10:48:01 -0700 Subject: [PATCH 0155/1581] Change StartSpanOptions to use Autovalue. (#345) --- .../java/io/opencensus/trace/SpanBuilder.java | 13 +- .../io/opencensus/trace/StartSpanOptions.java | 118 ++++++++++-------- .../io/opencensus/trace/SpanBuilderTest.java | 30 ++--- .../trace/StartSpanOptionsTest.java | 47 +++---- .../java/io/opencensus/trace/TracerTest.java | 10 +- .../opencensus/trace/SpanFactoryImplTest.java | 19 ++- 6 files changed, 130 insertions(+), 107 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/SpanBuilder.java b/api/src/main/java/io/opencensus/trace/SpanBuilder.java index 4b988dfc33..150932e0d2 100644 --- a/api/src/main/java/io/opencensus/trace/SpanBuilder.java +++ b/api/src/main/java/io/opencensus/trace/SpanBuilder.java @@ -101,7 +101,7 @@ public final class SpanBuilder { private final SpanFactory spanFactory; private final String name; - private final StartSpanOptions startSpanOption = new StartSpanOptions(); + private final StartSpanOptions.Builder startSpanOptionsBuilder = StartSpanOptions.builder(); private Span parentSpan; private SpanContext parentSpanContext; private boolean remoteParent; @@ -123,7 +123,7 @@ static SpanBuilder builderWithRemoteParent( * @return this. */ public SpanBuilder setSampler(@Nullable Sampler sampler) { - startSpanOption.setSampler(sampler); + startSpanOptionsBuilder.setSampler(sampler); return this; } @@ -136,7 +136,7 @@ public SpanBuilder setSampler(@Nullable Sampler sampler) { * @return this. */ public SpanBuilder setParentLinks(@Nullable List parentLinks) { - startSpanOption.setParentLinks(parentLinks); + startSpanOptionsBuilder.setParentLinks(parentLinks); return this; } @@ -148,7 +148,7 @@ public SpanBuilder setParentLinks(@Nullable List parentLinks) { * @return this. */ public SpanBuilder setRecordEvents(boolean recordEvents) { - startSpanOption.setRecordEvents(recordEvents); + startSpanOptionsBuilder.setRecordEvents(recordEvents); return this; } @@ -276,7 +276,8 @@ private SpanBuilder( // Utility method to start a Span. private Span start() { return remoteParent - ? spanFactory.startSpanWithRemoteParent(parentSpanContext, name, startSpanOption) - : spanFactory.startSpan(parentSpan, name, startSpanOption); + ? spanFactory.startSpanWithRemoteParent( + parentSpanContext, name, startSpanOptionsBuilder.build()) + : spanFactory.startSpan(parentSpan, name, startSpanOptionsBuilder.build()); } } diff --git a/api/src/main/java/io/opencensus/trace/StartSpanOptions.java b/api/src/main/java/io/opencensus/trace/StartSpanOptions.java index 01bc8885f7..9b7ccb659f 100644 --- a/api/src/main/java/io/opencensus/trace/StartSpanOptions.java +++ b/api/src/main/java/io/opencensus/trace/StartSpanOptions.java @@ -13,26 +13,27 @@ package io.opencensus.trace; -import com.google.common.base.Objects; +import com.google.auto.value.AutoValue; +import com.google.common.annotations.VisibleForTesting; +import io.opencensus.trace.config.TraceConfig; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; /** * A class that enables overriding the default values used when starting a {@link Span}. Allows * overriding the {@link Sampler sampler}, the parent links, and option to record all the events * even if the {@code Span} is not sampled. */ -public final class StartSpanOptions { - private Sampler sampler; - private List parentLinks; - private Boolean recordEvents; - - StartSpanOptions() { - this.sampler = null; - this.parentLinks = null; - this.recordEvents = null; - } +@AutoValue +@Immutable +public abstract class StartSpanOptions { + private static final List EMPTY_PARENT_LINKS_LIST = Collections.emptyList(); + + /** The default {@code StartSpanOptions}. */ + @VisibleForTesting static final StartSpanOptions DEFAULT = builder().build(); /** * Returns the {@link Sampler} to be used, or {@code null} if default. @@ -40,62 +41,81 @@ public final class StartSpanOptions { * @return the {@code Sampler} to be used, or {@code null} if default. */ @Nullable - public Sampler getSampler() { - return sampler; - } + public abstract Sampler getSampler(); /** * Returns the parent links to be set for the {@link Span}. * * @return the parent links to be set for the {@code Span}. */ - public List getParentLinks() { - // Return an unmodifiable list. - return parentLinks == null - ? Collections.emptyList() - : Collections.unmodifiableList(parentLinks); - } + public abstract List getParentLinks(); /** - * Returns the record events option setting. + * Returns the record events option, or {@code null} if default. + * + *

            See {@link Span.Options#RECORD_EVENTS} for more details. * - * @return the record events option setting. + * @return the record events option, or {@code null} if default. */ @Nullable - public Boolean getRecordEvents() { - return recordEvents; + public abstract Boolean getRecordEvents(); + + /** + * Returns a new {@link Builder} with default options. + * + * @return a new {@code Builder} with default options. + */ + public static Builder builder() { + return new AutoValue_StartSpanOptions.Builder().setParentLinks(EMPTY_PARENT_LINKS_LIST); } - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } + /** Builder class for {@link StartSpanOptions}. */ + @AutoValue.Builder + public abstract static class Builder { - if (!(obj instanceof StartSpanOptions)) { - return false; - } + /** + * Sets the {@link Sampler} to be used. If {@code null} the default {@code Sampler} from the + * {@link TraceConfig#getActiveTraceParams()} will be used. + * + * @param sampler the {@link Sampler} to be used. + * @return this. + */ + public abstract Builder setSampler(@Nullable Sampler sampler); - StartSpanOptions that = (StartSpanOptions) obj; - return Objects.equal(sampler, that.sampler) - && Objects.equal(parentLinks, that.parentLinks) - && Objects.equal(recordEvents, that.recordEvents); - } + /** + * Sets the parent links to be set for the {@link Span}. + * + * @param parentLinks the parent links to be set for the {@link Span}. + * @return this. + * @throws NullPointerException if {@code parentLinks} is {@code null}. + */ + public abstract Builder setParentLinks(List parentLinks); - @Override - public int hashCode() { - return Objects.hashCode(sampler, parentLinks, recordEvents); - } + /** + * Sets the record events option. If {@code null} the default value from the {@link + * TraceConfig#getActiveTraceParams()} will be used. + * + *

            See {@link Span.Options#RECORD_EVENTS} for more details. + * + * @param recordEvents the record events option. + * @return this. + */ + public abstract Builder setRecordEvents(@Nullable Boolean recordEvents); - void setSampler(@Nullable Sampler sampler) { - this.sampler = sampler; - } + abstract List getParentLinks(); // not public - void setParentLinks(@Nullable List parentLinks) { - this.parentLinks = parentLinks; - } + abstract StartSpanOptions autoBuild(); // not public - void setRecordEvents(@Nullable Boolean recordEvents) { - this.recordEvents = recordEvents; + /** + * Builds and returns a {@code StartSpanOptions} with the desired settings. + * + * @return a {@code StartSpanOptions} with the desired settings. + */ + public StartSpanOptions build() { + setParentLinks(Collections.unmodifiableList(new ArrayList(getParentLinks()))); + return autoBuild(); + } } + + StartSpanOptions() {} } diff --git a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java index ccd3d80620..1b8035e7fd 100644 --- a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java @@ -52,7 +52,7 @@ public void setUp() { @Test public void startScopedSpanRoot() { - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(new StartSpanOptions()))) + when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) .thenReturn(span); NonThrowingCloseable ss = spanBuilder.becomeRoot().startScopedSpan(); try { @@ -65,8 +65,8 @@ public void startScopedSpanRoot() { @Test public void startScopedSpanRootWithOptions() { - StartSpanOptions startSpanOptions = new StartSpanOptions(); - startSpanOptions.setSampler(Samplers.neverSample()); + StartSpanOptions startSpanOptions = + StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(startSpanOptions))) .thenReturn(span); NonThrowingCloseable ss = @@ -81,7 +81,7 @@ public void startScopedSpanRootWithOptions() { @Test public void startRootSpan() { - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(new StartSpanOptions()))) + when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) .thenReturn(span); Span rootSpan = spanBuilder.becomeRoot().startSpan(); assertThat(rootSpan).isEqualTo(span); @@ -92,7 +92,7 @@ public void startRootSpan() { @Test public void startSpan_WithNullParent() { spanBuilder = SpanBuilder.builder(spanFactory, null, SPAN_NAME); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(new StartSpanOptions()))) + when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) .thenReturn(span); Span rootSpan = spanBuilder.startSpan(); assertThat(rootSpan).isEqualTo(span); @@ -103,9 +103,11 @@ public void startSpan_WithNullParent() { @Test public void startRootSpanWithOptions() { List parentList = Arrays.asList(BlankSpan.INSTANCE); - StartSpanOptions startSpanOptions = new StartSpanOptions(); - startSpanOptions.setParentLinks(parentList); - startSpanOptions.setSampler(Samplers.neverSample()); + StartSpanOptions startSpanOptions = + StartSpanOptions.builder() + .setSampler(Samplers.neverSample()) + .setParentLinks(parentList) + .build(); when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(startSpanOptions))) .thenReturn(span); Span rootSpan = @@ -122,7 +124,7 @@ public void startRootSpanWithOptions() { @Test public void startChildSpan() { when(spanFactory.startSpan( - same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(new StartSpanOptions()))) + same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) .thenReturn(span); Span childSpan = spanBuilder.startSpan(); assertThat(childSpan).isEqualTo(span); @@ -132,9 +134,9 @@ public void startChildSpan() { @Test public void startChildSpanWithOptions() { - StartSpanOptions startSpanOptions = new StartSpanOptions(); - startSpanOptions.setSampler(Samplers.neverSample()); - startSpanOptions.setRecordEvents(true); + StartSpanOptions startSpanOptions = + StartSpanOptions.builder().setSampler(Samplers.neverSample()).setRecordEvents(true).build(); + ; when(spanFactory.startSpan(same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(startSpanOptions))) .thenReturn(span); Span childSpan = @@ -148,7 +150,7 @@ public void startChildSpanWithOptions() { public void startSpanWitRemoteParent() { spanBuilder = SpanBuilder.builderWithRemoteParent(spanFactory, spanContext, SPAN_NAME); when(spanFactory.startSpanWithRemoteParent( - same(spanContext), same(SPAN_NAME), eq(new StartSpanOptions()))) + same(spanContext), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) .thenReturn(span); Span remoteChildSpan = spanBuilder.startSpan(); assertThat(remoteChildSpan).isEqualTo(span); @@ -160,7 +162,7 @@ public void startSpanWitRemoteParent() { public void startSpanWitRemoteParent_WithNullParent() { spanBuilder = SpanBuilder.builderWithRemoteParent(spanFactory, null, SPAN_NAME); when(spanFactory.startSpanWithRemoteParent( - isNull(SpanContext.class), same(SPAN_NAME), eq(new StartSpanOptions()))) + isNull(SpanContext.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) .thenReturn(span); Span remoteChildSpan = spanBuilder.startSpan(); assertThat(remoteChildSpan).isEqualTo(span); diff --git a/api/src/test/java/io/opencensus/trace/StartSpanOptionsTest.java b/api/src/test/java/io/opencensus/trace/StartSpanOptionsTest.java index b91e78ee1c..c37324ab3a 100644 --- a/api/src/test/java/io/opencensus/trace/StartSpanOptionsTest.java +++ b/api/src/test/java/io/opencensus/trace/StartSpanOptionsTest.java @@ -30,7 +30,7 @@ public class StartSpanOptionsTest { @Test public void defaultOptions() { - StartSpanOptions defaultOptions = new StartSpanOptions(); + StartSpanOptions defaultOptions = StartSpanOptions.builder().build(); assertThat(defaultOptions.getSampler()).isNull(); assertThat(defaultOptions.getParentLinks().isEmpty()).isTrue(); assertThat(defaultOptions.getRecordEvents()).isNull(); @@ -38,8 +38,8 @@ public void defaultOptions() { @Test public void setSampler() { - StartSpanOptions options = new StartSpanOptions(); - options.setSampler(Samplers.neverSample()); + StartSpanOptions options = + StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); assertThat(options.getSampler()).isEqualTo(Samplers.neverSample()); assertThat(options.getParentLinks().isEmpty()).isTrue(); assertThat(options.getRecordEvents()).isNull(); @@ -47,8 +47,7 @@ public void setSampler() { @Test public void setParentLinks() { - StartSpanOptions options = new StartSpanOptions(); - options.setParentLinks(singleParentList); + StartSpanOptions options = StartSpanOptions.builder().setParentLinks(singleParentList).build(); assertThat(options.getSampler()).isNull(); assertThat(options.getParentLinks()).isEqualTo(singleParentList); assertThat(options.getRecordEvents()).isNull(); @@ -56,8 +55,8 @@ public void setParentLinks() { @Test public void setParentLinks_EmptyList() { - StartSpanOptions options = new StartSpanOptions(); - options.setParentLinks(new LinkedList()); + StartSpanOptions options = + StartSpanOptions.builder().setParentLinks(new LinkedList()).build(); assertThat(options.getSampler()).isNull(); assertThat(options.getParentLinks().size()).isEqualTo(0); assertThat(options.getRecordEvents()).isNull(); @@ -65,8 +64,10 @@ public void setParentLinks_EmptyList() { @Test public void setParentLinks_MultipleParents() { - StartSpanOptions options = new StartSpanOptions(); - options.setParentLinks(Arrays.asList(BlankSpan.INSTANCE, BlankSpan.INSTANCE)); + StartSpanOptions options = + StartSpanOptions.builder() + .setParentLinks(Arrays.asList(BlankSpan.INSTANCE, BlankSpan.INSTANCE)) + .build(); assertThat(options.getSampler()).isNull(); assertThat(options.getParentLinks().size()).isEqualTo(2); assertThat(options.getRecordEvents()).isNull(); @@ -74,8 +75,7 @@ public void setParentLinks_MultipleParents() { @Test public void setRecordEvents() { - StartSpanOptions options = new StartSpanOptions(); - options.setRecordEvents(true); + StartSpanOptions options = StartSpanOptions.builder().setRecordEvents(true).build(); assertThat(options.getSampler()).isNull(); assertThat(options.getParentLinks().isEmpty()).isTrue(); assertThat(options.getRecordEvents()).isTrue(); @@ -83,11 +83,12 @@ public void setRecordEvents() { @Test public void setAllProperties() { - StartSpanOptions options = new StartSpanOptions(); - options.setSampler(Samplers.neverSample()); - options.setSampler(Samplers.alwaysSample()); // second SetSampler should apply - options.setRecordEvents(true); - options.setParentLinks(singleParentList); + StartSpanOptions options = + StartSpanOptions.builder() + .setSampler(Samplers.alwaysSample()) + .setRecordEvents(true) + .setParentLinks(singleParentList) + .build(); assertThat(options.getSampler()).isEqualTo(Samplers.alwaysSample()); assertThat(options.getParentLinks()).isEqualTo(singleParentList); assertThat(options.getRecordEvents()).isTrue(); @@ -96,15 +97,15 @@ public void setAllProperties() { @Test public void startSpanOptions_EqualsAndHashCode() { EqualsTester tester = new EqualsTester(); - StartSpanOptions optionsWithAlwaysSampler1 = new StartSpanOptions(); - optionsWithAlwaysSampler1.setSampler(Samplers.alwaysSample()); - StartSpanOptions optionsWithAlwaysSampler2 = new StartSpanOptions(); - optionsWithAlwaysSampler2.setSampler(Samplers.alwaysSample()); + StartSpanOptions optionsWithAlwaysSampler1 = + StartSpanOptions.builder().setSampler(Samplers.alwaysSample()).build(); + StartSpanOptions optionsWithAlwaysSampler2 = + StartSpanOptions.builder().setSampler(Samplers.alwaysSample()).build(); tester.addEqualityGroup(optionsWithAlwaysSampler1, optionsWithAlwaysSampler2); - StartSpanOptions optionsWithNeverSampler = new StartSpanOptions(); - optionsWithNeverSampler.setSampler(Samplers.neverSample()); + StartSpanOptions optionsWithNeverSampler = + StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); tester.addEqualityGroup(optionsWithNeverSampler); - tester.addEqualityGroup(new StartSpanOptions()); + tester.addEqualityGroup(StartSpanOptions.DEFAULT); tester.testEquals(); } } diff --git a/api/src/test/java/io/opencensus/trace/TracerTest.java b/api/src/test/java/io/opencensus/trace/TracerTest.java index cc46956cd5..80e16baf26 100644 --- a/api/src/test/java/io/opencensus/trace/TracerTest.java +++ b/api/src/test/java/io/opencensus/trace/TracerTest.java @@ -127,7 +127,7 @@ public void defaultSpanBuilderWitRemoteParent() { @Test public void startScopedSpanRoot() { Tracer mockTracer = new MockTracer(spanFactory); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(new StartSpanOptions()))) + when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) .thenReturn(span); NonThrowingCloseable ss = mockTracer.spanBuilder(SPAN_NAME).becomeRoot().startScopedSpan(); try { @@ -145,7 +145,7 @@ public void startScopedSpanChild() { try { assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); when(spanFactory.startSpan( - same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(new StartSpanOptions()))) + same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) .thenReturn(span); NonThrowingCloseable ss = mockTracer.spanBuilder(SPAN_NAME).startScopedSpan(); try { @@ -163,7 +163,7 @@ public void startScopedSpanChild() { @Test public void startRootSpan() { Tracer mockTracer = new MockTracer(spanFactory); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(new StartSpanOptions()))) + when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) .thenReturn(span); Span rootSpan = mockTracer.spanBuilder(BlankSpan.INSTANCE, SPAN_NAME).becomeRoot().startSpan(); assertThat(rootSpan).isEqualTo(span); @@ -175,7 +175,7 @@ public void startRootSpan() { public void startChildSpan() { Tracer mockTracer = new MockTracer(spanFactory); when(spanFactory.startSpan( - same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(new StartSpanOptions()))) + same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) .thenReturn(span); Span childSpan = mockTracer.spanBuilder(BlankSpan.INSTANCE, SPAN_NAME).startSpan(); assertThat(childSpan).isEqualTo(span); @@ -193,7 +193,7 @@ public void startSpanWitRemoteParent() { SpanId.generateRandomId(random), TraceOptions.DEFAULT); when(spanFactory.startSpanWithRemoteParent( - same(spanContext), same(SPAN_NAME), eq(new StartSpanOptions()))) + same(spanContext), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) .thenReturn(span); Span remoteChildSpan = mockTracer.spanBuilderWithRemoteParent(spanContext, SPAN_NAME).startSpan(); diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java index e93d30c24f..f1e75b9396 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java @@ -49,7 +49,7 @@ public void setUp() { @Test public void startSpanNullParent() { - StartSpanOptions startSpanOptions = new StartSpanOptions(); + StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); assertThat(span.getContext().isValid()).isTrue(); @@ -65,9 +65,8 @@ public void startSpanNullParent() { @Test public void startSpanNullParentWithRecordEvents() { - StartSpanOptions startSpanOptions = new StartSpanOptions(); - startSpanOptions.setSampler(Samplers.neverSample()); - startSpanOptions.setRecordEvents(true); + StartSpanOptions startSpanOptions = + StartSpanOptions.builder().setSampler(Samplers.neverSample()).setRecordEvents(true).build(); when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); assertThat(span.getContext().isValid()).isTrue(); @@ -81,8 +80,8 @@ public void startSpanNullParentWithRecordEvents() { @Test public void startSpanNullParentNoRecordOptions() { - StartSpanOptions startSpanOptions = new StartSpanOptions(); - startSpanOptions.setSampler(Samplers.neverSample()); + StartSpanOptions startSpanOptions = + StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); assertThat(span.getContext().isValid()).isTrue(); @@ -92,7 +91,7 @@ public void startSpanNullParentNoRecordOptions() { @Test public void startRemoteSpanNullParent() { - StartSpanOptions startSpanOptions = new StartSpanOptions(); + StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); Span span = spanFactory.startSpanWithRemoteParent(null, SPAN_NAME, startSpanOptions); assertThat(span.getContext().isValid()).isTrue(); @@ -106,7 +105,7 @@ public void startRemoteSpanNullParent() { @Test public void startChildSpan() { - StartSpanOptions startSpanOptions = new StartSpanOptions(); + StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); Span rootSpan = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); assertThat(rootSpan.getContext().isValid()).isTrue(); @@ -123,7 +122,7 @@ public void startChildSpan() { @Test public void startRemoteSpanInvalidParent() { - StartSpanOptions startSpanOptions = new StartSpanOptions(); + StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); Span span = spanFactory.startSpanWithRemoteParent(SpanContext.INVALID, SPAN_NAME, startSpanOptions); @@ -143,7 +142,7 @@ public void startRemoteSpan() { TraceId.generateRandomId(randomHandler.current()), SpanId.generateRandomId(randomHandler.current()), TraceOptions.DEFAULT); - StartSpanOptions startSpanOptions = new StartSpanOptions(); + StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); Span span = spanFactory.startSpanWithRemoteParent(spanContext, SPAN_NAME, startSpanOptions); assertThat(span.getContext().isValid()).isTrue(); From ddcf44bdec4fa1dea15513c8949280457292e3e7 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 8 Jun 2017 13:57:45 -0700 Subject: [PATCH 0156/1581] Move all base types into a different package called base. (#342) --- .../main/java/io/opencensus/trace/BlankSpan.java | 5 +++++ .../main/java/io/opencensus/trace/Sampler.java | 2 ++ .../main/java/io/opencensus/trace/Samplers.java | 2 ++ api/src/main/java/io/opencensus/trace/Span.java | 5 +++++ .../java/io/opencensus/trace/SpanBuilder.java | 1 + .../java/io/opencensus/trace/SpanContext.java | 3 +++ .../main/java/io/opencensus/trace/SpanData.java | 6 ++++++ .../opencensus/trace/{ => base}/Annotation.java | 2 +- .../trace/{ => base}/AttributeValue.java | 2 +- .../trace/{ => base}/EndSpanOptions.java | 3 ++- .../io/opencensus/trace/{ => base}/Link.java | 4 +++- .../trace/{ => base}/NetworkEvent.java | 2 +- .../io/opencensus/trace/{ => base}/SpanId.java | 2 +- .../io/opencensus/trace/{ => base}/Status.java | 3 ++- .../io/opencensus/trace/{ => base}/TraceId.java | 16 ++++++++++++---- .../trace/{ => base}/TraceOptions.java | 3 ++- .../io/opencensus/trace/config/TraceParams.java | 6 +++--- .../opencensus/trace/export/ExportComponent.java | 2 +- .../trace/export/InProcessDebuggingHandler.java | 4 ++-- .../io/opencensus/trace/export/SpanExporter.java | 2 +- .../java/io/opencensus/trace/BlankSpanTest.java | 5 +++++ .../java/io/opencensus/trace/SamplersTest.java | 3 +++ .../opencensus/trace/ScopedSpanHandleTest.java | 1 + .../io/opencensus/trace/SpanBuilderTest.java | 4 ++++ .../io/opencensus/trace/SpanContextTest.java | 3 +++ .../java/io/opencensus/trace/SpanDataTest.java | 10 +++++++++- .../test/java/io/opencensus/trace/SpanTest.java | 8 ++++++++ .../java/io/opencensus/trace/TracerTest.java | 4 ++++ .../trace/{ => base}/AnnotationTest.java | 2 +- .../trace/{ => base}/AttributeValueTest.java | 2 +- .../trace/{ => base}/EndSpanOptionsTest.java | 2 +- .../io/opencensus/trace/{ => base}/LinkTest.java | 5 +++-- .../trace/{ => base}/NetworkEventTest.java | 2 +- .../opencensus/trace/{ => base}/SpanIdTest.java | 2 +- .../opencensus/trace/{ => base}/StatusTest.java | 2 +- .../opencensus/trace/{ => base}/TraceIdTest.java | 2 +- .../trace/{ => base}/TraceOptionsTest.java | 2 +- .../BinaryPropagationHandlerImplBenchmark.java | 3 +++ ...RecordTraceEventsNonSampledSpanBenchmark.java | 3 +++ .../RecordTraceEventsSampledSpanBenchmark.java | 3 +++ .../trace/BinaryPropagationHandlerImpl.java | 3 +++ .../io/opencensus/trace/SpanFactoryImpl.java | 6 +++++- .../main/java/io/opencensus/trace/SpanImpl.java | 7 +++++++ .../trace/BinaryPropagationHandlerImplTest.java | 3 +++ .../opencensus/trace/SpanExporterImplTest.java | 3 +++ .../io/opencensus/trace/SpanFactoryImplTest.java | 3 +++ .../java/io/opencensus/trace/SpanImplTest.java | 9 +++++++++ 47 files changed, 146 insertions(+), 31 deletions(-) rename api/src/main/java/io/opencensus/trace/{ => base}/Annotation.java (98%) rename api/src/main/java/io/opencensus/trace/{ => base}/AttributeValue.java (98%) rename api/src/main/java/io/opencensus/trace/{ => base}/EndSpanOptions.java (97%) rename api/src/main/java/io/opencensus/trace/{ => base}/Link.java (95%) rename api/src/main/java/io/opencensus/trace/{ => base}/NetworkEvent.java (99%) rename api/src/main/java/io/opencensus/trace/{ => base}/SpanId.java (99%) rename api/src/main/java/io/opencensus/trace/{ => base}/Status.java (99%) rename api/src/main/java/io/opencensus/trace/{ => base}/TraceId.java (92%) rename api/src/main/java/io/opencensus/trace/{ => base}/TraceOptions.java (98%) rename api/src/test/java/io/opencensus/trace/{ => base}/AnnotationTest.java (99%) rename api/src/test/java/io/opencensus/trace/{ => base}/AttributeValueTest.java (98%) rename api/src/test/java/io/opencensus/trace/{ => base}/EndSpanOptionsTest.java (98%) rename api/src/test/java/io/opencensus/trace/{ => base}/LinkTest.java (96%) rename api/src/test/java/io/opencensus/trace/{ => base}/NetworkEventTest.java (99%) rename api/src/test/java/io/opencensus/trace/{ => base}/SpanIdTest.java (98%) rename api/src/test/java/io/opencensus/trace/{ => base}/StatusTest.java (98%) rename api/src/test/java/io/opencensus/trace/{ => base}/TraceIdTest.java (98%) rename api/src/test/java/io/opencensus/trace/{ => base}/TraceOptionsTest.java (98%) diff --git a/api/src/main/java/io/opencensus/trace/BlankSpan.java b/api/src/main/java/io/opencensus/trace/BlankSpan.java index 40e49551b7..f78c3907fa 100644 --- a/api/src/main/java/io/opencensus/trace/BlankSpan.java +++ b/api/src/main/java/io/opencensus/trace/BlankSpan.java @@ -13,6 +13,11 @@ package io.opencensus.trace; +import io.opencensus.trace.base.Annotation; +import io.opencensus.trace.base.AttributeValue; +import io.opencensus.trace.base.EndSpanOptions; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.NetworkEvent; import java.util.Map; import javax.annotation.concurrent.Immutable; diff --git a/api/src/main/java/io/opencensus/trace/Sampler.java b/api/src/main/java/io/opencensus/trace/Sampler.java index e5014fa440..d231f41b6a 100644 --- a/api/src/main/java/io/opencensus/trace/Sampler.java +++ b/api/src/main/java/io/opencensus/trace/Sampler.java @@ -13,6 +13,8 @@ package io.opencensus.trace; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; import java.util.List; import javax.annotation.Nullable; diff --git a/api/src/main/java/io/opencensus/trace/Samplers.java b/api/src/main/java/io/opencensus/trace/Samplers.java index 33c2a0065d..8d7908ec9a 100644 --- a/api/src/main/java/io/opencensus/trace/Samplers.java +++ b/api/src/main/java/io/opencensus/trace/Samplers.java @@ -16,6 +16,8 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.auto.value.AutoValue; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; import java.util.List; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; diff --git a/api/src/main/java/io/opencensus/trace/Span.java b/api/src/main/java/io/opencensus/trace/Span.java index 76dcd9c7e6..0a941287c9 100644 --- a/api/src/main/java/io/opencensus/trace/Span.java +++ b/api/src/main/java/io/opencensus/trace/Span.java @@ -16,6 +16,11 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import io.opencensus.trace.base.Annotation; +import io.opencensus.trace.base.AttributeValue; +import io.opencensus.trace.base.EndSpanOptions; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.NetworkEvent; import java.util.Collections; import java.util.EnumSet; import java.util.Map; diff --git a/api/src/main/java/io/opencensus/trace/SpanBuilder.java b/api/src/main/java/io/opencensus/trace/SpanBuilder.java index 150932e0d2..ec9719fc75 100644 --- a/api/src/main/java/io/opencensus/trace/SpanBuilder.java +++ b/api/src/main/java/io/opencensus/trace/SpanBuilder.java @@ -14,6 +14,7 @@ package io.opencensus.trace; import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.base.EndSpanOptions; import java.util.List; import javax.annotation.Nullable; diff --git a/api/src/main/java/io/opencensus/trace/SpanContext.java b/api/src/main/java/io/opencensus/trace/SpanContext.java index 56a046f183..8847a3ce8f 100644 --- a/api/src/main/java/io/opencensus/trace/SpanContext.java +++ b/api/src/main/java/io/opencensus/trace/SpanContext.java @@ -15,6 +15,9 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Objects; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import javax.annotation.concurrent.Immutable; /** diff --git a/api/src/main/java/io/opencensus/trace/SpanData.java b/api/src/main/java/io/opencensus/trace/SpanData.java index f9a8140f38..02c8952824 100644 --- a/api/src/main/java/io/opencensus/trace/SpanData.java +++ b/api/src/main/java/io/opencensus/trace/SpanData.java @@ -17,6 +17,12 @@ import com.google.auto.value.AutoValue; import io.opencensus.common.Timestamp; +import io.opencensus.trace.base.Annotation; +import io.opencensus.trace.base.AttributeValue; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.NetworkEvent; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.Status; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; diff --git a/api/src/main/java/io/opencensus/trace/Annotation.java b/api/src/main/java/io/opencensus/trace/base/Annotation.java similarity index 98% rename from api/src/main/java/io/opencensus/trace/Annotation.java rename to api/src/main/java/io/opencensus/trace/base/Annotation.java index f72070e815..b86b93d8a6 100644 --- a/api/src/main/java/io/opencensus/trace/Annotation.java +++ b/api/src/main/java/io/opencensus/trace/base/Annotation.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/api/src/main/java/io/opencensus/trace/AttributeValue.java b/api/src/main/java/io/opencensus/trace/base/AttributeValue.java similarity index 98% rename from api/src/main/java/io/opencensus/trace/AttributeValue.java rename to api/src/main/java/io/opencensus/trace/base/AttributeValue.java index f66fd42597..86f0c84ab0 100644 --- a/api/src/main/java/io/opencensus/trace/AttributeValue.java +++ b/api/src/main/java/io/opencensus/trace/base/AttributeValue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/api/src/main/java/io/opencensus/trace/EndSpanOptions.java b/api/src/main/java/io/opencensus/trace/base/EndSpanOptions.java similarity index 97% rename from api/src/main/java/io/opencensus/trace/EndSpanOptions.java rename to api/src/main/java/io/opencensus/trace/base/EndSpanOptions.java index e58a06c381..00cd8ffbec 100644 --- a/api/src/main/java/io/opencensus/trace/EndSpanOptions.java +++ b/api/src/main/java/io/opencensus/trace/base/EndSpanOptions.java @@ -11,11 +11,12 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.base.Preconditions.checkNotNull; import com.google.auto.value.AutoValue; +import io.opencensus.trace.Span; import javax.annotation.concurrent.Immutable; /** diff --git a/api/src/main/java/io/opencensus/trace/Link.java b/api/src/main/java/io/opencensus/trace/base/Link.java similarity index 95% rename from api/src/main/java/io/opencensus/trace/Link.java rename to api/src/main/java/io/opencensus/trace/base/Link.java index d582b68b8d..363bd212b5 100644 --- a/api/src/main/java/io/opencensus/trace/Link.java +++ b/api/src/main/java/io/opencensus/trace/base/Link.java @@ -11,9 +11,11 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import com.google.auto.value.AutoValue; +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanContext; import javax.annotation.concurrent.Immutable; /** diff --git a/api/src/main/java/io/opencensus/trace/NetworkEvent.java b/api/src/main/java/io/opencensus/trace/base/NetworkEvent.java similarity index 99% rename from api/src/main/java/io/opencensus/trace/NetworkEvent.java rename to api/src/main/java/io/opencensus/trace/base/NetworkEvent.java index 10687074c4..9edc6f2505 100644 --- a/api/src/main/java/io/opencensus/trace/NetworkEvent.java +++ b/api/src/main/java/io/opencensus/trace/base/NetworkEvent.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/api/src/main/java/io/opencensus/trace/SpanId.java b/api/src/main/java/io/opencensus/trace/base/SpanId.java similarity index 99% rename from api/src/main/java/io/opencensus/trace/SpanId.java rename to api/src/main/java/io/opencensus/trace/base/SpanId.java index 8128c9d7de..4e0b1bedca 100644 --- a/api/src/main/java/io/opencensus/trace/SpanId.java +++ b/api/src/main/java/io/opencensus/trace/base/SpanId.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/api/src/main/java/io/opencensus/trace/Status.java b/api/src/main/java/io/opencensus/trace/base/Status.java similarity index 99% rename from api/src/main/java/io/opencensus/trace/Status.java rename to api/src/main/java/io/opencensus/trace/base/Status.java index 22cb52875a..6166c17ca7 100644 --- a/api/src/main/java/io/opencensus/trace/Status.java +++ b/api/src/main/java/io/opencensus/trace/base/Status.java @@ -11,12 +11,13 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; +import io.opencensus.trace.Span; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/api/src/main/java/io/opencensus/trace/TraceId.java b/api/src/main/java/io/opencensus/trace/base/TraceId.java similarity index 92% rename from api/src/main/java/io/opencensus/trace/TraceId.java rename to api/src/main/java/io/opencensus/trace/base/TraceId.java index 5684efdfda..293e2a7215 100644 --- a/api/src/main/java/io/opencensus/trace/TraceId.java +++ b/api/src/main/java/io/opencensus/trace/base/TraceId.java @@ -11,13 +11,14 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; import com.google.common.io.BaseEncoding; +import io.opencensus.common.Internal; import java.util.Arrays; import java.util.Random; import javax.annotation.concurrent.Immutable; @@ -133,9 +134,16 @@ public boolean isValid() { return !Arrays.equals(bytes, INVALID.bytes); } - // Return the lower 8 bytes of the trace-id as a long value, assuming little-endian order. This - // is used in ProbabilitySampler. - long getLowerLong() { + /** + * Returns the lower 8 bytes of the trace-id as a long value, assuming little-endian order. This + * is used in ProbabilitySampler. + * + *

            This method is marked as internal and subject to change. + * + * @return the lower 8 bytes of the trace-id as a long value, assuming little-endian order. + */ + @Internal + public long getLowerLong() { long result = 0; for (int i = 0; i < Long.SIZE / Byte.SIZE; i++) { result <<= Byte.SIZE; diff --git a/api/src/main/java/io/opencensus/trace/TraceOptions.java b/api/src/main/java/io/opencensus/trace/base/TraceOptions.java similarity index 98% rename from api/src/main/java/io/opencensus/trace/TraceOptions.java rename to api/src/main/java/io/opencensus/trace/base/TraceOptions.java index 6fc04bb92c..57733238f8 100644 --- a/api/src/main/java/io/opencensus/trace/TraceOptions.java +++ b/api/src/main/java/io/opencensus/trace/base/TraceOptions.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkElementIndex; @@ -20,6 +20,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; +import io.opencensus.trace.Span; import javax.annotation.concurrent.Immutable; /** diff --git a/api/src/main/java/io/opencensus/trace/config/TraceParams.java b/api/src/main/java/io/opencensus/trace/config/TraceParams.java index c446334265..1f0e093f76 100644 --- a/api/src/main/java/io/opencensus/trace/config/TraceParams.java +++ b/api/src/main/java/io/opencensus/trace/config/TraceParams.java @@ -16,13 +16,13 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.auto.value.AutoValue; -import io.opencensus.trace.Annotation; -import io.opencensus.trace.Link; -import io.opencensus.trace.NetworkEvent; import io.opencensus.trace.Sampler; import io.opencensus.trace.Samplers; import io.opencensus.trace.Span; import io.opencensus.trace.StartSpanOptions; +import io.opencensus.trace.base.Annotation; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.NetworkEvent; import javax.annotation.concurrent.Immutable; /** Class that holds global trace parameters. */ diff --git a/api/src/main/java/io/opencensus/trace/export/ExportComponent.java b/api/src/main/java/io/opencensus/trace/export/ExportComponent.java index 5407c46b02..03f1cc6c38 100644 --- a/api/src/main/java/io/opencensus/trace/export/ExportComponent.java +++ b/api/src/main/java/io/opencensus/trace/export/ExportComponent.java @@ -13,7 +13,7 @@ package io.opencensus.trace.export; -import io.opencensus.trace.TraceOptions; +import io.opencensus.trace.base.TraceOptions; import javax.annotation.Nullable; /** diff --git a/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java b/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java index 56318bd9d4..40fdcae0df 100644 --- a/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java +++ b/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java @@ -19,8 +19,8 @@ import com.google.auto.value.AutoValue; import io.opencensus.trace.Span; import io.opencensus.trace.SpanData; -import io.opencensus.trace.Status; -import io.opencensus.trace.Status.CanonicalCode; +import io.opencensus.trace.base.Status; +import io.opencensus.trace.base.Status.CanonicalCode; import java.util.Collection; import java.util.Collections; import java.util.HashMap; diff --git a/api/src/main/java/io/opencensus/trace/export/SpanExporter.java b/api/src/main/java/io/opencensus/trace/export/SpanExporter.java index 5e10d8be9a..199427b1bc 100644 --- a/api/src/main/java/io/opencensus/trace/export/SpanExporter.java +++ b/api/src/main/java/io/opencensus/trace/export/SpanExporter.java @@ -15,7 +15,7 @@ import io.opencensus.trace.Span; import io.opencensus.trace.SpanData; -import io.opencensus.trace.TraceOptions; +import io.opencensus.trace.base.TraceOptions; import java.util.Collection; import java.util.logging.Level; import java.util.logging.Logger; diff --git a/api/src/test/java/io/opencensus/trace/BlankSpanTest.java b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java index 252d02ff9f..c2f4c35d6f 100644 --- a/api/src/test/java/io/opencensus/trace/BlankSpanTest.java +++ b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java @@ -15,6 +15,11 @@ import static com.google.common.truth.Truth.assertThat; +import io.opencensus.trace.base.Annotation; +import io.opencensus.trace.base.AttributeValue; +import io.opencensus.trace.base.EndSpanOptions; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.NetworkEvent; import java.util.HashMap; import java.util.Map; import org.junit.Test; diff --git a/api/src/test/java/io/opencensus/trace/SamplersTest.java b/api/src/test/java/io/opencensus/trace/SamplersTest.java index af7fcaf596..52351f2c69 100644 --- a/api/src/test/java/io/opencensus/trace/SamplersTest.java +++ b/api/src/test/java/io/opencensus/trace/SamplersTest.java @@ -15,6 +15,9 @@ import static com.google.common.truth.Truth.assertThat; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import java.util.Collections; import java.util.Random; import org.junit.Test; diff --git a/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java b/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java index 8922f4c2d2..cf043d09f7 100644 --- a/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java +++ b/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java @@ -18,6 +18,7 @@ import static org.mockito.Mockito.verify; import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.base.EndSpanOptions; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java index 1b8035e7fd..e112376870 100644 --- a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java @@ -21,6 +21,10 @@ import static org.mockito.Mockito.when; import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.base.EndSpanOptions; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import java.util.Arrays; import java.util.List; import java.util.Random; diff --git a/api/src/test/java/io/opencensus/trace/SpanContextTest.java b/api/src/test/java/io/opencensus/trace/SpanContextTest.java index c0eb5d407f..eaa5bfc9f0 100644 --- a/api/src/test/java/io/opencensus/trace/SpanContextTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanContextTest.java @@ -16,6 +16,9 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/api/src/test/java/io/opencensus/trace/SpanDataTest.java b/api/src/test/java/io/opencensus/trace/SpanDataTest.java index 7a7f7899c5..ce10c35e0a 100644 --- a/api/src/test/java/io/opencensus/trace/SpanDataTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanDataTest.java @@ -17,11 +17,19 @@ import com.google.common.testing.EqualsTester; import io.opencensus.common.Timestamp; -import io.opencensus.trace.Link.Type; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.Link.Type; import io.opencensus.trace.SpanData.Attributes; import io.opencensus.trace.SpanData.Links; import io.opencensus.trace.SpanData.TimedEvent; import io.opencensus.trace.SpanData.TimedEvents; +import io.opencensus.trace.base.Annotation; +import io.opencensus.trace.base.AttributeValue; +import io.opencensus.trace.base.NetworkEvent; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.Status; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; diff --git a/api/src/test/java/io/opencensus/trace/SpanTest.java b/api/src/test/java/io/opencensus/trace/SpanTest.java index c8f7cb503f..0ab481d922 100644 --- a/api/src/test/java/io/opencensus/trace/SpanTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanTest.java @@ -17,6 +17,14 @@ import static org.mockito.Matchers.same; import static org.mockito.Mockito.verify; +import io.opencensus.trace.base.Annotation; +import io.opencensus.trace.base.AttributeValue; +import io.opencensus.trace.base.EndSpanOptions; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.NetworkEvent; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import java.util.EnumSet; import java.util.Map; import java.util.Random; diff --git a/api/src/test/java/io/opencensus/trace/TracerTest.java b/api/src/test/java/io/opencensus/trace/TracerTest.java index 80e16baf26..ad98483b1f 100644 --- a/api/src/test/java/io/opencensus/trace/TracerTest.java +++ b/api/src/test/java/io/opencensus/trace/TracerTest.java @@ -22,6 +22,10 @@ import io.grpc.Context; import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.base.EndSpanOptions; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import java.util.Random; import org.junit.Before; import org.junit.Rule; diff --git a/api/src/test/java/io/opencensus/trace/AnnotationTest.java b/api/src/test/java/io/opencensus/trace/base/AnnotationTest.java similarity index 99% rename from api/src/test/java/io/opencensus/trace/AnnotationTest.java rename to api/src/test/java/io/opencensus/trace/base/AnnotationTest.java index fbfe5fd354..c6e0c2ceab 100644 --- a/api/src/test/java/io/opencensus/trace/AnnotationTest.java +++ b/api/src/test/java/io/opencensus/trace/base/AnnotationTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/AttributeValueTest.java b/api/src/test/java/io/opencensus/trace/base/AttributeValueTest.java similarity index 98% rename from api/src/test/java/io/opencensus/trace/AttributeValueTest.java rename to api/src/test/java/io/opencensus/trace/base/AttributeValueTest.java index 7a999604e4..43f85aa48f 100644 --- a/api/src/test/java/io/opencensus/trace/AttributeValueTest.java +++ b/api/src/test/java/io/opencensus/trace/base/AttributeValueTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java b/api/src/test/java/io/opencensus/trace/base/EndSpanOptionsTest.java similarity index 98% rename from api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java rename to api/src/test/java/io/opencensus/trace/base/EndSpanOptionsTest.java index d531fba551..87ff8df8ae 100644 --- a/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java +++ b/api/src/test/java/io/opencensus/trace/base/EndSpanOptionsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/LinkTest.java b/api/src/test/java/io/opencensus/trace/base/LinkTest.java similarity index 96% rename from api/src/test/java/io/opencensus/trace/LinkTest.java rename to api/src/test/java/io/opencensus/trace/base/LinkTest.java index e1289f33a1..4fafa02ad7 100644 --- a/api/src/test/java/io/opencensus/trace/LinkTest.java +++ b/api/src/test/java/io/opencensus/trace/base/LinkTest.java @@ -11,12 +11,13 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import io.opencensus.trace.Link.Type; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.base.Link.Type; import java.util.Random; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/api/src/test/java/io/opencensus/trace/NetworkEventTest.java b/api/src/test/java/io/opencensus/trace/base/NetworkEventTest.java similarity index 99% rename from api/src/test/java/io/opencensus/trace/NetworkEventTest.java rename to api/src/test/java/io/opencensus/trace/base/NetworkEventTest.java index 946e8ce142..09d796ee00 100644 --- a/api/src/test/java/io/opencensus/trace/NetworkEventTest.java +++ b/api/src/test/java/io/opencensus/trace/base/NetworkEventTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/SpanIdTest.java b/api/src/test/java/io/opencensus/trace/base/SpanIdTest.java similarity index 98% rename from api/src/test/java/io/opencensus/trace/SpanIdTest.java rename to api/src/test/java/io/opencensus/trace/base/SpanIdTest.java index a35fddce62..6db2dc8181 100644 --- a/api/src/test/java/io/opencensus/trace/SpanIdTest.java +++ b/api/src/test/java/io/opencensus/trace/base/SpanIdTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/StatusTest.java b/api/src/test/java/io/opencensus/trace/base/StatusTest.java similarity index 98% rename from api/src/test/java/io/opencensus/trace/StatusTest.java rename to api/src/test/java/io/opencensus/trace/base/StatusTest.java index c66a3428f4..b8c2e19b07 100644 --- a/api/src/test/java/io/opencensus/trace/StatusTest.java +++ b/api/src/test/java/io/opencensus/trace/base/StatusTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/TraceIdTest.java b/api/src/test/java/io/opencensus/trace/base/TraceIdTest.java similarity index 98% rename from api/src/test/java/io/opencensus/trace/TraceIdTest.java rename to api/src/test/java/io/opencensus/trace/base/TraceIdTest.java index cd1b7c24f0..dd87d40d1b 100644 --- a/api/src/test/java/io/opencensus/trace/TraceIdTest.java +++ b/api/src/test/java/io/opencensus/trace/base/TraceIdTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/TraceOptionsTest.java b/api/src/test/java/io/opencensus/trace/base/TraceOptionsTest.java similarity index 98% rename from api/src/test/java/io/opencensus/trace/TraceOptionsTest.java rename to api/src/test/java/io/opencensus/trace/base/TraceOptionsTest.java index fb24064662..0d247347dc 100644 --- a/api/src/test/java/io/opencensus/trace/TraceOptionsTest.java +++ b/api/src/test/java/io/opencensus/trace/base/TraceOptionsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.truth.Truth.assertThat; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/BinaryPropagationHandlerImplBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/BinaryPropagationHandlerImplBenchmark.java index 85302d25db..8a0ff0169b 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/BinaryPropagationHandlerImplBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/BinaryPropagationHandlerImplBenchmark.java @@ -13,6 +13,9 @@ package io.opencensus.trace; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import java.text.ParseException; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java index 0c3daa87a2..13657e1bad 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java @@ -13,6 +13,9 @@ package io.opencensus.trace; +import io.opencensus.trace.base.AttributeValue; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.NetworkEvent; import java.util.HashMap; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java index 78a587f45e..3c2a9d1776 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java @@ -13,6 +13,9 @@ package io.opencensus.trace; +import io.opencensus.trace.base.AttributeValue; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.NetworkEvent; import java.util.HashMap; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; diff --git a/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java b/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java index 943f32112c..6359bc40cc 100644 --- a/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java @@ -15,6 +15,9 @@ import static com.google.common.base.Preconditions.checkNotNull; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import java.text.ParseException; /** diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java index 703b5b3b2b..de21507d56 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java @@ -16,8 +16,12 @@ import static com.google.common.base.Preconditions.checkNotNull; import io.opencensus.common.Clock; -import io.opencensus.trace.Link.Type; import io.opencensus.trace.Span.Options; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.Link.Type; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceParams; import java.util.EnumSet; diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java index 6eab0ccc30..53e897b7bc 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java @@ -19,6 +19,13 @@ import com.google.common.collect.EvictingQueue; import io.opencensus.common.Clock; import io.opencensus.trace.SpanData.TimedEvent; +import io.opencensus.trace.base.Annotation; +import io.opencensus.trace.base.AttributeValue; +import io.opencensus.trace.base.EndSpanOptions; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.NetworkEvent; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.Status; import io.opencensus.trace.config.TraceParams; import java.util.ArrayList; import java.util.Collections; diff --git a/core_impl/src/test/java/io/opencensus/trace/BinaryPropagationHandlerImplTest.java b/core_impl/src/test/java/io/opencensus/trace/BinaryPropagationHandlerImplTest.java index c6ea04e6b0..6137f95239 100644 --- a/core_impl/src/test/java/io/opencensus/trace/BinaryPropagationHandlerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/BinaryPropagationHandlerImplTest.java @@ -16,6 +16,9 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import java.text.ParseException; import org.junit.Rule; import org.junit.Test; diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java index 46256c9de5..9ffff353fe 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java @@ -21,6 +21,9 @@ import io.opencensus.common.SimpleEventQueue; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.export.SpanExporter.Handler; import java.util.ArrayList; diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java index f1e75b9396..89937321e5 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java @@ -19,6 +19,9 @@ import io.opencensus.internal.TestClock; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceParams; import java.util.Random; diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java index 81fd831620..6e81eb6dc7 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java @@ -20,6 +20,15 @@ import io.opencensus.internal.TestClock; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.base.Annotation; +import io.opencensus.trace.base.AttributeValue; +import io.opencensus.trace.base.EndSpanOptions; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.NetworkEvent; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.Status; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceParams; import java.util.EnumSet; import java.util.HashMap; From d6a42072f8d0988450dfbf35b18ce134f94368c4 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 8 Jun 2017 17:32:17 -0700 Subject: [PATCH 0157/1581] Fix all javadoc excludes for the internal package. (#349) --- all/build.gradle | 2 +- core_impl/build.gradle | 2 +- core_impl_java/build.gradle | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/all/build.gradle b/all/build.gradle index 3318927748..86f96814ec 100644 --- a/all/build.gradle +++ b/all/build.gradle @@ -42,7 +42,7 @@ javadoc { source subproject.javadoc.source options.links subproject.javadoc.options.links.toArray(new String[0]) } - exclude 'com/google/instrumentation/internal/**' + exclude 'io/opencensus/internal/**' } task jacocoMerge(type: JacocoMerge) { diff --git a/core_impl/build.gradle b/core_impl/build.gradle index 9db6338a2c..ced6e56733 100644 --- a/core_impl/build.gradle +++ b/core_impl/build.gradle @@ -11,4 +11,4 @@ dependencies { signature "org.codehaus.mojo.signature:java16:+@signature" } -javadoc.exclude 'com/google/instrumentation/internal/**' \ No newline at end of file +javadoc.exclude 'io/opencensus/internal/**' \ No newline at end of file diff --git a/core_impl_java/build.gradle b/core_impl_java/build.gradle index a223ac6396..61f23e4ecf 100644 --- a/core_impl_java/build.gradle +++ b/core_impl_java/build.gradle @@ -14,3 +14,5 @@ dependencies { signature "org.codehaus.mojo.signature:java17:+@signature" } + +javadoc.exclude 'io/opencensus/internal/**' \ No newline at end of file From 7331a983599bddccc87dd1545301edff795322b2 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 8 Jun 2017 17:33:01 -0700 Subject: [PATCH 0158/1581] Create a new package for all supported propagations. (#341) --- .../io/opencensus/trace/TraceComponent.java | 17 +++---- .../java/io/opencensus/trace/Tracing.java | 11 +++-- .../BinaryFormat.java} | 33 +++++++------ .../propagation/PropagationComponent.java | 47 +++++++++++++++++++ .../opencensus/trace/TraceComponentTest.java | 7 +-- .../java/io/opencensus/trace/TracingTest.java | 5 +- .../BinaryFormatTest.java} | 20 ++++---- .../propagation/PropagationComponentTest.java | 33 +++++++++++++ .../BinaryPropagationImplBenchmark.java} | 28 +++++------ .../trace/TraceComponentImplBase.java | 17 +++---- .../BinaryFormatImpl.java} | 11 +++-- .../propagation/PropagationComponentImpl.java | 24 ++++++++++ .../trace/TraceComponentImplBaseTest.java | 7 +-- .../BinaryFormatImplTest.java} | 38 +++++++-------- .../PropagationComponentImplTest.java | 32 +++++++++++++ .../trace/TraceComponentImplTest.java | 5 +- .../java/io/opencensus/trace/TracingTest.java | 5 +- 17 files changed, 241 insertions(+), 99 deletions(-) rename api/src/main/java/io/opencensus/trace/{BinaryPropagationHandler.java => propagation/BinaryFormat.java} (73%) create mode 100644 api/src/main/java/io/opencensus/trace/propagation/PropagationComponent.java rename api/src/test/java/io/opencensus/trace/{BinaryPropagationHandlerTest.java => propagation/BinaryFormatTest.java} (66%) create mode 100644 api/src/test/java/io/opencensus/trace/propagation/PropagationComponentTest.java rename benchmarks/src/jmh/java/io/opencensus/trace/{BinaryPropagationHandlerImplBenchmark.java => propagation/BinaryPropagationImplBenchmark.java} (74%) rename core_impl/src/main/java/io/opencensus/trace/{BinaryPropagationHandlerImpl.java => propagation/BinaryFormatImpl.java} (95%) create mode 100644 core_impl/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java rename core_impl/src/test/java/io/opencensus/trace/{BinaryPropagationHandlerImplTest.java => propagation/BinaryFormatImplTest.java} (82%) create mode 100644 core_impl/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java diff --git a/api/src/main/java/io/opencensus/trace/TraceComponent.java b/api/src/main/java/io/opencensus/trace/TraceComponent.java index 54c2c8a153..276999ccd3 100644 --- a/api/src/main/java/io/opencensus/trace/TraceComponent.java +++ b/api/src/main/java/io/opencensus/trace/TraceComponent.java @@ -17,10 +17,11 @@ import io.opencensus.internal.ZeroTimeClock; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.propagation.PropagationComponent; /** * Class that holds the implementation instances for {@link Tracer}, {@link - * BinaryPropagationHandler}, {@link Clock}, {@link ExportComponent} and {@link TraceConfig}. + * PropagationComponent}, {@link Clock}, {@link ExportComponent} and {@link TraceConfig}. * *

            Unless otherwise noted all methods (on component) results are cacheable. */ @@ -36,12 +37,12 @@ public abstract class TraceComponent { public abstract Tracer getTracer(); /** - * Returns the {@link BinaryPropagationHandler} with the provided implementations. If no + * Returns the {@link PropagationComponent} with the provided implementation. If no * implementation is provided then no-op implementation will be used. * - * @return the {@code BinaryPropagationHandler} implementation. + * @return the {@code PropagationComponent} implementation. */ - public abstract BinaryPropagationHandler getBinaryPropagationHandler(); + public abstract PropagationComponent getPropagationComponent(); /** * Returns the {@link Clock} with the provided implementation. @@ -56,7 +57,7 @@ public abstract class TraceComponent { * * @return the {@link ExportComponent} implementation. */ - public abstract ExportComponent getTraceExporter(); + public abstract ExportComponent getExportComponent(); /** * Returns the {@link TraceConfig} with the provided implementation. If no implementation is @@ -85,8 +86,8 @@ public Tracer getTracer() { } @Override - public BinaryPropagationHandler getBinaryPropagationHandler() { - return BinaryPropagationHandler.getNoopBinaryPropagationHandler(); + public PropagationComponent getPropagationComponent() { + return PropagationComponent.getNoopPropagationComponent(); } @Override @@ -95,7 +96,7 @@ public Clock getClock() { } @Override - public ExportComponent getTraceExporter() { + public ExportComponent getExportComponent() { return ExportComponent.getNoopExportComponent(); } diff --git a/api/src/main/java/io/opencensus/trace/Tracing.java b/api/src/main/java/io/opencensus/trace/Tracing.java index daf5b3c994..3a4be46350 100644 --- a/api/src/main/java/io/opencensus/trace/Tracing.java +++ b/api/src/main/java/io/opencensus/trace/Tracing.java @@ -18,6 +18,7 @@ import io.opencensus.internal.Provider; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.propagation.PropagationComponent; import java.util.logging.Level; import java.util.logging.Logger; @@ -37,12 +38,12 @@ public static Tracer getTracer() { } /** - * Returns the global {@link BinaryPropagationHandler}. + * Returns the global {@link PropagationComponent}. * - * @return the global {@code BinaryPropagationHandler}. + * @return the global {@code PropagationComponent}. */ - public static BinaryPropagationHandler getBinaryPropagationHandler() { - return traceComponent.getBinaryPropagationHandler(); + public static PropagationComponent getPropagationComponent() { + return traceComponent.getPropagationComponent(); } /** @@ -60,7 +61,7 @@ public static Clock getClock() { * @return the global {@code ExportComponent}. */ public static ExportComponent getTraceExporter() { - return traceComponent.getTraceExporter(); + return traceComponent.getExportComponent(); } /** diff --git a/api/src/main/java/io/opencensus/trace/BinaryPropagationHandler.java b/api/src/main/java/io/opencensus/trace/propagation/BinaryFormat.java similarity index 73% rename from api/src/main/java/io/opencensus/trace/BinaryPropagationHandler.java rename to api/src/main/java/io/opencensus/trace/propagation/BinaryFormat.java index bc86dd7f9e..d34f69f9dd 100644 --- a/api/src/main/java/io/opencensus/trace/BinaryPropagationHandler.java +++ b/api/src/main/java/io/opencensus/trace/propagation/BinaryFormat.java @@ -11,10 +11,11 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.propagation; import static com.google.common.base.Preconditions.checkNotNull; +import io.opencensus.trace.SpanContext; import java.text.ParseException; /** @@ -24,12 +25,11 @@ * *

            {@code
              * private static final Tracer tracer = Tracing.getTracer();
            - * private static final BinaryPropagationHandler binaryPropagationHandler =
            - *     Tracing.getBinaryPropagationHandler();
            + * private static final BinaryFormat binaryFormat =
            + *     Tracing.getPropagationComponent().getBinaryFormat();
              * void onSendRequest() {
              *   try (NonThrowingCloseable ss = tracer.spanBuilder("Sent.MyRequest").startScopedSpan()) {
            - *     byte[] binaryValue = binaryPropagationHandler.toBinaryValue(
            - *         tracer.getCurrentContext().context());
            + *     byte[] binaryValue = binaryFormat.toBinaryValue(tracer.getCurrentContext().context());
              *     // Send the request including the binaryValue and wait for the response.
              *   }
              * }
            @@ -39,14 +39,14 @@
              *
              * 
            {@code
              * private static final Tracer tracer = Tracing.getTracer();
            - * private static final BinaryPropagationHandler binaryPropagationHandler =
            - *     Tracing.getBinaryPropagationHandler();
            + * private static final BinaryFormat binaryFormat =
            + *     Tracing.getPropagationComponent().getBinaryFormat();
              * void onRequestReceived() {
              *   // Get the binaryValue from the request.
              *   SpanContext spanContext = SpanContext.INVALID;
              *   try {
              *     if (binaryValue != null) {
            - *       spanContext = binaryPropagationHandler.fromBinaryValue(binaryValue);
            + *       spanContext = binaryFormat.fromBinaryValue(binaryValue);
              *     }
              *   } catch (ParseException e) {
              *     // Maybe log the exception.
            @@ -58,9 +58,8 @@
              * }
              * }
            */ -public abstract class BinaryPropagationHandler { - static final NoopBinaryPropagationHandler noopBinaryPropagationHandler = - new NoopBinaryPropagationHandler(); +public abstract class BinaryFormat { + static final NoopBinaryFormat NOOP_BINARY_FORMAT = new NoopBinaryFormat(); /** * Serializes a {@link SpanContext} using the binary format. @@ -82,15 +81,15 @@ public abstract class BinaryPropagationHandler { public abstract SpanContext fromBinaryValue(byte[] bytes) throws ParseException; /** - * Returns the no-op implementation of the {@code BinaryPropagationHandler}. + * Returns the no-op implementation of the {@code BinaryFormat}. * - * @return the no-op implementation of the {@code BinaryPropagationHandler}. + * @return the no-op implementation of the {@code BinaryFormat}. */ - static BinaryPropagationHandler getNoopBinaryPropagationHandler() { - return noopBinaryPropagationHandler; + static BinaryFormat getNoopBinaryFormat() { + return NOOP_BINARY_FORMAT; } - private static final class NoopBinaryPropagationHandler extends BinaryPropagationHandler { + private static final class NoopBinaryFormat extends BinaryFormat { @Override public byte[] toBinaryValue(SpanContext spanContext) { checkNotNull(spanContext, "spanContext"); @@ -103,6 +102,6 @@ public SpanContext fromBinaryValue(byte[] bytes) throws ParseException { return SpanContext.INVALID; } - private NoopBinaryPropagationHandler() {} + private NoopBinaryFormat() {} } } diff --git a/api/src/main/java/io/opencensus/trace/propagation/PropagationComponent.java b/api/src/main/java/io/opencensus/trace/propagation/PropagationComponent.java new file mode 100644 index 0000000000..382333e355 --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/propagation/PropagationComponent.java @@ -0,0 +1,47 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.propagation; + +/** + * Container class for all the supported propagation formats. Currently supports only Binary + * format see {@link BinaryFormat} but more formats will be added. + */ +public abstract class PropagationComponent { + private static final PropagationComponent NOOP_PROPAGATION_COMPONENT = + new NoopPropagationComponent(); + + /** + * Returns the {@link BinaryFormat} with the provided implementations. If no implementation + * is provided then no-op implementation will be used. + * + * @return the {@code BinaryFormat} implementation. + */ + public abstract BinaryFormat getBinaryFormat(); + + /** + * Returns an instance that contains no-op implementations for all the instances. + * + * @return an instance that contains no-op implementations for all the instances. + */ + public static PropagationComponent getNoopPropagationComponent() { + return NOOP_PROPAGATION_COMPONENT; + } + + private static final class NoopPropagationComponent extends PropagationComponent { + @Override + public BinaryFormat getBinaryFormat() { + return BinaryFormat.getNoopBinaryFormat(); + } + } +} diff --git a/api/src/test/java/io/opencensus/trace/TraceComponentTest.java b/api/src/test/java/io/opencensus/trace/TraceComponentTest.java index 4a0c35947f..238a8420f5 100644 --- a/api/src/test/java/io/opencensus/trace/TraceComponentTest.java +++ b/api/src/test/java/io/opencensus/trace/TraceComponentTest.java @@ -18,6 +18,7 @@ import io.opencensus.internal.ZeroTimeClock; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.propagation.PropagationComponent; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -32,8 +33,8 @@ public void defaultTracer() { @Test public void defaultBinaryPropagationHandler() { - assertThat(TraceComponent.getNoopTraceComponent().getBinaryPropagationHandler()) - .isSameAs(BinaryPropagationHandler.getNoopBinaryPropagationHandler()); + assertThat(TraceComponent.getNoopTraceComponent().getPropagationComponent()) + .isSameAs(PropagationComponent.getNoopPropagationComponent()); } @Test @@ -43,7 +44,7 @@ public void defaultClock() { @Test public void defaultTraceExporter() { - assertThat(TraceComponent.getNoopTraceComponent().getTraceExporter()) + assertThat(TraceComponent.getNoopTraceComponent().getExportComponent()) .isSameAs(ExportComponent.getNoopExportComponent()); } diff --git a/api/src/test/java/io/opencensus/trace/TracingTest.java b/api/src/test/java/io/opencensus/trace/TracingTest.java index 0076cc77ae..33303896a8 100644 --- a/api/src/test/java/io/opencensus/trace/TracingTest.java +++ b/api/src/test/java/io/opencensus/trace/TracingTest.java @@ -17,6 +17,7 @@ import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.propagation.PropagationComponent; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -64,8 +65,8 @@ public void defaultTracer() { @Test public void defaultBinaryPropagationHandler() { - assertThat(Tracing.getBinaryPropagationHandler()) - .isSameAs(BinaryPropagationHandler.getNoopBinaryPropagationHandler()); + assertThat(Tracing.getPropagationComponent()) + .isSameAs(PropagationComponent.getNoopPropagationComponent()); } @Test diff --git a/api/src/test/java/io/opencensus/trace/BinaryPropagationHandlerTest.java b/api/src/test/java/io/opencensus/trace/propagation/BinaryFormatTest.java similarity index 66% rename from api/src/test/java/io/opencensus/trace/BinaryPropagationHandlerTest.java rename to api/src/test/java/io/opencensus/trace/propagation/BinaryFormatTest.java index d75effb695..b5994ba0be 100644 --- a/api/src/test/java/io/opencensus/trace/BinaryPropagationHandlerTest.java +++ b/api/src/test/java/io/opencensus/trace/propagation/BinaryFormatTest.java @@ -11,39 +11,39 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.propagation; import static com.google.common.truth.Truth.assertThat; +import io.opencensus.trace.SpanContext; import java.text.ParseException; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@link BinaryPropagationHandler}. */ +/** Unit tests for {@link BinaryFormat}. */ @RunWith(JUnit4.class) -public class BinaryPropagationHandlerTest { - private static final BinaryPropagationHandler binaryPropagationHandler = - BinaryPropagationHandler.getNoopBinaryPropagationHandler(); +public class BinaryFormatTest { + private static final BinaryFormat binaryFormat = + BinaryFormat.getNoopBinaryFormat(); @Test(expected = NullPointerException.class) public void toBinaryValue_NullSpanContext() { - binaryPropagationHandler.toBinaryValue(null); + binaryFormat.toBinaryValue(null); } @Test public void toBinaryValue_NotNullSpanContext() { - assertThat(binaryPropagationHandler.toBinaryValue(SpanContext.INVALID)).isEqualTo(new byte[0]); + assertThat(binaryFormat.toBinaryValue(SpanContext.INVALID)).isEqualTo(new byte[0]); } @Test(expected = NullPointerException.class) public void fromBinaryValue_NullInput() throws ParseException { - binaryPropagationHandler.fromBinaryValue(null); + binaryFormat.fromBinaryValue(null); } @Test public void fromBinaryValue_NotNullInput() throws ParseException { - assertThat(binaryPropagationHandler.fromBinaryValue(new byte[0])) - .isEqualTo(SpanContext.INVALID); + assertThat(binaryFormat.fromBinaryValue(new byte[0])).isEqualTo(SpanContext.INVALID); } } diff --git a/api/src/test/java/io/opencensus/trace/propagation/PropagationComponentTest.java b/api/src/test/java/io/opencensus/trace/propagation/PropagationComponentTest.java new file mode 100644 index 0000000000..24baee6928 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/propagation/PropagationComponentTest.java @@ -0,0 +1,33 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.propagation; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link PropagationComponent}. */ +@RunWith(JUnit4.class) +public class PropagationComponentTest { + private final PropagationComponent propagationComponent = + PropagationComponent.getNoopPropagationComponent(); + + @Test + public void implementationOfBinary() { + assertThat(propagationComponent.getBinaryFormat()) + .isEqualTo(BinaryFormat.getNoopBinaryFormat()); + } +} diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/BinaryPropagationHandlerImplBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java similarity index 74% rename from benchmarks/src/jmh/java/io/opencensus/trace/BinaryPropagationHandlerImplBenchmark.java rename to benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java index 8a0ff0169b..4a49b9c891 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/BinaryPropagationHandlerImplBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java @@ -11,8 +11,9 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.propagation; +import io.opencensus.trace.SpanContext; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; @@ -25,9 +26,9 @@ import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; -/** Benchmarks for {@link BinaryPropagationHandlerImpl}. */ +/** Benchmarks for {@link BinaryFormatImpl}. */ @State(Scope.Benchmark) -public class BinaryPropagationHandlerImplBenchmark { +public class BinaryPropagationImplBenchmark { private static final byte[] traceIdBytes = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'a'}; private static final TraceId traceId = TraceId.fromBytes(traceIdBytes); @@ -36,43 +37,42 @@ public class BinaryPropagationHandlerImplBenchmark { private static final byte[] traceOptionsBytes = new byte[] {1}; private static final TraceOptions traceOptions = TraceOptions.fromBytes(traceOptionsBytes); private static final SpanContext spanContext = SpanContext.create(traceId, spanId, traceOptions); - private static final BinaryPropagationHandler binaryPropagationHandler = - new BinaryPropagationHandlerImpl(); + private static final BinaryFormat BINARY_PROPAGATION = new BinaryFormatImpl(); private static final byte[] spanContextBinary = - binaryPropagationHandler.toBinaryValue(spanContext); + BINARY_PROPAGATION.toBinaryValue(spanContext); /** * This benchmark attempts to measure performance of {@link - * BinaryPropagationHandlerImpl#toBinaryValue(SpanContext)}. + * BinaryFormatImpl#toBinaryValue(SpanContext)}. */ @Benchmark @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public byte[] toBinaryValueSpanContext() { - return binaryPropagationHandler.toBinaryValue(spanContext); + return BINARY_PROPAGATION.toBinaryValue(spanContext); } /** * This benchmark attempts to measure performance of {@link - * BinaryPropagationHandlerImpl#fromBinaryValue(byte[])}. + * BinaryFormatImpl#fromBinaryValue(byte[])}. */ @Benchmark @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public SpanContext fromBinaryValueSpanContext() throws ParseException { - return binaryPropagationHandler.fromBinaryValue(spanContextBinary); + return BINARY_PROPAGATION.fromBinaryValue(spanContextBinary); } /** * This benchmark attempts to measure performance of {@link - * BinaryPropagationHandlerImpl#toBinaryValue(SpanContext)} then {@link - * BinaryPropagationHandlerImpl#fromBinaryValue(byte[])}. + * BinaryFormatImpl#toBinaryValue(SpanContext)} then {@link + * BinaryFormatImpl#fromBinaryValue(byte[])}. */ @Benchmark @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public SpanContext toFromBinarySpanContext() throws ParseException { - return binaryPropagationHandler.fromBinaryValue( - binaryPropagationHandler.toBinaryValue(spanContext)); + return BINARY_PROPAGATION.fromBinaryValue( + BINARY_PROPAGATION.toBinaryValue(spanContext)); } } diff --git a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java index 88eb193102..0b72d6564a 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java @@ -18,12 +18,13 @@ import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.propagation.PropagationComponent; +import io.opencensus.trace.propagation.PropagationComponentImpl; /** Base implementation of the {@link TraceComponent}. */ class TraceComponentImplBase extends TraceComponent { - private final BinaryPropagationHandler binaryPropagationHandler = - new BinaryPropagationHandlerImpl(); - private final ExportComponentImpl traceExporter = new ExportComponentImpl(); + private final ExportComponentImpl exportComponent = new ExportComponentImpl(); + private final PropagationComponent propagationComponent = new PropagationComponentImpl(); private final Clock clock; private final StartEndHandler startEndHandler; private final TraceConfig traceConfig = new TraceConfigImpl(); @@ -31,7 +32,7 @@ class TraceComponentImplBase extends TraceComponent { TraceComponentImplBase(Clock clock, RandomHandler randomHandler, EventQueue eventQueue) { this.clock = clock; - startEndHandler = new StartEndHandlerImpl(traceExporter.getSpanExporter(), eventQueue); + startEndHandler = new StartEndHandlerImpl(exportComponent.getSpanExporter(), eventQueue); tracer = new TracerImpl(randomHandler, startEndHandler, clock, traceConfig); } @@ -41,8 +42,8 @@ public Tracer getTracer() { } @Override - public BinaryPropagationHandler getBinaryPropagationHandler() { - return binaryPropagationHandler; + public PropagationComponent getPropagationComponent() { + return propagationComponent; } @Override @@ -51,8 +52,8 @@ public final Clock getClock() { } @Override - public ExportComponent getTraceExporter() { - return traceExporter; + public ExportComponent getExportComponent() { + return exportComponent; } @Override diff --git a/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java b/core_impl/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java similarity index 95% rename from core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java rename to core_impl/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java index 6359bc40cc..890d5821ea 100644 --- a/core_impl/src/main/java/io/opencensus/trace/BinaryPropagationHandlerImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java @@ -11,19 +11,20 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.propagation; import static com.google.common.base.Preconditions.checkNotNull; +import io.opencensus.trace.SpanContext; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; import java.text.ParseException; /** - * Implementation of the {@link BinaryPropagationHandler}. + * Implementation of the {@link BinaryFormat}. * - *

            Binary format: + *

            BinaryFormat format: * *

              *
            • Binary value: <version_id><version_format> @@ -54,7 +55,7 @@ *
            * */ -final class BinaryPropagationHandlerImpl extends BinaryPropagationHandler { +final class BinaryFormatImpl extends BinaryFormat { private static final byte VERSION_ID = 0; private static final int VERSION_ID_OFFSET = 0; // The version_id/field_id size in bytes. @@ -71,7 +72,7 @@ final class BinaryPropagationHandlerImpl extends BinaryPropagationHandler { private static final int FORMAT_LENGTH = 4 * ID_SIZE + TraceId.SIZE + SpanId.SIZE + TraceOptions.SIZE; - BinaryPropagationHandlerImpl() {} + BinaryFormatImpl() {} @Override public byte[] toBinaryValue(SpanContext spanContext) { diff --git a/core_impl/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java b/core_impl/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java new file mode 100644 index 0000000000..144a563989 --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java @@ -0,0 +1,24 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.propagation; + +/** Implementation of the {@link PropagationComponent}. */ +public class PropagationComponentImpl extends PropagationComponent { + private final BinaryFormat binaryFormat = new BinaryFormatImpl(); + + @Override + public BinaryFormat getBinaryFormat() { + return binaryFormat; + } +} diff --git a/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java b/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java index cbcac487ba..1be7b97a08 100644 --- a/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java @@ -18,6 +18,7 @@ import io.opencensus.common.MillisClock; import io.opencensus.common.SimpleEventQueue; import io.opencensus.trace.RandomHandler.SecureRandomHandler; +import io.opencensus.trace.propagation.PropagationComponentImpl; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -36,8 +37,8 @@ public void implementationOfTracer() { @Test public void implementationOfBinaryPropagationHandler() { - assertThat(traceComponent.getBinaryPropagationHandler()) - .isInstanceOf(BinaryPropagationHandlerImpl.class); + assertThat(traceComponent.getPropagationComponent()) + .isInstanceOf(PropagationComponentImpl.class); } @Test @@ -47,6 +48,6 @@ public void implementationOfClock() { @Test public void implementationOfTraceExporter() { - assertThat(traceComponent.getTraceExporter()).isInstanceOf(ExportComponentImpl.class); + assertThat(traceComponent.getExportComponent()).isInstanceOf(ExportComponentImpl.class); } } diff --git a/core_impl/src/test/java/io/opencensus/trace/BinaryPropagationHandlerImplTest.java b/core_impl/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java similarity index 82% rename from core_impl/src/test/java/io/opencensus/trace/BinaryPropagationHandlerImplTest.java rename to core_impl/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java index 6137f95239..6bc75578d3 100644 --- a/core_impl/src/test/java/io/opencensus/trace/BinaryPropagationHandlerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java @@ -11,11 +11,12 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.propagation; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import io.opencensus.trace.SpanContext; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; @@ -26,9 +27,9 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@link BinaryPropagationHandlerImpl}. */ +/** Unit tests for {@link BinaryFormatImpl}. */ @RunWith(JUnit4.class) -public class BinaryPropagationHandlerImplTest { +public class BinaryFormatImplTest { private static final byte[] TRACE_ID_BYTES = new byte[] {64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79}; private static final TraceId TRACE_ID = TraceId.fromBytes(TRACE_ID_BYTES); @@ -44,15 +45,13 @@ public class BinaryPropagationHandlerImplTest { private static final SpanContext EXAMPLE_SPAN_CONTEXT = SpanContext.create(TRACE_ID, SPAN_ID, TRACE_OPTIONS); @Rule public ExpectedException expectedException = ExpectedException.none(); - private final BinaryPropagationHandler binaryPropagationHandler = - new BinaryPropagationHandlerImpl(); + private final BinaryFormat binaryFormat = new BinaryFormatImpl(); private void testSpanContextConversion(SpanContext spanContext) throws ParseException { SpanContext propagatedBinarySpanContext = - binaryPropagationHandler.fromBinaryValue( - binaryPropagationHandler.toBinaryValue(spanContext)); + binaryFormat.fromBinaryValue(binaryFormat.toBinaryValue(spanContext)); - assertWithMessage("Binary propagated context is not equal with the initial context.") + assertWithMessage("BinaryFormat propagated context is not equal with the initial context.") .that(propagatedBinarySpanContext) .isEqualTo(spanContext); } @@ -70,12 +69,12 @@ public void propagate_SpanContextNoTracing() throws ParseException { @Test(expected = NullPointerException.class) public void toBinaryValue_NullSpanContext() { - binaryPropagationHandler.toBinaryValue(null); + binaryFormat.toBinaryValue(null); } @Test public void toBinaryValue_InvalidSpanContext() { - assertThat(binaryPropagationHandler.toBinaryValue(SpanContext.INVALID)) + assertThat(binaryFormat.toBinaryValue(SpanContext.INVALID)) .isEqualTo( new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0 @@ -84,27 +83,26 @@ public void toBinaryValue_InvalidSpanContext() { @Test public void fromBinaryValue_BinaryExampleValue() throws ParseException { - assertThat(binaryPropagationHandler.fromBinaryValue(EXAMPLE_BYTES)) - .isEqualTo(EXAMPLE_SPAN_CONTEXT); + assertThat(binaryFormat.fromBinaryValue(EXAMPLE_BYTES)).isEqualTo(EXAMPLE_SPAN_CONTEXT); } @Test(expected = NullPointerException.class) public void fromBinaryValue_NullInput() throws ParseException { - binaryPropagationHandler.fromBinaryValue(null); + binaryFormat.fromBinaryValue(null); } @Test public void fromBinaryValue_EmptyInput() throws ParseException { expectedException.expect(ParseException.class); expectedException.expectMessage("Unsupported version."); - binaryPropagationHandler.fromBinaryValue(new byte[0]); + binaryFormat.fromBinaryValue(new byte[0]); } @Test public void fromBinaryValue_UnsupportedVersionId() throws ParseException { expectedException.expect(ParseException.class); expectedException.expectMessage("Unsupported version."); - binaryPropagationHandler.fromBinaryValue( + binaryFormat.fromBinaryValue( new byte[] { 66, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 97, 98, 99, 100, 101, 102, 103, 104, 1 @@ -114,7 +112,7 @@ public void fromBinaryValue_UnsupportedVersionId() throws ParseException { @Test public void fromBinaryValue_UnsupportedFieldIdFirst() throws ParseException { assertThat( - binaryPropagationHandler.fromBinaryValue( + binaryFormat.fromBinaryValue( new byte[] { 0, 4, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1, 97, 98, 99, 100, 101, 102, 103, 104, 2, 1 @@ -125,7 +123,7 @@ public void fromBinaryValue_UnsupportedFieldIdFirst() throws ParseException { @Test public void fromBinaryValue_UnsupportedFieldIdSecond() throws ParseException { assertThat( - binaryPropagationHandler.fromBinaryValue( + binaryFormat.fromBinaryValue( new byte[] { 0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 3, 97, 98, 99, 100, 101, 102, 103, 104, 2, 1 @@ -142,7 +140,7 @@ public void fromBinaryValue_UnsupportedFieldIdSecond() throws ParseException { public void fromBinaryValue_ShorterTraceId() throws ParseException { expectedException.expect(ParseException.class); expectedException.expectMessage("Invalid input: java.lang.ArrayIndexOutOfBoundsException"); - binaryPropagationHandler.fromBinaryValue( + binaryFormat.fromBinaryValue( new byte[] {0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76}); } @@ -150,14 +148,14 @@ public void fromBinaryValue_ShorterTraceId() throws ParseException { public void fromBinaryValue_ShorterSpanId() throws ParseException { expectedException.expect(ParseException.class); expectedException.expectMessage("Invalid input: java.lang.ArrayIndexOutOfBoundsException"); - binaryPropagationHandler.fromBinaryValue(new byte[] {0, 1, 97, 98, 99, 100, 101, 102, 103}); + binaryFormat.fromBinaryValue(new byte[] {0, 1, 97, 98, 99, 100, 101, 102, 103}); } @Test public void fromBinaryValue_ShorterTraceOptions() throws ParseException { expectedException.expect(ParseException.class); expectedException.expectMessage("Invalid input: java.lang.IndexOutOfBoundsException"); - binaryPropagationHandler.fromBinaryValue( + binaryFormat.fromBinaryValue( new byte[] { 0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1, 97, 98, 99, 100, 101, 102, 103, 104, 2 diff --git a/core_impl/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java b/core_impl/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java new file mode 100644 index 0000000000..dd7812ab07 --- /dev/null +++ b/core_impl/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java @@ -0,0 +1,32 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.propagation; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link PropagationComponentImpl}. */ +@RunWith(JUnit4.class) +public class PropagationComponentImplTest { + private final PropagationComponent propagationComponent = new PropagationComponentImpl(); + + @Test + public void implementationOfBinary() { + assertThat(propagationComponent.getBinaryFormat()) + .isInstanceOf(BinaryFormatImpl.class); + } +} diff --git a/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java b/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java index b8393ec46d..2ae4ad9461 100644 --- a/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java +++ b/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java @@ -16,6 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.MillisClock; +import io.opencensus.trace.propagation.PropagationComponentImpl; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -30,8 +31,8 @@ public void implementationOfTracer() { @Test public void implementationOfBinaryPropagationHandler() { - assertThat(Tracing.getBinaryPropagationHandler()) - .isInstanceOf(BinaryPropagationHandlerImpl.class); + assertThat(Tracing.getPropagationComponent()) + .isInstanceOf(PropagationComponentImpl.class); } @Test diff --git a/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java b/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java index 85db9898bd..909eca9b98 100644 --- a/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java +++ b/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java @@ -16,6 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.MillisClock; +import io.opencensus.trace.propagation.PropagationComponent; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -30,8 +31,8 @@ public void implementationOfTracer() { @Test public void implementationOfBinaryPropagationHandler() { - assertThat(Tracing.getBinaryPropagationHandler()) - .isInstanceOf(BinaryPropagationHandlerImpl.class); + assertThat(Tracing.getPropagationComponent()) + .isInstanceOf(PropagationComponent.class); } @Test From f27ee518014266152c87b87695964d6dfa54c7ad Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 8 Jun 2017 17:38:43 -0700 Subject: [PATCH 0159/1581] Cleanup in config package. (#346) * Remove unimplemented method from TraceConfig. * Move config implementations to config package. * Add tests for NoopTraceConfig. --- .../opencensus/trace/config/TraceConfig.java | 11 ----- .../trace/config/TraceConfigTest.java | 47 +++++++++++++++++++ .../trace/{ => config}/TraceParamsTest.java | 4 +- .../trace/TraceComponentImplBase.java | 1 + .../trace/{ => config}/TraceConfigImpl.java | 19 ++++---- .../{ => config}/TraceConfigImplTest.java | 4 +- 6 files changed, 61 insertions(+), 25 deletions(-) create mode 100644 api/src/test/java/io/opencensus/trace/config/TraceConfigTest.java rename api/src/test/java/io/opencensus/trace/{ => config}/TraceParamsTest.java (97%) rename core_impl/src/main/java/io/opencensus/trace/{ => config}/TraceConfigImpl.java (74%) rename core_impl/src/test/java/io/opencensus/trace/{ => config}/TraceConfigImplTest.java (95%) diff --git a/api/src/main/java/io/opencensus/trace/config/TraceConfig.java b/api/src/main/java/io/opencensus/trace/config/TraceConfig.java index 80f206c951..01cb6d04dc 100644 --- a/api/src/main/java/io/opencensus/trace/config/TraceConfig.java +++ b/api/src/main/java/io/opencensus/trace/config/TraceConfig.java @@ -34,14 +34,6 @@ public abstract class TraceConfig { */ public abstract void updateActiveTraceParams(TraceParams traceParams); - /** - * Temporary updates the active {@link TraceParams} for {@code durationNs} nanoseconds. - * - * @param traceParams the new active {@code TraceParams}. - * @param durationNs the duration for how long the new params will be active. - */ - public abstract void temporaryUpdateActiveTraceParams(TraceParams traceParams, long durationNs); - /** * Returns the no-op implementation of the {@code TraceConfig}. * @@ -60,8 +52,5 @@ public TraceParams getActiveTraceParams() { @Override public void updateActiveTraceParams(TraceParams traceParams) {} - - @Override - public void temporaryUpdateActiveTraceParams(TraceParams traceParams, long durationNs) {} } } diff --git a/api/src/test/java/io/opencensus/trace/config/TraceConfigTest.java b/api/src/test/java/io/opencensus/trace/config/TraceConfigTest.java new file mode 100644 index 0000000000..2bf9356d34 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/config/TraceConfigTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.config; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.trace.Samplers; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TraceConfig}. */ +@RunWith(JUnit4.class) +public class TraceConfigTest { + TraceConfig traceConfig = TraceConfig.getNoopTraceConfig(); + + @Test + public void activeTraceParams_NoOpImplementation() { + assertThat(traceConfig.getActiveTraceParams()).isEqualTo(TraceParams.DEFAULT); + } + + @Test + public void updateActiveTraceParams_NoOpImplementation() { + TraceParams traceParams = + TraceParams.DEFAULT + .toBuilder() + .setSampler(Samplers.alwaysSample()) + .setMaxNumberOfAttributes(8) + .setMaxNumberOfAnnotations(9) + .setMaxNumberOfNetworkEvents(10) + .setMaxNumberOfLinks(11) + .build(); + traceConfig.updateActiveTraceParams(traceParams); + assertThat(traceConfig.getActiveTraceParams()).isEqualTo(TraceParams.DEFAULT); + } +} diff --git a/api/src/test/java/io/opencensus/trace/TraceParamsTest.java b/api/src/test/java/io/opencensus/trace/config/TraceParamsTest.java similarity index 97% rename from api/src/test/java/io/opencensus/trace/TraceParamsTest.java rename to api/src/test/java/io/opencensus/trace/config/TraceParamsTest.java index e21485e151..76d828a9ea 100644 --- a/api/src/test/java/io/opencensus/trace/TraceParamsTest.java +++ b/api/src/test/java/io/opencensus/trace/config/TraceParamsTest.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.config; import static com.google.common.truth.Truth.assertThat; -import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.Samplers; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java index 0b72d6564a..6cb1f912e7 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java @@ -17,6 +17,7 @@ import io.opencensus.common.EventQueue; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.config.TraceConfigImpl; import io.opencensus.trace.export.ExportComponent; import io.opencensus.trace.propagation.PropagationComponent; import io.opencensus.trace.propagation.PropagationComponentImpl; diff --git a/core_impl/src/main/java/io/opencensus/trace/TraceConfigImpl.java b/core_impl/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java similarity index 74% rename from core_impl/src/main/java/io/opencensus/trace/TraceConfigImpl.java rename to core_impl/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java index 673c4c8a2d..cf3dc59ee2 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TraceConfigImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java @@ -11,18 +11,22 @@ * limitations under the License. */ -package io.opencensus.trace; - -import io.opencensus.trace.config.TraceConfig; -import io.opencensus.trace.config.TraceParams; +package io.opencensus.trace.config; /** * Global configuration of the trace service. This allows users to change configs for the default * sampler, maximum events to be kept, etc. */ -final class TraceConfigImpl extends TraceConfig { +public final class TraceConfigImpl extends TraceConfig { + // Reads and writes are atomic for reference variables. Use volatile to ensure that these + // operations are visible on other CPUs as well. private volatile TraceParams activeTraceParams = TraceParams.DEFAULT; + /** + * Constructs a new {@code TraceConfigImpl}. + */ + public TraceConfigImpl() {} + @Override public TraceParams getActiveTraceParams() { return activeTraceParams; @@ -32,9 +36,4 @@ public TraceParams getActiveTraceParams() { public void updateActiveTraceParams(TraceParams traceParams) { activeTraceParams = traceParams; } - - @Override - public void temporaryUpdateActiveTraceParams(TraceParams traceParams, long durationNs) { - throw new UnsupportedOperationException("Not supported yet."); - } } diff --git a/core_impl/src/test/java/io/opencensus/trace/TraceConfigImplTest.java b/core_impl/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java similarity index 95% rename from core_impl/src/test/java/io/opencensus/trace/TraceConfigImplTest.java rename to core_impl/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java index 9872dd61dd..24e78b2b94 100644 --- a/core_impl/src/test/java/io/opencensus/trace/TraceConfigImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.config; import static com.google.common.truth.Truth.assertThat; -import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.Samplers; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; From beebb4e7b8948e9f5a7fb72d87538166980173c9 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 8 Jun 2017 17:59:00 -0700 Subject: [PATCH 0160/1581] Move more classes into internal packages to be clearer that they are internal. (#348) * Move EventQueue and implementations to internal package. Move TimestampConverter to internal implementation. Move RandomHandler to trace/internal. --- .../instrumentation/stats/StatsManagerImplBase.java | 2 +- .../google/instrumentation/stats/ViewManager.java | 2 +- .../opencensus/{common => internal}/EventQueue.java | 2 +- .../{common => internal}/SimpleEventQueue.java | 2 +- .../{trace => internal}/TimestampConverter.java | 8 ++++---- .../java/io/opencensus/internal/package-info.java | 2 +- .../io/opencensus/trace/ExportComponentImpl.java | 2 +- .../java/io/opencensus/trace/SpanFactoryImpl.java | 2 ++ .../src/main/java/io/opencensus/trace/SpanImpl.java | 1 + .../io/opencensus/trace/StartEndHandlerImpl.java | 2 +- .../io/opencensus/trace/TraceComponentImplBase.java | 3 ++- .../main/java/io/opencensus/trace/TracerImpl.java | 1 + .../trace/{ => internal}/RandomHandler.java | 12 ++++++------ .../stats/StatsContextFactoryTest.java | 2 +- .../instrumentation/stats/StatsContextTest.java | 2 +- .../instrumentation/stats/StatsManagerImplTest.java | 2 +- .../{trace => internal}/TimestampConverterTest.java | 2 +- .../io/opencensus/trace/SpanExporterImplTest.java | 2 +- .../io/opencensus/trace/SpanFactoryImplTest.java | 3 ++- .../test/java/io/opencensus/trace/SpanImplTest.java | 1 + .../trace/TraceComponentImplBaseTest.java | 4 ++-- .../instrumentation/stats/StatsManagerImpl.java | 2 +- .../io/opencensus/trace/TraceComponentImpl.java | 4 ++-- .../instrumentation/stats/StatsManagerImpl.java | 2 +- .../{common => internal}/DisruptorEventQueue.java | 2 +- .../io/opencensus/trace/TraceComponentImpl.java | 3 ++- .../{ => internal}/ThreadLocalRandomHandler.java | 13 +++++++++---- .../DisruptorEventQueueTest.java | 2 +- 28 files changed, 50 insertions(+), 37 deletions(-) rename core_impl/src/main/java/io/opencensus/{common => internal}/EventQueue.java (97%) rename core_impl/src/main/java/io/opencensus/{common => internal}/SimpleEventQueue.java (96%) rename core_impl/src/main/java/io/opencensus/{trace => internal}/TimestampConverter.java (89%) rename core_impl/src/main/java/io/opencensus/trace/{ => internal}/RandomHandler.java (81%) rename core_impl/src/test/java/io/opencensus/{trace => internal}/TimestampConverterTest.java (98%) rename core_impl_java/src/main/java/io/opencensus/{common => internal}/DisruptorEventQueue.java (99%) rename core_impl_java/src/main/java/io/opencensus/trace/{ => internal}/ThreadLocalRandomHandler.java (74%) rename core_impl_java/src/test/java/io/opencensus/{common => internal}/DisruptorEventQueueTest.java (98%) diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java index 746ce8731b..76a84fcdab 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java @@ -14,7 +14,7 @@ package com.google.instrumentation.stats; import io.opencensus.common.Clock; -import io.opencensus.common.EventQueue; +import io.opencensus.internal.EventQueue; /** * Base implementation of {@link StatsManager}. diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java index dc74a18593..f69a688016 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java +++ b/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java @@ -15,7 +15,7 @@ import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.common.Clock; -import io.opencensus.common.EventQueue; +import io.opencensus.internal.EventQueue; /** Object that stores all views and stats. */ final class ViewManager { diff --git a/core_impl/src/main/java/io/opencensus/common/EventQueue.java b/core_impl/src/main/java/io/opencensus/internal/EventQueue.java similarity index 97% rename from core_impl/src/main/java/io/opencensus/common/EventQueue.java rename to core_impl/src/main/java/io/opencensus/internal/EventQueue.java index 6026d1049b..d038e3d446 100644 --- a/core_impl/src/main/java/io/opencensus/common/EventQueue.java +++ b/core_impl/src/main/java/io/opencensus/internal/EventQueue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.common; +package io.opencensus.internal; /** A queue that processes events. See {@code DisruptorEventQueue} for an example. */ public interface EventQueue { diff --git a/core_impl/src/main/java/io/opencensus/common/SimpleEventQueue.java b/core_impl/src/main/java/io/opencensus/internal/SimpleEventQueue.java similarity index 96% rename from core_impl/src/main/java/io/opencensus/common/SimpleEventQueue.java rename to core_impl/src/main/java/io/opencensus/internal/SimpleEventQueue.java index b39a2590ff..380e51d6cb 100644 --- a/core_impl/src/main/java/io/opencensus/common/SimpleEventQueue.java +++ b/core_impl/src/main/java/io/opencensus/internal/SimpleEventQueue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.common; +package io.opencensus.internal; /** * An {@link EventQueue} that processes events in the current thread. This class can be used for diff --git a/core_impl/src/main/java/io/opencensus/trace/TimestampConverter.java b/core_impl/src/main/java/io/opencensus/internal/TimestampConverter.java similarity index 89% rename from core_impl/src/main/java/io/opencensus/trace/TimestampConverter.java rename to core_impl/src/main/java/io/opencensus/internal/TimestampConverter.java index 2e8982ac43..1bf258c9b2 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TimestampConverter.java +++ b/core_impl/src/main/java/io/opencensus/internal/TimestampConverter.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.internal; import io.opencensus.common.Clock; import io.opencensus.common.Timestamp; @@ -22,12 +22,12 @@ * {@link Timestamp}. */ @Immutable -final class TimestampConverter { +public final class TimestampConverter { private final Timestamp timestamp; private final long nanoTime; // Returns a WallTimeConverter initialized to now. - static TimestampConverter now(Clock clock) { + public static TimestampConverter now(Clock clock) { return new TimestampConverter(clock.now(), clock.nowNanos()); } @@ -37,7 +37,7 @@ static TimestampConverter now(Clock clock) { * @param nanoTime value to convert. * @return the {@code Timestamp} representation of the {@code time}. */ - Timestamp convertNanoTime(long nanoTime) { + public Timestamp convertNanoTime(long nanoTime) { return timestamp.addNanos(nanoTime - this.nanoTime); } diff --git a/core_impl/src/main/java/io/opencensus/internal/package-info.java b/core_impl/src/main/java/io/opencensus/internal/package-info.java index 5fe0010d41..a9f9486497 100644 --- a/core_impl/src/main/java/io/opencensus/internal/package-info.java +++ b/core_impl/src/main/java/io/opencensus/internal/package-info.java @@ -12,7 +12,7 @@ */ /** - * Interfaces and implementations that are internal to opencensus. + * Interfaces and implementations that are internal to OpenCensus. * *

            All the content under this package and its subpackages are considered annotated with {@link * io.opencensus.common.Internal}. diff --git a/core_impl/src/main/java/io/opencensus/trace/ExportComponentImpl.java b/core_impl/src/main/java/io/opencensus/trace/ExportComponentImpl.java index 168acbba5c..c695243f46 100644 --- a/core_impl/src/main/java/io/opencensus/trace/ExportComponentImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/ExportComponentImpl.java @@ -13,7 +13,7 @@ package io.opencensus.trace; -import io.opencensus.common.EventQueue; +import io.opencensus.internal.EventQueue; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.export.ExportComponent; import io.opencensus.trace.export.InProcessDebuggingHandler; diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java index de21507d56..bf370a24f5 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java @@ -16,6 +16,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import io.opencensus.common.Clock; +import io.opencensus.internal.TimestampConverter; import io.opencensus.trace.Span.Options; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.Link.Type; @@ -24,6 +25,7 @@ import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.internal.RandomHandler; import java.util.EnumSet; import java.util.List; import java.util.Random; diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java index 53e897b7bc..a69458e501 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java @@ -18,6 +18,7 @@ import com.google.common.collect.EvictingQueue; import io.opencensus.common.Clock; +import io.opencensus.internal.TimestampConverter; import io.opencensus.trace.SpanData.TimedEvent; import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.AttributeValue; diff --git a/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java b/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java index 8360f69838..c00b463bbe 100644 --- a/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java @@ -13,7 +13,7 @@ package io.opencensus.trace; -import io.opencensus.common.EventQueue; +import io.opencensus.internal.EventQueue; import io.opencensus.trace.SpanImpl.StartEndHandler; /** diff --git a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java index 6cb1f912e7..289d087716 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java @@ -14,11 +14,12 @@ package io.opencensus.trace; import io.opencensus.common.Clock; -import io.opencensus.common.EventQueue; +import io.opencensus.internal.EventQueue; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceConfigImpl; import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.internal.RandomHandler; import io.opencensus.trace.propagation.PropagationComponent; import io.opencensus.trace.propagation.PropagationComponentImpl; diff --git a/core_impl/src/main/java/io/opencensus/trace/TracerImpl.java b/core_impl/src/main/java/io/opencensus/trace/TracerImpl.java index 7b550cc158..f753a8473a 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TracerImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/TracerImpl.java @@ -15,6 +15,7 @@ import io.opencensus.common.Clock; import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.internal.RandomHandler; /** Implementation of the {@link Tracer}. */ final class TracerImpl extends Tracer { diff --git a/core_impl/src/main/java/io/opencensus/trace/RandomHandler.java b/core_impl/src/main/java/io/opencensus/trace/internal/RandomHandler.java similarity index 81% rename from core_impl/src/main/java/io/opencensus/trace/RandomHandler.java rename to core_impl/src/main/java/io/opencensus/trace/internal/RandomHandler.java index b687881d73..8d4060a90f 100644 --- a/core_impl/src/main/java/io/opencensus/trace/RandomHandler.java +++ b/core_impl/src/main/java/io/opencensus/trace/internal/RandomHandler.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.internal; import java.security.SecureRandom; import java.util.Random; @@ -23,22 +23,22 @@ *

            Implementation can have a per thread instance or a single global instance. */ @ThreadSafe -abstract class RandomHandler { +public abstract class RandomHandler { /** * Returns the current {@link Random}. * * @return the current {@code Random}. */ - abstract Random current(); + public abstract Random current(); @ThreadSafe - static final class SecureRandomHandler extends RandomHandler { + public static final class SecureRandomHandler extends RandomHandler { private final Random random = new SecureRandom(); - SecureRandomHandler() {} + public SecureRandomHandler() {} @Override - Random current() { + public Random current() { return random; } } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java index 72d880f687..1bc7cfd3c5 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java @@ -16,7 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.common.SimpleEventQueue; +import io.opencensus.internal.SimpleEventQueue; import io.opencensus.internal.TestClock; import io.opencensus.internal.VarInt; import io.grpc.Context; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java index 9b68f942f6..783506ba36 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java @@ -19,7 +19,7 @@ import com.google.common.collect.Collections2; import com.google.common.testing.EqualsTester; import io.opencensus.common.Function; -import io.opencensus.common.SimpleEventQueue; +import io.opencensus.internal.SimpleEventQueue; import io.opencensus.internal.TestClock; import io.opencensus.internal.VarInt; import com.google.instrumentation.stats.View.DistributionView; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index bdd98ca170..a5f74211fd 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -17,7 +17,7 @@ import static com.google.instrumentation.stats.StatsTestUtil.createContext; import io.opencensus.common.Duration; -import io.opencensus.common.SimpleEventQueue; +import io.opencensus.internal.SimpleEventQueue; import io.opencensus.common.Timestamp; import io.opencensus.internal.TestClock; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; diff --git a/core_impl/src/test/java/io/opencensus/trace/TimestampConverterTest.java b/core_impl/src/test/java/io/opencensus/internal/TimestampConverterTest.java similarity index 98% rename from core_impl/src/test/java/io/opencensus/trace/TimestampConverterTest.java rename to core_impl/src/test/java/io/opencensus/internal/TimestampConverterTest.java index e6f48a9ff2..2fd9612e5d 100644 --- a/core_impl/src/test/java/io/opencensus/trace/TimestampConverterTest.java +++ b/core_impl/src/test/java/io/opencensus/internal/TimestampConverterTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.internal; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java index 9ffff353fe..bc514d4bad 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java @@ -18,7 +18,7 @@ import static org.mockito.Mockito.doThrow; import io.opencensus.common.MillisClock; -import io.opencensus.common.SimpleEventQueue; +import io.opencensus.internal.SimpleEventQueue; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.base.SpanId; diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java index 89937321e5..4e718cf836 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java @@ -24,6 +24,7 @@ import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.internal.RandomHandler; import java.util.Random; import org.junit.Before; import org.junit.Test; @@ -165,7 +166,7 @@ private static final class FakeRandomHandler extends RandomHandler { } @Override - Random current() { + public Random current() { return random; } } diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java index 6e81eb6dc7..7c39d7e138 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java @@ -18,6 +18,7 @@ import io.opencensus.common.Duration; import io.opencensus.common.Timestamp; import io.opencensus.internal.TestClock; +import io.opencensus.internal.TimestampConverter; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.base.Annotation; diff --git a/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java b/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java index 1be7b97a08..442efcc866 100644 --- a/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java @@ -16,8 +16,8 @@ import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.MillisClock; -import io.opencensus.common.SimpleEventQueue; -import io.opencensus.trace.RandomHandler.SecureRandomHandler; +import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.trace.internal.RandomHandler.SecureRandomHandler; import io.opencensus.trace.propagation.PropagationComponentImpl; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java index af0214d1a3..da09d3bc50 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -14,7 +14,7 @@ package com.google.instrumentation.stats; import io.opencensus.common.MillisClock; -import io.opencensus.common.SimpleEventQueue; +import io.opencensus.internal.SimpleEventQueue; /** * Android-compatible implementation of {@link StatsManager}. diff --git a/core_impl_android/src/main/java/io/opencensus/trace/TraceComponentImpl.java b/core_impl_android/src/main/java/io/opencensus/trace/TraceComponentImpl.java index b4e2e49ecc..ca8065085f 100644 --- a/core_impl_android/src/main/java/io/opencensus/trace/TraceComponentImpl.java +++ b/core_impl_android/src/main/java/io/opencensus/trace/TraceComponentImpl.java @@ -14,8 +14,8 @@ package io.opencensus.trace; import io.opencensus.common.MillisClock; -import io.opencensus.common.SimpleEventQueue; -import io.opencensus.trace.RandomHandler.SecureRandomHandler; +import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.trace.internal.RandomHandler.SecureRandomHandler; /** Android-compatible implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplBase { diff --git a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java index 53650a9603..913a1ef959 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java @@ -13,8 +13,8 @@ package com.google.instrumentation.stats; -import io.opencensus.common.DisruptorEventQueue; import io.opencensus.common.MillisClock; +import io.opencensus.internal.DisruptorEventQueue; /** Java 7 and 8 implementation of {@link StatsManager}. */ public final class StatsManagerImpl extends StatsManagerImplBase { diff --git a/core_impl_java/src/main/java/io/opencensus/common/DisruptorEventQueue.java b/core_impl_java/src/main/java/io/opencensus/internal/DisruptorEventQueue.java similarity index 99% rename from core_impl_java/src/main/java/io/opencensus/common/DisruptorEventQueue.java rename to core_impl_java/src/main/java/io/opencensus/internal/DisruptorEventQueue.java index 4c9c0c6239..6360fe0e31 100644 --- a/core_impl_java/src/main/java/io/opencensus/common/DisruptorEventQueue.java +++ b/core_impl_java/src/main/java/io/opencensus/internal/DisruptorEventQueue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.common; +package io.opencensus.internal; import com.lmax.disruptor.EventFactory; import com.lmax.disruptor.EventHandler; diff --git a/core_impl_java/src/main/java/io/opencensus/trace/TraceComponentImpl.java b/core_impl_java/src/main/java/io/opencensus/trace/TraceComponentImpl.java index 4aecbbc6ca..5d0700bde9 100644 --- a/core_impl_java/src/main/java/io/opencensus/trace/TraceComponentImpl.java +++ b/core_impl_java/src/main/java/io/opencensus/trace/TraceComponentImpl.java @@ -13,8 +13,9 @@ package io.opencensus.trace; -import io.opencensus.common.DisruptorEventQueue; import io.opencensus.common.MillisClock; +import io.opencensus.internal.DisruptorEventQueue; +import io.opencensus.trace.internal.ThreadLocalRandomHandler; /** Java 7 and 8 implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplBase { diff --git a/core_impl_java/src/main/java/io/opencensus/trace/ThreadLocalRandomHandler.java b/core_impl_java/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java similarity index 74% rename from core_impl_java/src/main/java/io/opencensus/trace/ThreadLocalRandomHandler.java rename to core_impl_java/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java index 156ae08432..7cb9b2f25a 100644 --- a/core_impl_java/src/main/java/io/opencensus/trace/ThreadLocalRandomHandler.java +++ b/core_impl_java/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java @@ -11,19 +11,24 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.internal; +import io.opencensus.trace.internal.RandomHandler; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; import javax.annotation.concurrent.ThreadSafe; /** Implementation of the {@link RandomHandler} using {@link ThreadLocalRandom}. */ @ThreadSafe -final class ThreadLocalRandomHandler extends RandomHandler { - ThreadLocalRandomHandler() {} +public final class ThreadLocalRandomHandler extends RandomHandler { + + /** + * Constructs a new {@code ThreadLocalRandomHandler}. + */ + public ThreadLocalRandomHandler() {} @Override - Random current() { + public Random current() { return ThreadLocalRandom.current(); } } diff --git a/core_impl_java/src/test/java/io/opencensus/common/DisruptorEventQueueTest.java b/core_impl_java/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java similarity index 98% rename from core_impl_java/src/test/java/io/opencensus/common/DisruptorEventQueueTest.java rename to core_impl_java/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java index 725b751dcf..83a008472b 100644 --- a/core_impl_java/src/test/java/io/opencensus/common/DisruptorEventQueueTest.java +++ b/core_impl_java/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.common; +package io.opencensus.internal; import static com.google.common.truth.Truth.assertThat; From 453f93217f3561aeb9fc95984274bdc26751fbb7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 9 Jun 2017 08:50:10 -0700 Subject: [PATCH 0161/1581] Temporarily move "tags" package back to "core" directory. The tags API isn't ready to be released, so it should be moved out of the "api" directory. --- {api => core}/src/main/java/io/opencensus/tags/TagKey.java | 0 {api => core}/src/main/java/io/opencensus/tags/TagMap.java | 0 {api => core}/src/test/java/io/opencensus/tags/TagKeyTest.java | 0 {api => core}/src/test/java/io/opencensus/tags/TagMapTest.java | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {api => core}/src/main/java/io/opencensus/tags/TagKey.java (100%) rename {api => core}/src/main/java/io/opencensus/tags/TagMap.java (100%) rename {api => core}/src/test/java/io/opencensus/tags/TagKeyTest.java (100%) rename {api => core}/src/test/java/io/opencensus/tags/TagMapTest.java (100%) diff --git a/api/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java similarity index 100% rename from api/src/main/java/io/opencensus/tags/TagKey.java rename to core/src/main/java/io/opencensus/tags/TagKey.java diff --git a/api/src/main/java/io/opencensus/tags/TagMap.java b/core/src/main/java/io/opencensus/tags/TagMap.java similarity index 100% rename from api/src/main/java/io/opencensus/tags/TagMap.java rename to core/src/main/java/io/opencensus/tags/TagMap.java diff --git a/api/src/test/java/io/opencensus/tags/TagKeyTest.java b/core/src/test/java/io/opencensus/tags/TagKeyTest.java similarity index 100% rename from api/src/test/java/io/opencensus/tags/TagKeyTest.java rename to core/src/test/java/io/opencensus/tags/TagKeyTest.java diff --git a/api/src/test/java/io/opencensus/tags/TagMapTest.java b/core/src/test/java/io/opencensus/tags/TagMapTest.java similarity index 100% rename from api/src/test/java/io/opencensus/tags/TagMapTest.java rename to core/src/test/java/io/opencensus/tags/TagMapTest.java From fe94d4afb9af7f13f351f0c38d794b3596bb8274 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Sat, 10 Jun 2017 13:11:39 -0700 Subject: [PATCH 0162/1581] Move SpanFactory into internal package. No need to be in the public API. (#352) --- api/src/main/java/io/opencensus/trace/SpanBuilder.java | 1 + api/src/main/java/io/opencensus/trace/Tracer.java | 5 +++-- .../io/opencensus/trace/{ => internal}/SpanFactory.java | 9 ++++++--- .../test/java/io/opencensus/trace/SpanBuilderTest.java | 1 + api/src/test/java/io/opencensus/trace/TracerTest.java | 1 + .../main/java/io/opencensus/trace/SpanFactoryImpl.java | 5 +++-- 6 files changed, 15 insertions(+), 7 deletions(-) rename api/src/main/java/io/opencensus/trace/{ => internal}/SpanFactory.java (85%) diff --git a/api/src/main/java/io/opencensus/trace/SpanBuilder.java b/api/src/main/java/io/opencensus/trace/SpanBuilder.java index ec9719fc75..b3ad8a5f70 100644 --- a/api/src/main/java/io/opencensus/trace/SpanBuilder.java +++ b/api/src/main/java/io/opencensus/trace/SpanBuilder.java @@ -15,6 +15,7 @@ import io.opencensus.common.NonThrowingCloseable; import io.opencensus.trace.base.EndSpanOptions; +import io.opencensus.trace.internal.SpanFactory; import java.util.List; import javax.annotation.Nullable; diff --git a/api/src/main/java/io/opencensus/trace/Tracer.java b/api/src/main/java/io/opencensus/trace/Tracer.java index 56c4280d96..64f0ae4995 100644 --- a/api/src/main/java/io/opencensus/trace/Tracer.java +++ b/api/src/main/java/io/opencensus/trace/Tracer.java @@ -16,6 +16,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.internal.SpanFactory; import javax.annotation.Nullable; /** @@ -210,12 +211,12 @@ private NoopTracer() { // No-op implementation of the SpanFactory private static final class NoopSpanFactory extends SpanFactory { @Override - protected Span startSpan(@Nullable Span parent, String name, StartSpanOptions options) { + public Span startSpan(@Nullable Span parent, String name, StartSpanOptions options) { return BlankSpan.INSTANCE; } @Override - protected Span startSpanWithRemoteParent( + public Span startSpanWithRemoteParent( @Nullable SpanContext remoteParent, String name, StartSpanOptions options) { return BlankSpan.INSTANCE; } diff --git a/api/src/main/java/io/opencensus/trace/SpanFactory.java b/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java similarity index 85% rename from api/src/main/java/io/opencensus/trace/SpanFactory.java rename to api/src/main/java/io/opencensus/trace/internal/SpanFactory.java index aca5bd852b..b93ec86591 100644 --- a/api/src/main/java/io/opencensus/trace/SpanFactory.java +++ b/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java @@ -11,8 +11,11 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.internal; +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.StartSpanOptions; import javax.annotation.Nullable; /** Factory class to create and start a {@link Span}. */ @@ -26,7 +29,7 @@ public abstract class SpanFactory { * @param options The options for the start of the {@code Span}. * @return A child {@code Span} that will have the name provided. */ - protected abstract Span startSpan(@Nullable Span parent, String name, StartSpanOptions options); + public abstract Span startSpan(@Nullable Span parent, String name, StartSpanOptions options); /** * Creates and starts a new child {@link Span} (or root if parent is {@code null}), with parent @@ -39,6 +42,6 @@ public abstract class SpanFactory { * @param options The options for the start of the {@code Span}. * @return A child {@code Span} that will have the name provided. */ - protected abstract Span startSpanWithRemoteParent( + public abstract Span startSpanWithRemoteParent( @Nullable SpanContext remoteParent, String name, StartSpanOptions options); } diff --git a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java index e112376870..469fe9bbe8 100644 --- a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java @@ -25,6 +25,7 @@ import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.internal.SpanFactory; import java.util.Arrays; import java.util.List; import java.util.Random; diff --git a/api/src/test/java/io/opencensus/trace/TracerTest.java b/api/src/test/java/io/opencensus/trace/TracerTest.java index ad98483b1f..51b86b636c 100644 --- a/api/src/test/java/io/opencensus/trace/TracerTest.java +++ b/api/src/test/java/io/opencensus/trace/TracerTest.java @@ -26,6 +26,7 @@ import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.internal.SpanFactory; import java.util.Random; import org.junit.Before; import org.junit.Rule; diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java index bf370a24f5..3f087799a5 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java @@ -26,6 +26,7 @@ import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.internal.RandomHandler; +import io.opencensus.trace.internal.SpanFactory; import java.util.EnumSet; import java.util.List; import java.util.Random; @@ -39,7 +40,7 @@ final class SpanFactoryImpl extends SpanFactory { private final TraceConfig traceConfig; @Override - protected Span startSpan(@Nullable Span parent, String name, StartSpanOptions options) { + public Span startSpan(@Nullable Span parent, String name, StartSpanOptions options) { SpanContext parentContext = null; TimestampConverter timestampConverter = null; if (parent != null) { @@ -54,7 +55,7 @@ protected Span startSpan(@Nullable Span parent, String name, StartSpanOptions op } @Override - protected Span startSpanWithRemoteParent( + public Span startSpanWithRemoteParent( @Nullable SpanContext remoteParent, String name, StartSpanOptions options) { return startSpanInternal(remoteParent, true, name, options, null); } From 4bc0242c17cbaa931f30ef031c312c8ee936b6e0 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 12 Jun 2017 13:17:06 -0700 Subject: [PATCH 0163/1581] Move Sampler and StartSpanOptions in base. Create a samplers package for all the Sampler implementations. (#347) --- .../java/io/opencensus/trace/Samplers.java | 168 ------------------ .../main/java/io/opencensus/trace/Span.java | 1 + .../java/io/opencensus/trace/SpanBuilder.java | 2 + .../main/java/io/opencensus/trace/Tracer.java | 1 + .../opencensus/trace/{ => base}/Sampler.java | 9 +- .../trace/{ => base}/StartSpanOptions.java | 5 +- .../opencensus/trace/config/TraceParams.java | 20 +-- .../trace/internal/SpanFactory.java | 2 +- .../trace/samplers/AlwaysSampleSampler.java | 50 ++++++ .../trace/samplers/NeverSampleSampler.java | 50 ++++++ .../trace/samplers/ProbabilitySampler.java | 93 ++++++++++ .../opencensus/trace/samplers/Samplers.java | 55 ++++++ .../io/opencensus/trace/SpanBuilderTest.java | 2 + .../java/io/opencensus/trace/TracerTest.java | 1 + .../{ => base}/StartSpanOptionsTest.java | 5 +- .../trace/config/TraceConfigTest.java | 2 +- .../trace/config/TraceParamsTest.java | 2 +- .../trace/{ => samplers}/SamplersTest.java | 5 +- ...ordTraceEventsNonSampledSpanBenchmark.java | 1 + ...RecordTraceEventsSampledSpanBenchmark.java | 1 + .../trace/StartEndSpanBenchmark.java | 1 + .../io/opencensus/trace/SpanFactoryImpl.java | 2 + .../opencensus/trace/SpanFactoryImplTest.java | 2 + .../trace/config/TraceConfigImplTest.java | 2 +- 24 files changed, 291 insertions(+), 191 deletions(-) delete mode 100644 api/src/main/java/io/opencensus/trace/Samplers.java rename api/src/main/java/io/opencensus/trace/{ => base}/Sampler.java (91%) rename api/src/main/java/io/opencensus/trace/{ => base}/StartSpanOptions.java (96%) create mode 100644 api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java create mode 100644 api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java create mode 100644 api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java create mode 100644 api/src/main/java/io/opencensus/trace/samplers/Samplers.java rename api/src/test/java/io/opencensus/trace/{ => base}/StartSpanOptionsTest.java (96%) rename api/src/test/java/io/opencensus/trace/{ => samplers}/SamplersTest.java (97%) diff --git a/api/src/main/java/io/opencensus/trace/Samplers.java b/api/src/main/java/io/opencensus/trace/Samplers.java deleted file mode 100644 index 8d7908ec9a..0000000000 --- a/api/src/main/java/io/opencensus/trace/Samplers.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.trace; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.auto.value.AutoValue; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import java.util.List; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** Static class to access a set of pre-defined {@link Sampler Samplers}. */ -public final class Samplers { - private static final Sampler ALWAYS_SAMPLE = new AlwaysSampleSampler(); - private static final Sampler NEVER_SAMPLE = new NeverSampleSampler(); - - // No instance of this class. - private Samplers() {} - - /** - * Returns a {@link Sampler} that always makes a "yes" decision on {@link Span} sampling. - * - * @return a {@code Sampler} that always makes a "yes" decision on {@code Span} sampling. - */ - public static Sampler alwaysSample() { - return ALWAYS_SAMPLE; - } - - /** - * Returns a {@link Sampler} that always makes a "no" decision on {@link Span} sampling. - * - * @return a {@code Sampler} that always makes a "no" decision on {@code Span} sampling. - */ - public static Sampler neverSample() { - return NEVER_SAMPLE; - } - - /** - * Returns a {@link Sampler} that makes a "yes" decision with a given probability. - * - * @param probability The desired probability of sampling. Must be within [0.0, 1.0]. - * @return a {@code Sampler} that makes a "yes" decision with a given probability. - * @throws IllegalArgumentException if {@code probability} is out of range - */ - public static Sampler probabilitySampler(double probability) { - return ProbabilitySampler.create(probability); - } - - @Immutable - private static final class AlwaysSampleSampler extends Sampler { - private AlwaysSampleSampler() {} - - // Returns always makes a "yes" decision on {@link Span} sampling. - @Override - protected boolean shouldSample( - @Nullable SpanContext parentContext, - boolean remoteParent, - TraceId traceId, - SpanId spanId, - String name, - List parentLinks) { - return true; - } - - @Override - public String toString() { - return "AlwaysSampleSampler"; - } - } - - @Immutable - private static final class NeverSampleSampler extends Sampler { - private NeverSampleSampler() {} - - // Returns always makes a "no" decision on {@link Span} sampling. - @Override - protected boolean shouldSample( - @Nullable SpanContext parentContext, - boolean remoteParent, - TraceId traceId, - SpanId spanId, - String name, - List parentLinks) { - return false; - } - - @Override - public String toString() { - return "NeverSampleSampler"; - } - } - - // We assume the lower 64 bits of the traceId's are randomly distributed around the whole (long) - // range. We convert an incoming probability into an upper bound on that value, such that we can - // just compare the absolute value of the id and the bound to see if we are within the desired - // probability range. Using the low bits of the traceId also ensures that systems that only use - // 64 bit ID's will also work with this sampler. - @AutoValue - @Immutable - abstract static class ProbabilitySampler extends Sampler { - ProbabilitySampler() {} - - abstract double getProbability(); - - abstract long getIdUpperBound(); - - /** - * Returns a new {@link ProbabilitySampler}. The probability of sampling a trace is equal to - * that of the specified probability. - * - * @param probability The desired probability of sampling. Must be within [0.0, 1.0]. - * @return a new {@link ProbabilitySampler}. - * @throws IllegalArgumentException if {@code probability} is out of range - */ - private static ProbabilitySampler create(double probability) { - checkArgument( - probability >= 0.0 && probability <= 1.0, "probability must be in range [0.0, 1.0]"); - long idUpperBound = 0; - // Special case the limits, to avoid any possible issues with lack of precision across - // double/long boundaries. For probability == 0.0, we use Long.MIN_VALUE as this guarantees - // that we will never sample a trace, even in the case where the id == Long.MIN_VALUE, since - // Math.Abs(Long.MIN_VALUE) == Long.MIN_VALUE. - if (probability == 0.0) { - idUpperBound = Long.MIN_VALUE; - } else if (probability == 1.0) { - idUpperBound = Long.MAX_VALUE; - } else { - idUpperBound = (long) (probability * Long.MAX_VALUE); - } - return new AutoValue_Samplers_ProbabilitySampler(probability, idUpperBound); - } - - @Override - protected final boolean shouldSample( - @Nullable SpanContext parentContext, - boolean remoteParent, - TraceId traceId, - SpanId spanId, - String name, - @Nullable List parentLinks) { - // Always enable sampling if parent was sampled. - if (parentContext != null && parentContext.getTraceOptions().isSampled()) { - return true; - } - // Always sample if we are within probability range. This is true even for child spans (that - // may have had a different sampling decision made) to allow for different sampling policies, - // and dynamic increases to sampling probabilities for debugging purposes. - // Note use of '<' for comparison. This ensures that we never sample for probability == 0.0, - // while allowing for a (very) small chance of *not* sampling if the id == Long.MAX_VALUE. - // This is considered a reasonable tradeoff for the simplicity/performance requirements (this - // code is executed in-line for every Span creation). - return Math.abs(traceId.getLowerLong()) < getIdUpperBound(); - } - } -} diff --git a/api/src/main/java/io/opencensus/trace/Span.java b/api/src/main/java/io/opencensus/trace/Span.java index 0a941287c9..f1661901a0 100644 --- a/api/src/main/java/io/opencensus/trace/Span.java +++ b/api/src/main/java/io/opencensus/trace/Span.java @@ -21,6 +21,7 @@ import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; +import io.opencensus.trace.base.StartSpanOptions; import java.util.Collections; import java.util.EnumSet; import java.util.Map; diff --git a/api/src/main/java/io/opencensus/trace/SpanBuilder.java b/api/src/main/java/io/opencensus/trace/SpanBuilder.java index b3ad8a5f70..782248baac 100644 --- a/api/src/main/java/io/opencensus/trace/SpanBuilder.java +++ b/api/src/main/java/io/opencensus/trace/SpanBuilder.java @@ -15,6 +15,8 @@ import io.opencensus.common.NonThrowingCloseable; import io.opencensus.trace.base.EndSpanOptions; +import io.opencensus.trace.base.Sampler; +import io.opencensus.trace.base.StartSpanOptions; import io.opencensus.trace.internal.SpanFactory; import java.util.List; import javax.annotation.Nullable; diff --git a/api/src/main/java/io/opencensus/trace/Tracer.java b/api/src/main/java/io/opencensus/trace/Tracer.java index 64f0ae4995..e6172bed85 100644 --- a/api/src/main/java/io/opencensus/trace/Tracer.java +++ b/api/src/main/java/io/opencensus/trace/Tracer.java @@ -16,6 +16,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.base.StartSpanOptions; import io.opencensus.trace.internal.SpanFactory; import javax.annotation.Nullable; diff --git a/api/src/main/java/io/opencensus/trace/Sampler.java b/api/src/main/java/io/opencensus/trace/base/Sampler.java similarity index 91% rename from api/src/main/java/io/opencensus/trace/Sampler.java rename to api/src/main/java/io/opencensus/trace/base/Sampler.java index d231f41b6a..94bd2966fd 100644 --- a/api/src/main/java/io/opencensus/trace/Sampler.java +++ b/api/src/main/java/io/opencensus/trace/base/Sampler.java @@ -11,10 +11,11 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; + +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; import java.util.List; import javax.annotation.Nullable; @@ -33,7 +34,7 @@ public abstract class Sampler { * @param parentLinks The parentLinks associated with the new {@code Span}. * @return {@code true} if the {@code Span} is sampled. */ - protected abstract boolean shouldSample( + public abstract boolean shouldSample( @Nullable SpanContext parentContext, boolean remoteParent, TraceId traceId, diff --git a/api/src/main/java/io/opencensus/trace/StartSpanOptions.java b/api/src/main/java/io/opencensus/trace/base/StartSpanOptions.java similarity index 96% rename from api/src/main/java/io/opencensus/trace/StartSpanOptions.java rename to api/src/main/java/io/opencensus/trace/base/StartSpanOptions.java index 9b7ccb659f..518f1e60ec 100644 --- a/api/src/main/java/io/opencensus/trace/StartSpanOptions.java +++ b/api/src/main/java/io/opencensus/trace/base/StartSpanOptions.java @@ -11,10 +11,11 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import com.google.auto.value.AutoValue; import com.google.common.annotations.VisibleForTesting; +import io.opencensus.trace.Span; import io.opencensus.trace.config.TraceConfig; import java.util.ArrayList; import java.util.Collections; @@ -33,7 +34,7 @@ public abstract class StartSpanOptions { private static final List EMPTY_PARENT_LINKS_LIST = Collections.emptyList(); /** The default {@code StartSpanOptions}. */ - @VisibleForTesting static final StartSpanOptions DEFAULT = builder().build(); + @VisibleForTesting public static final StartSpanOptions DEFAULT = builder().build(); /** * Returns the {@link Sampler} to be used, or {@code null} if default. diff --git a/api/src/main/java/io/opencensus/trace/config/TraceParams.java b/api/src/main/java/io/opencensus/trace/config/TraceParams.java index 1f0e093f76..74953cfd39 100644 --- a/api/src/main/java/io/opencensus/trace/config/TraceParams.java +++ b/api/src/main/java/io/opencensus/trace/config/TraceParams.java @@ -16,13 +16,13 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.auto.value.AutoValue; -import io.opencensus.trace.Sampler; -import io.opencensus.trace.Samplers; import io.opencensus.trace.Span; -import io.opencensus.trace.StartSpanOptions; import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; +import io.opencensus.trace.base.Sampler; +import io.opencensus.trace.base.StartSpanOptions; +import io.opencensus.trace.samplers.Samplers; import javax.annotation.concurrent.Immutable; /** Class that holds global trace parameters. */ @@ -109,8 +109,8 @@ public abstract static class Builder { /** * Sets the global default max number of attributes per {@link Span}. * - * @param maxNumberOfAttributes the global default max number of attributes per {@link Span}. - * It must be positive otherwise {@link #build()} will throw an exception. + * @param maxNumberOfAttributes the global default max number of attributes per {@link Span}. It + * must be positive otherwise {@link #build()} will throw an exception. * @return this. */ public abstract Builder setMaxNumberOfAttributes(int maxNumberOfAttributes); @@ -118,9 +118,8 @@ public abstract static class Builder { /** * Sets the global default max number of {@link Annotation} events per {@link Span}. * - * @param maxNumberOfAnnotations the global default max number of {@link Annotation} events - * per {@link Span}. It must be positive otherwise {@link #build()} will throw an - * exception. + * @param maxNumberOfAnnotations the global default max number of {@link Annotation} events per + * {@link Span}. It must be positive otherwise {@link #build()} will throw an exception. * @return this. */ public abstract Builder setMaxNumberOfAnnotations(int maxNumberOfAnnotations); @@ -128,9 +127,8 @@ public abstract static class Builder { /** * Sets the global default max number of {@link NetworkEvent} events per {@link Span}. * - * @param maxNumberOfNetworkEvents the global default max number of {@link NetworkEvent} - * events per {@link Span}. It must be positive otherwise {@link #build()} will throw an - * exception. + * @param maxNumberOfNetworkEvents the global default max number of {@link NetworkEvent} events + * per {@link Span}. It must be positive otherwise {@link #build()} will throw an exception. * @return this. */ public abstract Builder setMaxNumberOfNetworkEvents(int maxNumberOfNetworkEvents); diff --git a/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java b/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java index b93ec86591..a030615227 100644 --- a/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java +++ b/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java @@ -15,7 +15,7 @@ import io.opencensus.trace.Span; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.StartSpanOptions; +import io.opencensus.trace.base.StartSpanOptions; import javax.annotation.Nullable; /** Factory class to create and start a {@link Span}. */ diff --git a/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java b/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java new file mode 100644 index 0000000000..f3daed4b4d --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java @@ -0,0 +1,50 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.samplers; + +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.base.Sampler; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import java.util.List; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * Sampler that always makes a "yes" decision on {@link Span} sampling. + */ +@Immutable +final class AlwaysSampleSampler extends Sampler { + + AlwaysSampleSampler() { + } + + // Returns always makes a "yes" decision on {@link Span} sampling. + @Override + public boolean shouldSample( + @Nullable SpanContext parentContext, + boolean remoteParent, + TraceId traceId, + SpanId spanId, + String name, + List parentLinks) { + return true; + } + + @Override + public String toString() { + return "AlwaysSampleSampler"; + } +} diff --git a/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java b/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java new file mode 100644 index 0000000000..bca64df4d5 --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java @@ -0,0 +1,50 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.samplers; + +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.base.Sampler; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import java.util.List; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * Sampler that always makes a "no" decision on {@link Span} sampling. + */ +@Immutable +final class NeverSampleSampler extends Sampler { + + NeverSampleSampler() { + } + + // Returns always makes a "no" decision on {@link Span} sampling. + @Override + public boolean shouldSample( + @Nullable SpanContext parentContext, + boolean remoteParent, + TraceId traceId, + SpanId spanId, + String name, + List parentLinks) { + return false; + } + + @Override + public String toString() { + return "NeverSampleSampler"; + } +} diff --git a/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java b/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java new file mode 100644 index 0000000000..c5c9c00237 --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java @@ -0,0 +1,93 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.samplers; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.auto.value.AutoValue; +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.base.Sampler; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import java.util.List; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * We assume the lower 64 bits of the traceId's are randomly distributed around the whole (long) + * range. We convert an incoming probability into an upper bound on that value, such that we can + * just compare the absolute value of the id and the bound to see if we are within the desired + * probability range. Using the low bits of the traceId also ensures that systems that only use + * 64 bit ID's will also work with this sampler. + */ +@AutoValue +@Immutable +abstract class ProbabilitySampler extends Sampler { + + ProbabilitySampler() { + } + + abstract double getProbability(); + + abstract long getIdUpperBound(); + + /** + * Returns a new {@link ProbabilitySampler}. The probability of sampling a trace is equal to + * that of the specified probability. + * + * @param probability The desired probability of sampling. Must be within [0.0, 1.0]. + * @return a new {@link ProbabilitySampler}. + * @throws IllegalArgumentException if {@code probability} is out of range + */ + static ProbabilitySampler create(double probability) { + checkArgument( + probability >= 0.0 && probability <= 1.0, "probability must be in range [0.0, 1.0]"); + long idUpperBound = 0; + // Special case the limits, to avoid any possible issues with lack of precision across + // double/long boundaries. For probability == 0.0, we use Long.MIN_VALUE as this guarantees + // that we will never sample a trace, even in the case where the id == Long.MIN_VALUE, since + // Math.Abs(Long.MIN_VALUE) == Long.MIN_VALUE. + if (probability == 0.0) { + idUpperBound = Long.MIN_VALUE; + } else if (probability == 1.0) { + idUpperBound = Long.MAX_VALUE; + } else { + idUpperBound = (long) (probability * Long.MAX_VALUE); + } + return new AutoValue_ProbabilitySampler(probability, idUpperBound); + } + + @Override + public final boolean shouldSample( + @Nullable SpanContext parentContext, + boolean remoteParent, + TraceId traceId, + SpanId spanId, + String name, + @Nullable List parentLinks) { + // Always enable sampling if parent was sampled. + if (parentContext != null && parentContext.getTraceOptions().isSampled()) { + return true; + } + // Always sample if we are within probability range. This is true even for child spans (that + // may have had a different sampling decision made) to allow for different sampling policies, + // and dynamic increases to sampling probabilities for debugging purposes. + // Note use of '<' for comparison. This ensures that we never sample for probability == 0.0, + // while allowing for a (very) small chance of *not* sampling if the id == Long.MAX_VALUE. + // This is considered a reasonable tradeoff for the simplicity/performance requirements (this + // code is executed in-line for every Span creation). + return Math.abs(traceId.getLowerLong()) < getIdUpperBound(); + } +} diff --git a/api/src/main/java/io/opencensus/trace/samplers/Samplers.java b/api/src/main/java/io/opencensus/trace/samplers/Samplers.java new file mode 100644 index 0000000000..40d7293159 --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/samplers/Samplers.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.samplers; + +import io.opencensus.trace.Span; +import io.opencensus.trace.base.Sampler; + +/** Static class to access a set of pre-defined {@link Sampler Samplers}. */ +public final class Samplers { + private static final Sampler ALWAYS_SAMPLE = new AlwaysSampleSampler(); + private static final Sampler NEVER_SAMPLE = new NeverSampleSampler(); + + // No instance of this class. + private Samplers() {} + + /** + * Returns a {@link Sampler} that always makes a "yes" decision on {@link Span} sampling. + * + * @return a {@code Sampler} that always makes a "yes" decision on {@code Span} sampling. + */ + public static Sampler alwaysSample() { + return ALWAYS_SAMPLE; + } + + /** + * Returns a {@link Sampler} that always makes a "no" decision on {@link Span} sampling. + * + * @return a {@code Sampler} that always makes a "no" decision on {@code Span} sampling. + */ + public static Sampler neverSample() { + return NEVER_SAMPLE; + } + + /** + * Returns a {@link Sampler} that makes a "yes" decision with a given probability. + * + * @param probability The desired probability of sampling. Must be within [0.0, 1.0]. + * @return a {@code Sampler} that makes a "yes" decision with a given probability. + * @throws IllegalArgumentException if {@code probability} is out of range + */ + public static Sampler probabilitySampler(double probability) { + return ProbabilitySampler.create(probability); + } +} diff --git a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java index 469fe9bbe8..10eccbe6fe 100644 --- a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java @@ -23,9 +23,11 @@ import io.opencensus.common.NonThrowingCloseable; import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.StartSpanOptions; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.internal.SpanFactory; +import io.opencensus.trace.samplers.Samplers; import java.util.Arrays; import java.util.List; import java.util.Random; diff --git a/api/src/test/java/io/opencensus/trace/TracerTest.java b/api/src/test/java/io/opencensus/trace/TracerTest.java index 51b86b636c..7339eae266 100644 --- a/api/src/test/java/io/opencensus/trace/TracerTest.java +++ b/api/src/test/java/io/opencensus/trace/TracerTest.java @@ -24,6 +24,7 @@ import io.opencensus.common.NonThrowingCloseable; import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.StartSpanOptions; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.internal.SpanFactory; diff --git a/api/src/test/java/io/opencensus/trace/StartSpanOptionsTest.java b/api/src/test/java/io/opencensus/trace/base/StartSpanOptionsTest.java similarity index 96% rename from api/src/test/java/io/opencensus/trace/StartSpanOptionsTest.java rename to api/src/test/java/io/opencensus/trace/base/StartSpanOptionsTest.java index c37324ab3a..1a983b73df 100644 --- a/api/src/test/java/io/opencensus/trace/StartSpanOptionsTest.java +++ b/api/src/test/java/io/opencensus/trace/base/StartSpanOptionsTest.java @@ -11,11 +11,14 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.base; import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; +import io.opencensus.trace.BlankSpan; +import io.opencensus.trace.Span; +import io.opencensus.trace.samplers.Samplers; import java.util.Arrays; import java.util.LinkedList; import java.util.List; diff --git a/api/src/test/java/io/opencensus/trace/config/TraceConfigTest.java b/api/src/test/java/io/opencensus/trace/config/TraceConfigTest.java index 2bf9356d34..cbb6092cd2 100644 --- a/api/src/test/java/io/opencensus/trace/config/TraceConfigTest.java +++ b/api/src/test/java/io/opencensus/trace/config/TraceConfigTest.java @@ -15,7 +15,7 @@ import static com.google.common.truth.Truth.assertThat; -import io.opencensus.trace.Samplers; +import io.opencensus.trace.samplers.Samplers; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/api/src/test/java/io/opencensus/trace/config/TraceParamsTest.java b/api/src/test/java/io/opencensus/trace/config/TraceParamsTest.java index 76d828a9ea..165f02119c 100644 --- a/api/src/test/java/io/opencensus/trace/config/TraceParamsTest.java +++ b/api/src/test/java/io/opencensus/trace/config/TraceParamsTest.java @@ -15,7 +15,7 @@ import static com.google.common.truth.Truth.assertThat; -import io.opencensus.trace.Samplers; +import io.opencensus.trace.samplers.Samplers; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/api/src/test/java/io/opencensus/trace/SamplersTest.java b/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java similarity index 97% rename from api/src/test/java/io/opencensus/trace/SamplersTest.java rename to api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java index 52351f2c69..5e99683511 100644 --- a/api/src/test/java/io/opencensus/trace/SamplersTest.java +++ b/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java @@ -11,10 +11,13 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.samplers; import static com.google.common.truth.Truth.assertThat; +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.base.Sampler; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java index 13657e1bad..3013e764ca 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java @@ -16,6 +16,7 @@ import io.opencensus.trace.base.AttributeValue; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; +import io.opencensus.trace.samplers.Samplers; import java.util.HashMap; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java index 3c2a9d1776..ccfbc7753a 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java @@ -16,6 +16,7 @@ import io.opencensus.trace.base.AttributeValue; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; +import io.opencensus.trace.samplers.Samplers; import java.util.HashMap; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java index 9a51ffbe42..0a86b6f8ae 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java @@ -13,6 +13,7 @@ package io.opencensus.trace; +import io.opencensus.trace.samplers.Samplers; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java index 3f087799a5..d9aadb5e37 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java @@ -20,7 +20,9 @@ import io.opencensus.trace.Span.Options; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.Link.Type; +import io.opencensus.trace.base.Sampler; import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.StartSpanOptions; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceConfig; diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java index 4e718cf836..74bc2d8663 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java @@ -20,11 +20,13 @@ import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.StartSpanOptions; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.internal.RandomHandler; +import io.opencensus.trace.samplers.Samplers; import java.util.Random; import org.junit.Before; import org.junit.Test; diff --git a/core_impl/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java b/core_impl/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java index 24e78b2b94..a76e180f80 100644 --- a/core_impl/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java @@ -15,7 +15,7 @@ import static com.google.common.truth.Truth.assertThat; -import io.opencensus.trace.Samplers; +import io.opencensus.trace.samplers.Samplers; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; From c6e146ba77ed74b8272c2d1142b3e17eda93d090 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 12 Jun 2017 14:34:59 -0700 Subject: [PATCH 0164/1581] Move SpanData to export package. Move implementation of export package class to export package. (#343) --- .../io/opencensus/internal/package-info.java | 2 +- .../export/InProcessDebuggingHandler.java | 1 - .../trace/{ => export}/SpanData.java | 4 ++- .../opencensus/trace/export/SpanExporter.java | 1 - .../trace/export/ExportComponentTest.java | 36 +++++++++++++++++++ .../trace/{ => export}/SpanDataTest.java | 15 ++++---- .../java/io/opencensus/trace/SpanImpl.java | 21 ++++++----- .../opencensus/trace/StartEndHandlerImpl.java | 6 ++-- .../trace/TraceComponentImplBase.java | 1 + .../{ => export}/ExportComponentImpl.java | 9 +++-- .../trace/{ => export}/SpanExporterImpl.java | 13 ++++--- .../opencensus/trace/SpanFactoryImplTest.java | 1 + .../io/opencensus/trace/SpanImplTest.java | 1 + .../trace/TraceComponentImplBaseTest.java | 1 + .../trace/export/ExportComponentImplTest.java | 36 +++++++++++++++++++ .../{ => export}/SpanExporterImplTest.java | 5 ++- .../trace/TraceComponentImplTest.java | 1 + .../java/io/opencensus/trace/TracingTest.java | 1 + 18 files changed, 123 insertions(+), 32 deletions(-) rename api/src/main/java/io/opencensus/trace/{ => export}/SpanData.java (98%) create mode 100644 api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java rename api/src/test/java/io/opencensus/trace/{ => export}/SpanDataTest.java (97%) rename core_impl/src/main/java/io/opencensus/trace/{ => export}/ExportComponentImpl.java (87%) rename core_impl/src/main/java/io/opencensus/trace/{ => export}/SpanExporterImpl.java (96%) create mode 100644 core_impl/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java rename core_impl/src/test/java/io/opencensus/trace/{ => export}/SpanExporterImplTest.java (98%) diff --git a/api/src/main/java/io/opencensus/internal/package-info.java b/api/src/main/java/io/opencensus/internal/package-info.java index 5fe0010d41..a9f9486497 100644 --- a/api/src/main/java/io/opencensus/internal/package-info.java +++ b/api/src/main/java/io/opencensus/internal/package-info.java @@ -12,7 +12,7 @@ */ /** - * Interfaces and implementations that are internal to opencensus. + * Interfaces and implementations that are internal to OpenCensus. * *

            All the content under this package and its subpackages are considered annotated with {@link * io.opencensus.common.Internal}. diff --git a/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java b/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java index 40fdcae0df..c2e7ab1c42 100644 --- a/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java +++ b/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java @@ -18,7 +18,6 @@ import com.google.auto.value.AutoValue; import io.opencensus.trace.Span; -import io.opencensus.trace.SpanData; import io.opencensus.trace.base.Status; import io.opencensus.trace.base.Status.CanonicalCode; import java.util.Collection; diff --git a/api/src/main/java/io/opencensus/trace/SpanData.java b/api/src/main/java/io/opencensus/trace/export/SpanData.java similarity index 98% rename from api/src/main/java/io/opencensus/trace/SpanData.java rename to api/src/main/java/io/opencensus/trace/export/SpanData.java index 02c8952824..73e03f468d 100644 --- a/api/src/main/java/io/opencensus/trace/SpanData.java +++ b/api/src/main/java/io/opencensus/trace/export/SpanData.java @@ -11,12 +11,14 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.export; import static com.google.common.base.Preconditions.checkNotNull; import com.google.auto.value.AutoValue; import io.opencensus.common.Timestamp; +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanContext; import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.AttributeValue; import io.opencensus.trace.base.Link; diff --git a/api/src/main/java/io/opencensus/trace/export/SpanExporter.java b/api/src/main/java/io/opencensus/trace/export/SpanExporter.java index 199427b1bc..39e0a583c0 100644 --- a/api/src/main/java/io/opencensus/trace/export/SpanExporter.java +++ b/api/src/main/java/io/opencensus/trace/export/SpanExporter.java @@ -14,7 +14,6 @@ package io.opencensus.trace.export; import io.opencensus.trace.Span; -import io.opencensus.trace.SpanData; import io.opencensus.trace.base.TraceOptions; import java.util.Collection; import java.util.logging.Level; diff --git a/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java b/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java new file mode 100644 index 0000000000..4125801c3c --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.export; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link ExportComponent}. */ +@RunWith(JUnit4.class) +public class ExportComponentTest { + private final ExportComponent exportComponent = ExportComponent.getNoopExportComponent(); + + @Test + public void implementationOfSpanExporter() { + assertThat(exportComponent.getSpanExporter()).isEqualTo(SpanExporter.getNoopSpanExporter()); + } + + @Test + public void implementationOfInProcessDebuggingHandler() { + assertThat(exportComponent.getInProcessDebuggingHandler()).isNull(); + } +} diff --git a/api/src/test/java/io/opencensus/trace/SpanDataTest.java b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java similarity index 97% rename from api/src/test/java/io/opencensus/trace/SpanDataTest.java rename to api/src/test/java/io/opencensus/trace/export/SpanDataTest.java index ce10c35e0a..1a92b0e634 100644 --- a/api/src/test/java/io/opencensus/trace/SpanDataTest.java +++ b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java @@ -11,25 +11,26 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.export; import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; import io.opencensus.common.Timestamp; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.Link.Type; -import io.opencensus.trace.SpanData.Attributes; -import io.opencensus.trace.SpanData.Links; -import io.opencensus.trace.SpanData.TimedEvent; -import io.opencensus.trace.SpanData.TimedEvents; +import io.opencensus.trace.SpanContext; import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.AttributeValue; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.Link.Type; import io.opencensus.trace.base.NetworkEvent; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.Status; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.export.SpanData.Attributes; +import io.opencensus.trace.export.SpanData.Links; +import io.opencensus.trace.export.SpanData.TimedEvent; +import io.opencensus.trace.export.SpanData.TimedEvents; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java index a69458e501..11efb30bb9 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java @@ -16,10 +16,10 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.EvictingQueue; import io.opencensus.common.Clock; import io.opencensus.internal.TimestampConverter; -import io.opencensus.trace.SpanData.TimedEvent; import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.AttributeValue; import io.opencensus.trace.base.EndSpanOptions; @@ -28,6 +28,8 @@ import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.Status; import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.export.SpanData; +import io.opencensus.trace.export.SpanData.TimedEvent; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; @@ -42,7 +44,7 @@ /** Implementation for the {@link Span} class. */ @ThreadSafe -final class SpanImpl extends Span { +public final class SpanImpl extends Span { private static final Logger logger = Logger.getLogger(Tracer.class.getName()); // The parent SpanId of this span. Null if this is a root. @@ -86,10 +88,13 @@ final class SpanImpl extends Span { @GuardedBy("this") private boolean hasBeenEnded; - // Creates and starts a span with the given configuration. TimestampConverter is null if the - // Span is a root span or the parent is not sampled. If the parent is sampled we should use the - // same converter to ensure ordering between tracing events. - static SpanImpl startSpan( + /** + * Creates and starts a span with the given configuration. TimestampConverter is null if the + * {@code Span} is a root span or the parent is not sampled. If the parent is sampled we should + * use the same converter to ensure ordering between tracing events. + */ + @VisibleForTesting + public static SpanImpl startSpan( SpanContext context, @Nullable EnumSet options, String name, @@ -143,7 +148,7 @@ TimestampConverter getTimestampConverter() { * @return an immutable representation of all the data from this {@code Span}. * @throws IllegalStateException if the Span doesn't have RECORD_EVENTS option. */ - SpanData toSpanData() { + public SpanData toSpanData() { checkState( getOptions().contains(Options.RECORD_EVENTS), "Getting SpanData for a Span without RECORD_EVENTS option."); @@ -330,7 +335,7 @@ private static SpanData.TimedEvents createTimedEvents( *

            One instance can be called by multiple threads in the same time, so the implementation must * be thread-safe. */ - interface StartEndHandler { + public interface StartEndHandler { void onStart(SpanImpl span); void onEnd(SpanImpl span); diff --git a/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java b/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java index c00b463bbe..454f08eeac 100644 --- a/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java @@ -15,16 +15,18 @@ import io.opencensus.internal.EventQueue; import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.export.SpanData; +import io.opencensus.trace.export.SpanExporterImpl; /** * Uses the provided {@link EventQueue} to defer processing/exporting of the {@link SpanData} to * avoid impacting the critical path. */ -final class StartEndHandlerImpl implements StartEndHandler { +public final class StartEndHandlerImpl implements StartEndHandler { private final EventQueue eventQueue; private final SpanExporterImpl sampledSpansServiceExporter; - StartEndHandlerImpl( + public StartEndHandlerImpl( SpanExporterImpl sampledSpansServiceExporter, EventQueue eventQueue) { this.sampledSpansServiceExporter = sampledSpansServiceExporter; this.eventQueue = eventQueue; diff --git a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java index 289d087716..23a13269df 100644 --- a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java @@ -19,6 +19,7 @@ import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceConfigImpl; import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.export.ExportComponentImpl; import io.opencensus.trace.internal.RandomHandler; import io.opencensus.trace.propagation.PropagationComponent; import io.opencensus.trace.propagation.PropagationComponentImpl; diff --git a/core_impl/src/main/java/io/opencensus/trace/ExportComponentImpl.java b/core_impl/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java similarity index 87% rename from core_impl/src/main/java/io/opencensus/trace/ExportComponentImpl.java rename to core_impl/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java index c695243f46..7bac1a001f 100644 --- a/core_impl/src/main/java/io/opencensus/trace/ExportComponentImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java @@ -11,12 +11,10 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.export; import io.opencensus.internal.EventQueue; import io.opencensus.trace.SpanImpl.StartEndHandler; -import io.opencensus.trace.export.ExportComponent; -import io.opencensus.trace.export.InProcessDebuggingHandler; import javax.annotation.Nullable; /** @@ -25,7 +23,7 @@ *

            Uses the provided {@link EventQueue} to defer processing/exporting of the {@link SpanData} to * avoid impacting the critical path. */ -final class ExportComponentImpl extends ExportComponent { +public final class ExportComponentImpl extends ExportComponent { private static final int EXPORTER_BUFFER_SIZE = 32; // Enforces that trace export exports data at least once every 2 seconds. private static final long EXPORTER_SCHEDULE_DELAY_MS = 2000; @@ -44,7 +42,8 @@ public InProcessDebuggingHandler getInProcessDebuggingHandler() { return null; } - ExportComponentImpl() { + /** Constructs a new {@code ExportComponentImpl}. */ + public ExportComponentImpl() { this.spanExporter = SpanExporterImpl.create(EXPORTER_BUFFER_SIZE, EXPORTER_SCHEDULE_DELAY_MS); } } diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanExporterImpl.java b/core_impl/src/main/java/io/opencensus/trace/export/SpanExporterImpl.java similarity index 96% rename from core_impl/src/main/java/io/opencensus/trace/SpanExporterImpl.java rename to core_impl/src/main/java/io/opencensus/trace/export/SpanExporterImpl.java index 5428c60dd3..643daae38e 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanExporterImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/export/SpanExporterImpl.java @@ -11,11 +11,10 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.export; import com.google.common.annotations.VisibleForTesting; -import io.opencensus.trace.export.ExportComponent; -import io.opencensus.trace.export.SpanExporter; +import io.opencensus.trace.SpanImpl; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; @@ -49,8 +48,12 @@ static SpanExporterImpl create(int bufferSize, long scheduleDelayMillis) { return new SpanExporterImpl(workerThread); } - // Adds a Span to the exporting service. - void addSpan(SpanImpl span) { + /** + * Adds a Span to the exporting service. + * + * @param span the {@code Span} to be added. + */ + public void addSpan(SpanImpl span) { workerThread.addSpan(span); } diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java index 74bc2d8663..00d051a6ae 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java @@ -25,6 +25,7 @@ import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.export.SpanData; import io.opencensus.trace.internal.RandomHandler; import io.opencensus.trace.samplers.Samplers; import java.util.Random; diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java b/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java index 7c39d7e138..62052dd2d8 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java @@ -31,6 +31,7 @@ import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.export.SpanData; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; diff --git a/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java b/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java index 442efcc866..9af5591001 100644 --- a/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java @@ -17,6 +17,7 @@ import io.opencensus.common.MillisClock; import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.trace.export.ExportComponentImpl; import io.opencensus.trace.internal.RandomHandler.SecureRandomHandler; import io.opencensus.trace.propagation.PropagationComponentImpl; import org.junit.Test; diff --git a/core_impl/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java b/core_impl/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java new file mode 100644 index 0000000000..860b8af068 --- /dev/null +++ b/core_impl/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.export; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link ExportComponentImpl}. */ +@RunWith(JUnit4.class) +public class ExportComponentImplTest { + private final ExportComponent exportComponent = new ExportComponentImpl(); + + @Test + public void implementationOfSpanExporter() { + assertThat(exportComponent.getSpanExporter()).isInstanceOf(SpanExporterImpl.class); + } + + @Test + public void implementationOfInProcessDebuggingHandler() { + assertThat(exportComponent.getInProcessDebuggingHandler()).isNull(); + } +} diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java b/core_impl/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java similarity index 98% rename from core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java rename to core_impl/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java index bc514d4bad..52251107c2 100644 --- a/core_impl/src/test/java/io/opencensus/trace/SpanExporterImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.export; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyListOf; @@ -20,7 +20,10 @@ import io.opencensus.common.MillisClock; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.trace.Span.Options; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanImpl; import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.StartEndHandlerImpl; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; diff --git a/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java b/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java index 2ae4ad9461..024e8692d1 100644 --- a/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java +++ b/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java @@ -16,6 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.MillisClock; +import io.opencensus.trace.export.ExportComponentImpl; import io.opencensus.trace.propagation.PropagationComponentImpl; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java b/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java index 909eca9b98..5f5fbeee26 100644 --- a/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java +++ b/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java @@ -16,6 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.MillisClock; +import io.opencensus.trace.export.ExportComponentImpl; import io.opencensus.trace.propagation.PropagationComponent; import org.junit.Test; import org.junit.runner.RunWith; From e47a5ca5063c59bc18ac4c90f4df3514fe0b5b95 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 13 Jun 2017 16:16:55 -0700 Subject: [PATCH 0165/1581] Add README.md for examples, change all reference to Instrumentation to OpenCensus. (#354) --- benchmarks/README.md | 6 +++--- benchmarks/build.gradle | 2 +- core_impl/README.md | 2 +- core_impl/build.gradle | 2 +- core_impl_android/README.md | 2 +- core_impl_android/build.gradle | 2 +- core_impl_java/README.md | 2 +- core_impl_java/build.gradle | 2 +- examples/README.md | 12 ++++++++++++ examples/build.gradle | 2 +- 10 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 examples/README.md diff --git a/benchmarks/README.md b/benchmarks/README.md index a152273feb..e4027008d1 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -1,7 +1,7 @@ -# Instrumentation Benchmarks +# OpenCensus Benchmarks -## To run the benchmark type +## To run the benchmark use ``` -$ ./gradlew :instrumentation-java-benchmarks:jmh +$ ./gradlew :benchmarks:jmh ``` diff --git a/benchmarks/build.gradle b/benchmarks/build.gradle index 3c20fd0cb1..5203885a22 100644 --- a/benchmarks/build.gradle +++ b/benchmarks/build.gradle @@ -1,4 +1,4 @@ -description = 'Instrumentation: Benchmarks' +description = 'OpenCensus Benchmarks' buildscript { repositories { diff --git a/core_impl/README.md b/core_impl/README.md index 95e4027e26..901177c82d 100644 --- a/core_impl/README.md +++ b/core_impl/README.md @@ -1,4 +1,4 @@ -Instrumentation implementation +OpenCensus implementation ====================================================== * The main implementation shared between Java and Android. diff --git a/core_impl/build.gradle b/core_impl/build.gradle index ced6e56733..65a752a431 100644 --- a/core_impl/build.gradle +++ b/core_impl/build.gradle @@ -1,4 +1,4 @@ -description = 'Instrumentation Core Impl' +description = 'OpenCensus Core Impl' dependencies { compile project(':core'), diff --git a/core_impl_android/README.md b/core_impl_android/README.md index 97a99ff97d..ad7bb9b165 100644 --- a/core_impl_android/README.md +++ b/core_impl_android/README.md @@ -1,4 +1,4 @@ -Instrumentation Android implementation +OpenCensus Android implementation ====================================================== * Android compatible. diff --git a/core_impl_android/build.gradle b/core_impl_android/build.gradle index 17249dacee..4d830586ad 100644 --- a/core_impl_android/build.gradle +++ b/core_impl_android/build.gradle @@ -1,4 +1,4 @@ -description = 'Instrumentation Core Impl Android' +description = 'OpenCensus Core Impl Android' dependencies { compile project(':core'), diff --git a/core_impl_java/README.md b/core_impl_java/README.md index e578f26f27..3dee26f9de 100644 --- a/core_impl_java/README.md +++ b/core_impl_java/README.md @@ -1,4 +1,4 @@ -Instrumentation Java implementation +OpenCensus Java implementation ====================================================== * Java 7 compatible. diff --git a/core_impl_java/build.gradle b/core_impl_java/build.gradle index 61f23e4ecf..da47efc578 100644 --- a/core_impl_java/build.gradle +++ b/core_impl_java/build.gradle @@ -1,4 +1,4 @@ -description = 'Instrumentation Core Impl Java' +description = 'OpenCensus Core Impl Java' apply plugin: 'java' diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000000..b76f456b8c --- /dev/null +++ b/examples/README.md @@ -0,0 +1,12 @@ +# OpenCensus Examples + +## To build the examples use + +``` +$ ./gradlew installDist +``` +## To run "StatsRunner" example use + +``` +$ ./examples/build/install/examples/bin/StatsRunner +``` \ No newline at end of file diff --git a/examples/build.gradle b/examples/build.gradle index aac3619ef0..480374a102 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -1,4 +1,4 @@ -description = 'Instrumentation: Examples' +description = 'OpenCensus Examples' tasks.withType(JavaCompile) { sourceCompatibility = '1.8' From 82bc9cdefb378d80cfe8ad1f1ac8c72978119c66 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 14 Jun 2017 12:18:58 -0700 Subject: [PATCH 0166/1581] Split InProcessDebuggingHandler into ActiveSpans and SampleStore. (#351) --- .../trace/export/ActiveSpansExporter.java | 159 ++++++++++ .../trace/export/ExportComponent.java | 30 +- ...gingHandler.java => SampledSpanStore.java} | 274 +++++++----------- .../trace/export/ExportComponentTest.java | 8 +- .../trace/export/ExportComponentImpl.java | 18 +- .../trace/export/ExportComponentImplTest.java | 11 +- 6 files changed, 311 insertions(+), 189 deletions(-) create mode 100644 api/src/main/java/io/opencensus/trace/export/ActiveSpansExporter.java rename api/src/main/java/io/opencensus/trace/export/{InProcessDebuggingHandler.java => SampledSpanStore.java} (61%) diff --git a/api/src/main/java/io/opencensus/trace/export/ActiveSpansExporter.java b/api/src/main/java/io/opencensus/trace/export/ActiveSpansExporter.java new file mode 100644 index 0000000000..bb2edb31c5 --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/export/ActiveSpansExporter.java @@ -0,0 +1,159 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.export; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.auto.value.AutoValue; +import io.opencensus.trace.Span; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import javax.annotation.concurrent.Immutable; +import javax.annotation.concurrent.ThreadSafe; + +/** + * This class allows users to access in-process information about all active spans. + * + *

            The active spans tracking is available for all the spans with the option {@link + * Span.Options#RECORD_EVENTS}. This functionality allows users to debug stuck operations or long + * living operations. + */ +@ThreadSafe +public abstract class ActiveSpansExporter { + + protected ActiveSpansExporter() {} + + /** + * Returns the summary of all available data such, as number of active spans. + * + * @return the summary of all available data. + */ + public abstract Summary getSummary(); + + /** + * Returns the number of active spans for every span name. + * + * @return the number of active spans for every span name. + */ + public abstract Map getNumberOfActiveSpans(); + + /** + * Returns a list of active spans that match the {@code Filter}. + * + * @param filter used to filter the returned spans. + * @return a list of active spans that match the {@code Filter}. + */ + public abstract Collection getActiveSpans(Filter filter); + + /** The summary of all available data. */ + @AutoValue + @Immutable + public abstract static class Summary { + + Summary() {} + + /** + * Returns a new instance of {@code Summary}. + * + * @param perSpanNameSummary a map with summary for each span name. + * @return a new instance of {@code Summary}. + * @throws NullPointerException if {@code perSpanNameSummary} is {@code null}. + */ + public static Summary create(Map perSpanNameSummary) { + return new AutoValue_ActiveSpansExporter_Summary( + Collections.unmodifiableMap( + new HashMap( + checkNotNull(perSpanNameSummary, "perSpanNameSummary")))); + } + + /** + * Returns a map with summary of available data for each span name. + * + * @return a map with all the span names and the summary. + */ + public abstract Map getPerSpanNameSummary(); + } + + /** Summary of all available data for a span name. */ + @AutoValue + @Immutable + public abstract static class PerSpanNameSummary { + + PerSpanNameSummary() {} + + /** + * Returns a new instance of {@code PerSpanNameSummary}. + * + * @param numActiveSpans the number of sampled spans. + * @return a new instance of {@code PerSpanNameSummary}. + * @throws IllegalArgumentException if {@code numActiveSpans} is negative. + */ + public static PerSpanNameSummary create(int numActiveSpans) { + checkArgument(numActiveSpans >= 0, "Negative numActiveSpans."); + return new AutoValue_ActiveSpansExporter_PerSpanNameSummary(numActiveSpans); + } + + /** + * Returns the number of active spans. + * + * @return the number of active spans. + */ + public abstract int getNumActiveSpans(); + } + + /** + * Filter for active spans. Used to filter results returned by the {@link #getActiveSpans(Filter)} + * request. + */ + @AutoValue + @Immutable + public abstract static class Filter { + + Filter() {} + + /** + * Returns a new instance of {@code Filter}. + * + *

            Filters all the spans based on {@code spanName} and returns a maximum of {@code + * maxSpansToReturn}. + * + * @param spanName the name of the span. + * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. + * @return a new instance of {@code Filter}. + * @throws NullPointerException if {@code spanName} is {@code null}. + * @throws IllegalArgumentException if {@code maxSpansToReturn} is negative. + */ + public static Filter create(String spanName, int maxSpansToReturn) { + checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); + return new AutoValue_ActiveSpansExporter_Filter(spanName, maxSpansToReturn); + } + + /** + * Returns the span name. + * + * @return the span name. + */ + public abstract String getSpanName(); + + /** + * Returns the maximum number of spans to be returned. {@code 0} means all. + * + * @return the maximum number of spans to be returned. + */ + public abstract int getMaxSpansToReturn(); + } +} diff --git a/api/src/main/java/io/opencensus/trace/export/ExportComponent.java b/api/src/main/java/io/opencensus/trace/export/ExportComponent.java index 03f1cc6c38..99e73a6cd1 100644 --- a/api/src/main/java/io/opencensus/trace/export/ExportComponent.java +++ b/api/src/main/java/io/opencensus/trace/export/ExportComponent.java @@ -17,8 +17,8 @@ import javax.annotation.Nullable; /** - * Class that holds the implementation instances for {@link SpanExporter} and {@link - * InProcessDebuggingHandler}. + * Class that holds the implementation instances for {@link SpanExporter}, {@link + * ActiveSpansExporter} and {@link SampledSpanStore}. * *

            Unless otherwise noted all methods (on component) results are cacheable. */ @@ -45,14 +45,22 @@ public static ExportComponent getNoopExportComponent() { public abstract SpanExporter getSpanExporter(); /** - * Returns the {@link InProcessDebuggingHandler} that can be used to get useful debugging - * information such as (active spans, latency based sampled spans, error based sampled spans). + * Returns the {@link ActiveSpansExporter} that can be used to get useful debugging information + * about all the current active spans. * - * @return the {@code InProcessDebuggingHandler} or {@code null} if in-process debugging is not - * supported. + * @return the {@code ActiveSpansExporter} or {@code null} if not supported. */ @Nullable - public abstract InProcessDebuggingHandler getInProcessDebuggingHandler(); + public abstract ActiveSpansExporter getActiveSpansExporter(); + + /** + * Returns the {@link SampledSpanStore} that can be used to get useful debugging information, such + * as latency based sampled spans, error based sampled spans. + * + * @return the {@code SampledSpanStore} or {@code null} if not supported. + */ + @Nullable + public abstract SampledSpanStore getSampledSpanStore(); private static final class NoopExportComponent extends ExportComponent { @Override @@ -62,7 +70,13 @@ public SpanExporter getSpanExporter() { @Nullable @Override - public InProcessDebuggingHandler getInProcessDebuggingHandler() { + public ActiveSpansExporter getActiveSpansExporter() { + return null; + } + + @Nullable + @Override + public SampledSpanStore getSampledSpanStore() { return null; } } diff --git a/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java b/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java similarity index 61% rename from api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java rename to api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java index c2e7ab1c42..1fae1750ed 100644 --- a/api/src/main/java/io/opencensus/trace/export/InProcessDebuggingHandler.java +++ b/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java @@ -29,12 +29,8 @@ import javax.annotation.concurrent.ThreadSafe; /** - * This class allows users to access in-process debugging information such as (getting access to all - * active spans, support latency based sampled spans and error based sampled spans). - * - *

            The active spans tracking is available for all the spans with the option {@link - * Span.Options#RECORD_EVENTS}. This functionality allows users to debug stuck operations or long - * living operations. + * This class allows users to access in-process information such as latency based sampled spans and + * error based sampled spans. * *

            For all completed spans with the option {@link Span.Options#RECORD_EVENTS} the library can * store samples based on latency for succeeded operations or based on error code for failed @@ -42,31 +38,21 @@ * will be collected (see {@link #registerSpanNamesForCollection(Collection)}). */ @ThreadSafe -public abstract class InProcessDebuggingHandler { +public abstract class SampledSpanStore { - InProcessDebuggingHandler() {} + protected SampledSpanStore() {} /** - * Returns the summary of all available in-process debugging data such as number of active spans, - * number of sampled spans in the latency based samples or error based samples. + * Returns the summary of all available data, such as number of sampled spans in the latency based + * samples or error based samples. * - *

            Latency based sampled summary buckets and error based sampled summary buckets are available - * only for span names registered using {@link #registerSpanNamesForCollection(Collection)}. + *

            Data available only for span names registered using {@link + * #registerSpanNamesForCollection(Collection)}. * - * @return the summary of all available in-process debugging data. + * @return the summary of all available data. */ public abstract Summary getSummary(); - /** - * Returns a list of active spans that match the {@code filter}. - * - *

            Active spans are available for all the span names. - * - * @param filter used to filter the returned spans. - * @return a list of active spans that match the {@code filter}. - */ - public abstract Collection getActiveSpans(ActiveSpansFilter filter); - /** * Returns a list of succeeded spans (spans with {@link Status} equal to {@link Status#OK}) that * match the {@code filter}. @@ -77,8 +63,7 @@ public abstract class InProcessDebuggingHandler { * @param filter used to filter the returned sampled spans. * @return a list of succeeded spans that match the {@code filter}. */ - public abstract Collection getLatencyBasedSampledSpans( - LatencyBasedSampledSpansFilter filter); + public abstract Collection getLatencySampledSpans(LatencyFilter filter); /** * Returns a list of failed spans (spans with {@link Status} other than {@link Status#OK}) that @@ -90,8 +75,7 @@ public abstract Collection getLatencyBasedSampledSpans( * @param filter used to filter the returned sampled spans. * @return a list of failed spans that match the {@code filter}. */ - public abstract Collection getErrorBasedSampledSpans( - ErrorBasedSampledSpansFilter filter); + public abstract Collection getErrorSampledSpans(ErrorFilter filter); /** * Appends a list of span names for which the library will collect latency based sampled spans and @@ -114,6 +98,84 @@ public abstract Collection getErrorBasedSampledSpans( */ public abstract void unregisterSpanNamesForCollection(Collection spanNames); + /** The summary of all available data. */ + @AutoValue + @Immutable + public abstract static class Summary { + + Summary() {} + + /** + * Returns a new instance of {@code Summary}. + * + * @param perSpanNameSummary a map with summary for each span name. + * @return a new instance of {@code Summary}. + * @throws NullPointerException if {@code perSpanNameSummary} is {@code null}. + */ + public static Summary create(Map perSpanNameSummary) { + return new AutoValue_SampledSpanStore_Summary( + Collections.unmodifiableMap( + new HashMap( + checkNotNull(perSpanNameSummary, "perSpanNameSummary")))); + } + + /** + * Returns a map with summary of available data for each span name. + * + * @return a map with all the span names and the summary. + */ + public abstract Map getPerSpanNameSummary(); + } + + /** Summary of all available data for a span name. */ + @AutoValue + @Immutable + public abstract static class PerSpanNameSummary { + + PerSpanNameSummary() {} + + /** + * Returns a new instance of {@code PerSpanNameSummary}. + * + * @param numberOfLatencySampledSpans the summary for the latency buckets. + * @param numberOfErrorSampledSpans the summary for the error buckets. + * @return a new instance of {@code PerSpanNameSummary}. + * @throws NullPointerException if {@code numberOfLatencySampledSpans} or {@code + * numberOfErrorSampledSpans} are {@code null}. + */ + public static PerSpanNameSummary create( + Map numberOfLatencySampledSpans, + Map numberOfErrorSampledSpans) { + return new AutoValue_SampledSpanStore_PerSpanNameSummary( + Collections.unmodifiableMap( + new HashMap( + checkNotNull(numberOfLatencySampledSpans, "numberOfLatencySampledSpans"))), + Collections.unmodifiableMap( + new HashMap( + checkNotNull(numberOfErrorSampledSpans, "numberOfErrorSampledSpans")))); + } + + /** + * Returns the number of sampled spans in all the latency buckets. + * + *

            Data available only for span names registered using {@link + * #registerSpanNamesForCollection(Collection)}. + * + * @return the number of sampled spans in all the latency buckets. + */ + public abstract Map getNumberOfLatencySampledSpans(); + + /** + * Returns the number of sampled spans in all the error buckets. + * + *

            Data available only for span names registered using {@link + * #registerSpanNamesForCollection(Collection)}. + * + * @return the number of sampled spans in all the error buckets. + */ + public abstract Map getNumberOfErrorSampledSpans(); + } + /** * The latency buckets boundaries. Samples based on latency for successful spans (the status of * the span has a canonical code equal to {@link CanonicalCode#OK}) are collected in one of these @@ -172,144 +234,18 @@ public long getLatencyUpperNs() { private final long latencyUpperNs; } - /** The summary of all in-process debugging information. */ - @AutoValue - @Immutable - public abstract static class Summary { - - Summary() {} - - /** - * Returns a new instance of {@code Summary}. - * - * @param perSpanNameSummary a map with summary for each different span name. - * @return a new instance of {@code Summary}. - * @throws NullPointerException if {@code perSpanNameSummary} is {@code null}. - */ - public static Summary create(Map perSpanNameSummary) { - return new AutoValue_InProcessDebuggingHandler_Summary( - Collections.unmodifiableMap( - new HashMap( - checkNotNull(perSpanNameSummary, "perSpanNameSummary")))); - } - - /** - * Returns a map with summary of available data for each different span name. - * - * @return a map with all the span names and the summary. - */ - public abstract Map getPerSpanNameSummary(); - - /** Summary of all available data for a span name. */ - @AutoValue - @Immutable - public abstract static class PerSpanNameSummary { - - PerSpanNameSummary() {} - - /** - * Returns a new instance of {@code PerSpanNameSummary}. - * - * @param numActiveSpans the number of sampled spans. - * @param latencyBucketsSummaries the summary for the latency buckets. - * @param errorBucketsSummaries the summary for the error buckets. - * @return a new instance of {@code PerSpanNameSummary}. - * @throws NullPointerException if {@code latencyBucketSummaries} or {@code - * errorBucketSummaries} are {@code null}. - * @throws IllegalArgumentException if {@code numActiveSpans} is negative. - */ - public static Summary.PerSpanNameSummary create( - int numActiveSpans, - Map latencyBucketsSummaries, - Map errorBucketsSummaries) { - checkArgument(numActiveSpans >= 0, "Negative numActiveSpans."); - return new AutoValue_InProcessDebuggingHandler_Summary_PerSpanNameSummary( - numActiveSpans, - Collections.unmodifiableMap( - new HashMap( - checkNotNull(latencyBucketsSummaries, "latencyBucketsSummaries"))), - Collections.unmodifiableMap( - new HashMap( - checkNotNull(errorBucketsSummaries, "errorBucketsSummaries")))); - } - - /** - * Returns the number of active spans. - * - * @return the number of active spans. - */ - public abstract int getNumActiveSpans(); - - /** - * Returns the number of samples for each latency based sampled bucket. - * - * @return the number of samples for each latency based sampled bucket. - */ - public abstract Map getLatencyBucketsSummaries(); - - /** - * Returns the number of samples for each error based sampled bucket. - * - * @return the number of samples for each error based sampled bucket. - */ - public abstract Map getErrorBucketsSummaries(); - } - } - - /** - * Filter for active spans. Used to filter results returned by the {@link - * #getActiveSpans(ActiveSpansFilter)} request. - */ - @AutoValue - @Immutable - public abstract static class ActiveSpansFilter { - - ActiveSpansFilter() {} - - /** - * Returns a new instance of {@code ActiveSpansFilter}. - * - *

            Filters all the spans based on {@code spanName} and returns a maximum of {@code - * maxSpansToReturn}. - * - * @param spanName the name of the span. - * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. - * @return a new instance of {@code ActiveSpansFilter}. - * @throws NullPointerException if {@code spanName} is {@code null}. - * @throws IllegalArgumentException if {@code maxSpansToReturn} is negative. - */ - public static ActiveSpansFilter create(String spanName, int maxSpansToReturn) { - checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); - return new AutoValue_InProcessDebuggingHandler_ActiveSpansFilter(spanName, maxSpansToReturn); - } - - /** - * Returns the span name. - * - * @return the span name. - */ - public abstract String getSpanName(); - - /** - * Returns the maximum number of spans to be returned. {@code 0} means all. - * - * @return the maximum number of spans to be returned. - */ - public abstract int getMaxSpansToReturn(); - } - /** * Filter for latency based sampled spans. Used to filter results returned by the {@link - * #getLatencyBasedSampledSpans(LatencyBasedSampledSpansFilter)} request. + * #getLatencySampledSpans(LatencyFilter)} request. */ @AutoValue @Immutable - public abstract static class LatencyBasedSampledSpansFilter { + public abstract static class LatencyFilter { - LatencyBasedSampledSpansFilter() {} + LatencyFilter() {} /** - * Returns a new instance of {@code LatencyBasedSampledSpansFilter}. + * Returns a new instance of {@code LatencyFilter}. * *

            Filters all the spans based on {@code spanName} and latency in the interval * [latencyLowerNs, latencyUpperNs) and returns a maximum of {@code maxSpansToReturn}. @@ -318,17 +254,17 @@ public abstract static class LatencyBasedSampledSpansFilter { * @param latencyLowerNs the latency lower bound. * @param latencyUpperNs the latency upper bound. * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. - * @return a new instance of {@code LatencyBasedSampledSpansFilter}. + * @return a new instance of {@code LatencyFilter}. * @throws NullPointerException if {@code spanName} is {@code null}. * @throws IllegalArgumentException if {@code maxSpansToReturn} or {@code latencyLowerNs} or * {@code latencyUpperNs} are negative. */ - public static LatencyBasedSampledSpansFilter create( + public static LatencyFilter create( String spanName, long latencyLowerNs, long latencyUpperNs, int maxSpansToReturn) { checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); checkArgument(latencyLowerNs >= 0, "Negative latencyLowerNs"); checkArgument(latencyUpperNs >= 0, "Negative latencyUpperNs"); - return new AutoValue_InProcessDebuggingHandler_LatencyBasedSampledSpansFilter( + return new AutoValue_SampledSpanStore_LatencyFilter( spanName, latencyLowerNs, latencyUpperNs, maxSpansToReturn); } @@ -361,15 +297,18 @@ public static LatencyBasedSampledSpansFilter create( public abstract int getMaxSpansToReturn(); } - /** Filter for error based sampled spans. */ + /** + * Filter for error based sampled spans. Used to filter results returned by the {@link + * #getErrorSampledSpans(ErrorFilter)} request. + */ @AutoValue @Immutable - public abstract static class ErrorBasedSampledSpansFilter { + public abstract static class ErrorFilter { - ErrorBasedSampledSpansFilter() {} + ErrorFilter() {} /** - * Returns a new instance of {@code ErrorBasedSampledSpansFilter}. + * Returns a new instance of {@code ErrorFilter}. * *

            Filters all the spans based on {@code spanName} and {@code canonicalCode} and returns a * maximum of {@code maxSpansToReturn}. @@ -377,17 +316,16 @@ public abstract static class ErrorBasedSampledSpansFilter { * @param spanName the name of the span. * @param canonicalCode the error code of the span. * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. - * @return a new instance of {@code ErrorBasedSampledSpansFilter}. + * @return a new instance of {@code ErrorFilter}. * @throws NullPointerException if {@code spanName} or {@code canonicalCode} are {@code null}. * @throws IllegalArgumentException if {@code canonicalCode} is {@link CanonicalCode#OK} or * {@code maxSpansToReturn} is negative. */ - public static ErrorBasedSampledSpansFilter create( + public static ErrorFilter create( String spanName, CanonicalCode canonicalCode, int maxSpansToReturn) { checkArgument(canonicalCode != CanonicalCode.OK, "Invalid canonical code."); checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); - return new AutoValue_InProcessDebuggingHandler_ErrorBasedSampledSpansFilter( - spanName, canonicalCode, maxSpansToReturn); + return new AutoValue_SampledSpanStore_ErrorFilter(spanName, canonicalCode, maxSpansToReturn); } /** diff --git a/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java b/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java index 4125801c3c..f3a3b13726 100644 --- a/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java +++ b/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java @@ -29,8 +29,12 @@ public void implementationOfSpanExporter() { assertThat(exportComponent.getSpanExporter()).isEqualTo(SpanExporter.getNoopSpanExporter()); } + public void implementationOfActiveSpans() { + assertThat(exportComponent.getActiveSpansExporter()).isNull(); + } + @Test - public void implementationOfInProcessDebuggingHandler() { - assertThat(exportComponent.getInProcessDebuggingHandler()).isNull(); + public void implementationOfSampledSpanStore() { + assertThat(exportComponent.getSampledSpanStore()).isNull(); } } diff --git a/core_impl/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java b/core_impl/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java index 7bac1a001f..a6286083bb 100644 --- a/core_impl/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java @@ -13,16 +13,9 @@ package io.opencensus.trace.export; -import io.opencensus.internal.EventQueue; -import io.opencensus.trace.SpanImpl.StartEndHandler; import javax.annotation.Nullable; -/** - * Implementation of the {@link ExportComponent}, implements also {@link StartEndHandler}. - * - *

            Uses the provided {@link EventQueue} to defer processing/exporting of the {@link SpanData} to - * avoid impacting the critical path. - */ +/** Implementation of the {@link ExportComponent}. */ public final class ExportComponentImpl extends ExportComponent { private static final int EXPORTER_BUFFER_SIZE = 32; // Enforces that trace export exports data at least once every 2 seconds. @@ -37,7 +30,14 @@ public SpanExporterImpl getSpanExporter() { @Nullable @Override - public InProcessDebuggingHandler getInProcessDebuggingHandler() { + public ActiveSpansExporter getActiveSpansExporter() { + // TODO(bdrutu): Implement this. + return null; + } + + @Nullable + @Override + public SampledSpanStore getSampledSpanStore() { // TODO(bdrutu): Implement this. return null; } diff --git a/core_impl/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java b/core_impl/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java index 860b8af068..52e578d55a 100644 --- a/core_impl/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java +++ b/core_impl/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java @@ -30,7 +30,14 @@ public void implementationOfSpanExporter() { } @Test - public void implementationOfInProcessDebuggingHandler() { - assertThat(exportComponent.getInProcessDebuggingHandler()).isNull(); + public void implementationOfActiveSpans() { + // TODO(bdrutu): Change this when implementation is available. + assertThat(exportComponent.getActiveSpansExporter()).isNull(); + } + + @Test + public void implementationOfSampledSpanStore() { + // TODO(bdrutu): Change this when implementation is available. + assertThat(exportComponent.getSampledSpanStore()).isNull(); } } From 1a7b4b5286a12796b3af946ff186b72e8e26b2e7 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 14 Jun 2017 13:16:03 -0700 Subject: [PATCH 0167/1581] Add an IntrusiveList implementation to be used to implement ActiveSpans. (#353) --- .../java/io/opencensus/trace/SpanImpl.java | 27 ++- .../internal/ConcurrentIntrusiveList.java | 174 ++++++++++++++++++ .../internal/ConcurrentIntrusiveListTest.java | 119 ++++++++++++ 3 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 core_impl/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java create mode 100644 core_impl/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java index 11efb30bb9..269eb76764 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java @@ -30,6 +30,7 @@ import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.export.SpanData; import io.opencensus.trace.export.SpanData.TimedEvent; +import io.opencensus.trace.internal.ConcurrentIntrusiveList.Element; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; @@ -44,7 +45,7 @@ /** Implementation for the {@link Span} class. */ @ThreadSafe -public final class SpanImpl extends Span { +public final class SpanImpl extends Span implements Element { private static final Logger logger = Logger.getLogger(Tracer.class.getName()); // The parent SpanId of this span. Null if this is a root. @@ -88,6 +89,10 @@ public final class SpanImpl extends Span { @GuardedBy("this") private boolean hasBeenEnded; + // Pointers for the ConcurrentIntrusiveList$Element. Guarded by the ConcurrentIntrusiveList. + private SpanImpl next = null; + private SpanImpl prev = null; + /** * Creates and starts a span with the given configuration. TimestampConverter is null if the * {@code Span} is a root span or the parent is not sampled. If the parent is sampled we should @@ -325,6 +330,26 @@ private static SpanData.TimedEvents createTimedEvents( return SpanData.TimedEvents.create(eventsList, events.getNumberOfDroppedEvents()); } + @Override + public SpanImpl getNext() { + return next; + } + + @Override + public void setNext(SpanImpl element) { + next = element; + } + + @Override + public SpanImpl getPrev() { + return prev; + } + + @Override + public void setPrev(SpanImpl element) { + prev = element; + } + /** * Interface to handle the start and end operations for a {@link Span} only when the {@code Span} * has {@link Span.Options#RECORD_EVENTS} option. diff --git a/core_impl/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java b/core_impl/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java new file mode 100644 index 0000000000..5b0bc134eb --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java @@ -0,0 +1,174 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.internal; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.opencensus.trace.internal.ConcurrentIntrusiveList.Element; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import javax.annotation.concurrent.ThreadSafe; + +/** + * An {@code ConcurrentIntrusiveList} is a doubly-linked list where the link pointers are + * embedded in the elements. This makes insertion and removal into a known position constant time. + * + *

            Elements must derive from the {@code Element>} interface: + * + *

            {@code
            + * class MyClass implements Element {
            + *   private MyClass next = null;
            + *   private MyClass prev = null;
            + *
            + *   {@literal @}Override
            + *   MyClass getNext() {
            + *     return next;
            + *   }
            + *
            + *   {@literal @}Override
            + *   void setNext(MyClass element) {
            + *     next = element;
            + *   }
            + *
            + *   {@literal @}Override
            + *   MyClass getPrev() {
            + *     return prev;
            + *   }
            + *
            + *   {@literal @}Override
            + *   void setPrev(MyClass element) {
            + *     prev = element;
            + *   }
            + * }
            + * }
            + */ +@ThreadSafe +public final class ConcurrentIntrusiveList> { + private int size = 0; + private T head = null; + + public ConcurrentIntrusiveList() {} + + /** + * Adds the given {@code element} to the list. + * + * @param element the element to add. + * @throws IllegalArgumentException if the element is already in a list. + */ + public synchronized void addElement(T element) { + checkArgument( + element.getNext() == null && element.getPrev() == null && element != head, + "Element already in a list."); + size++; + if (head == null) { + head = element; + } else { + element.setNext(head); + head.setPrev(element); + head = element; + } + } + + /** + * Removes the given {@code element} from the list. + * + * @param element the element to remove. + * @throws IllegalArgumentException if the element is not in the list. + */ + public synchronized void removeElement(T element) { + checkArgument( + element.getNext() != null || element.getPrev() != null || element == head, + "Element not in the list."); + size--; + if (element.getPrev() == null) { + // This is the first element + head = element.getNext(); + if (head != null) { + // If more than one element in the list. + head.setPrev(null); + element.setNext(null); + } + } else if (element.getNext() == null) { + // This is the last element, and there is at least another element because + // element.getPrev() != null. + element.getPrev().setNext(null); + element.setPrev(null); + } else { + element.getPrev().setNext(element.getNext()); + element.getNext().setPrev(element.getPrev()); + element.setNext(null); + element.setPrev(null); + } + } + + /** + * Returns the number of elements in this list. + * + * @return the number of elements in this list. + */ + public synchronized int size() { + return size; + } + + /** + * Returns all the elements from this list. + * + * @return all the elements from this list. + */ + public synchronized Collection getAll() { + List all = new ArrayList(size); + for (T e = head; e != null; e = e.getNext()) { + all.add(e); + } + return all; + } + + /** + * This is an interface that must be implemented by any element that uses {@link + * ConcurrentIntrusiveList}. + * + * @param the element that will be used for the list. + */ + public interface Element> { + + /** + * Returns a reference to the next element in the list. + * + * @return a reference to the next element in the list. + */ + T getNext(); + + /** + * Sets the reference to the next element in the list. + * + * @param element the reference to the next element in the list. + */ + void setNext(T element); + + /** + * Returns a reference to the previous element in the list. + * + * @return a reference to the previous element in the list. + */ + T getPrev(); + + /** + * Sets the reference to the previous element in the list. + * + * @param element the reference to the previous element in the list. + */ + void setPrev(T element); + } +} diff --git a/core_impl/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java b/core_impl/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java new file mode 100644 index 0000000000..d1c13ad095 --- /dev/null +++ b/core_impl/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java @@ -0,0 +1,119 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.internal; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.trace.internal.ConcurrentIntrusiveList.Element; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link ConcurrentIntrusiveList}. */ +@RunWith(JUnit4.class) +public class ConcurrentIntrusiveListTest { + private final ConcurrentIntrusiveList intrusiveList = + new ConcurrentIntrusiveList(); + @Rule public final ExpectedException exception = ExpectedException.none(); + + @Test + public void emptyList() { + assertThat(intrusiveList.size()).isEqualTo(0); + assertThat(intrusiveList.getAll().isEmpty()).isTrue(); + } + + @Test + public void addRemoveAdd_SameElement() { + FakeElement element = new FakeElement(); + intrusiveList.addElement(element); + assertThat(intrusiveList.size()).isEqualTo(1); + intrusiveList.removeElement(element); + assertThat(intrusiveList.size()).isEqualTo(0); + intrusiveList.addElement(element); + assertThat(intrusiveList.size()).isEqualTo(1); + } + + @Test + public void addAndRemoveElements() { + FakeElement element1 = new FakeElement(); + FakeElement element2 = new FakeElement(); + FakeElement element3 = new FakeElement(); + intrusiveList.addElement(element1); + intrusiveList.addElement(element2); + intrusiveList.addElement(element3); + assertThat(intrusiveList.size()).isEqualTo(3); + assertThat(intrusiveList.getAll()).containsExactly(element3, element2, element1).inOrder(); + // Remove element from the middle of the list. + intrusiveList.removeElement(element2); + assertThat(intrusiveList.size()).isEqualTo(2); + assertThat(intrusiveList.getAll()).containsExactly(element3, element1).inOrder(); + // Remove element from the tail of the list. + intrusiveList.removeElement(element1); + assertThat(intrusiveList.size()).isEqualTo(1); + assertThat(intrusiveList.getAll().contains(element3)).isTrue(); + intrusiveList.addElement(element1); + assertThat(intrusiveList.size()).isEqualTo(2); + assertThat(intrusiveList.getAll()).containsExactly(element1, element3).inOrder(); + // Remove element from the head of the list when there are other elements after. + intrusiveList.removeElement(element1); + assertThat(intrusiveList.size()).isEqualTo(1); + assertThat(intrusiveList.getAll().contains(element3)).isTrue(); + // Remove element from the head of the list when no more other elements in the list. + intrusiveList.removeElement(element3); + assertThat(intrusiveList.size()).isEqualTo(0); + assertThat(intrusiveList.getAll().isEmpty()).isTrue(); + } + + @Test + public void addAlreadyAddedElement() { + FakeElement element = new FakeElement(); + intrusiveList.addElement(element); + exception.expect(IllegalArgumentException.class); + intrusiveList.addElement(element); + } + + @Test + public void removeNotAddedElement() { + FakeElement element = new FakeElement(); + exception.expect(IllegalArgumentException.class); + intrusiveList.removeElement(element); + } + + private static final class FakeElement implements Element { + private FakeElement next = null; + private FakeElement prev = null; + + @Override + public FakeElement getNext() { + return next; + } + + @Override + public void setNext(FakeElement element) { + next = element; + } + + @Override + public FakeElement getPrev() { + return prev; + } + + @Override + public void setPrev(FakeElement element) { + prev = element; + } + } +} From 461b4ed4a37e74a42c8ba6264807a15e36ab9dc6 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 14 Jun 2017 16:25:07 -0700 Subject: [PATCH 0168/1581] Remove method left unintentionally. (#355) --- .../io/opencensus/trace/export/ActiveSpansExporter.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/export/ActiveSpansExporter.java b/api/src/main/java/io/opencensus/trace/export/ActiveSpansExporter.java index bb2edb31c5..c6c5b8da3d 100644 --- a/api/src/main/java/io/opencensus/trace/export/ActiveSpansExporter.java +++ b/api/src/main/java/io/opencensus/trace/export/ActiveSpansExporter.java @@ -44,13 +44,6 @@ protected ActiveSpansExporter() {} */ public abstract Summary getSummary(); - /** - * Returns the number of active spans for every span name. - * - * @return the number of active spans for every span name. - */ - public abstract Map getNumberOfActiveSpans(); - /** * Returns a list of active spans that match the {@code Filter}. * From 3b74070f74a75e780828370126b713524eece13c Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 15 Jun 2017 11:29:30 -0700 Subject: [PATCH 0169/1581] Prepare the release of the opencensus library. (#357) --- all/build.gradle | 5 ++++- .../java/io/opencensus/common/Internal.java | 4 ++-- benchmarks/build.gradle | 6 +++--- core/README.md | 2 +- core_impl/README.md | 2 +- core_impl/build.gradle | 10 +++++++--- core_impl_android/README.md | 2 +- core_impl_java/README.md | 2 +- core_impl_java/build.gradle | 6 ++---- impl/README.md | 5 +++++ impl/build.gradle | 18 ++++++++++++++++++ .../internal/DisruptorEventQueue.java | 0 .../opencensus/trace/TraceComponentImpl.java | 0 .../internal/ThreadLocalRandomHandler.java | 0 .../internal/DisruptorEventQueueTest.java | 0 .../java/io/opencensus/trace/TracingTest.java | 0 impl_core/README.md | 5 +++++ impl_core/build.gradle | 13 +++++++++++++ .../java/io/opencensus/common/MillisClock.java | 0 .../io/opencensus/internal/EventQueue.java | 0 .../opencensus/internal/SimpleEventQueue.java | 0 .../internal/TimestampConverter.java | 0 .../java/io/opencensus/internal/VarInt.java | 0 .../io/opencensus/internal/package-info.java | 0 .../io/opencensus/trace/SpanFactoryImpl.java | 2 +- .../java/io/opencensus/trace/SpanImpl.java | 6 +++--- .../opencensus/trace/StartEndHandlerImpl.java | 0 .../trace/TraceComponentImplBase.java | 0 .../java/io/opencensus/trace/TracerImpl.java | 0 .../trace/config/TraceConfigImpl.java | 0 .../trace/export/ExportComponentImpl.java | 0 .../trace/export/SpanExporterImpl.java | 0 .../internal/ConcurrentIntrusiveList.java | 0 .../trace/internal/RandomHandler.java | 0 .../trace/propagation/BinaryFormatImpl.java | 0 .../propagation/PropagationComponentImpl.java | 0 .../internal/TimestampConverterTest.java | 0 .../opencensus/trace/SpanFactoryImplTest.java | 0 .../java/io/opencensus/trace/SpanImplTest.java | 0 .../trace/TraceComponentImplBaseTest.java | 0 .../trace/config/TraceConfigImplTest.java | 0 .../trace/export/ExportComponentImplTest.java | 0 .../trace/export/SpanExporterImplTest.java | 0 .../internal/ConcurrentIntrusiveListTest.java | 0 .../propagation/BinaryFormatImplTest.java | 0 .../PropagationComponentImplTest.java | 0 impl_lite/README.md | 6 ++++++ impl_lite/build.gradle | 8 ++++++++ .../opencensus/trace/TraceComponentImpl.java | 0 .../trace/TraceComponentImplTest.java | 0 settings.gradle | 8 +++++++- 51 files changed, 88 insertions(+), 22 deletions(-) create mode 100644 impl/README.md create mode 100644 impl/build.gradle rename {core_impl_java => impl}/src/main/java/io/opencensus/internal/DisruptorEventQueue.java (100%) rename {core_impl_java => impl}/src/main/java/io/opencensus/trace/TraceComponentImpl.java (100%) rename {core_impl_java => impl}/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java (100%) rename {core_impl_java => impl}/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java (100%) rename {core_impl_java => impl}/src/test/java/io/opencensus/trace/TracingTest.java (100%) create mode 100644 impl_core/README.md create mode 100644 impl_core/build.gradle rename {core_impl => impl_core}/src/main/java/io/opencensus/common/MillisClock.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/internal/EventQueue.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/internal/SimpleEventQueue.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/internal/TimestampConverter.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/internal/VarInt.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/internal/package-info.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/SpanFactoryImpl.java (98%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/SpanImpl.java (98%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/TraceComponentImplBase.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/TracerImpl.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/export/SpanExporterImpl.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/internal/RandomHandler.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java (100%) rename {core_impl => impl_core}/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java (100%) rename {core_impl => impl_core}/src/test/java/io/opencensus/internal/TimestampConverterTest.java (100%) rename {core_impl => impl_core}/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java (100%) rename {core_impl => impl_core}/src/test/java/io/opencensus/trace/SpanImplTest.java (100%) rename {core_impl => impl_core}/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java (100%) rename {core_impl => impl_core}/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java (100%) rename {core_impl => impl_core}/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java (100%) rename {core_impl => impl_core}/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java (100%) rename {core_impl => impl_core}/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java (100%) rename {core_impl => impl_core}/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java (100%) rename {core_impl => impl_core}/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java (100%) create mode 100644 impl_lite/README.md create mode 100644 impl_lite/build.gradle rename {core_impl_android => impl_lite}/src/main/java/io/opencensus/trace/TraceComponentImpl.java (100%) rename {core_impl_android => impl_lite}/src/test/java/io/opencensus/trace/TraceComponentImplTest.java (100%) diff --git a/all/build.gradle b/all/build.gradle index 86f96814ec..ebd032774b 100644 --- a/all/build.gradle +++ b/all/build.gradle @@ -1,6 +1,6 @@ apply plugin: 'com.github.kt3k.coveralls' -description = "Instrumentation: All" +description = "OpenCensus All" buildscript { repositories { @@ -16,8 +16,10 @@ buildscript { def subprojects = [ project(':opencensus-api'), project(':core'), + project(':opencensus-impl-core'), project(':core_impl'), project(':core_impl_java'), + project(':opencensus-impl'), ] for (subproject in rootProject.subprojects) { @@ -43,6 +45,7 @@ javadoc { options.links subproject.javadoc.options.links.toArray(new String[0]) } exclude 'io/opencensus/internal/**' + exclude 'io/opencensus/trace/internal/**' } task jacocoMerge(type: JacocoMerge) { diff --git a/api/src/main/java/io/opencensus/common/Internal.java b/api/src/main/java/io/opencensus/common/Internal.java index 9d540e21da..fee892c3fe 100644 --- a/api/src/main/java/io/opencensus/common/Internal.java +++ b/api/src/main/java/io/opencensus/common/Internal.java @@ -20,8 +20,8 @@ import java.lang.annotation.Target; /** - * Annotates a program element (class, method, package etc) which is internal to opencensus, not - * part of the public API, and should not be used by users of the opencensus library. + * Annotates a program element (class, method, package etc) which is internal to OpenCensus, not + * part of the public API, and should not be used by users of the OpenCensus library. */ @Internal @Retention(RetentionPolicy.SOURCE) diff --git a/benchmarks/build.gradle b/benchmarks/build.gradle index 5203885a22..62fda00c2b 100644 --- a/benchmarks/build.gradle +++ b/benchmarks/build.gradle @@ -23,9 +23,9 @@ jmh { } dependencies { - compile project(':core'), - project(':core_impl') - project(':core_impl_java') + compile project(':opencensus-api'), + project(':opencensus-impl-core') + project(':opencensus-impl') } compileJmhJava { diff --git a/core/README.md b/core/README.md index b4dfea1886..2109a4bde9 100644 --- a/core/README.md +++ b/core/README.md @@ -1,4 +1,4 @@ -Instrumentation API +Will be ported to io.opencensus soon in api/. ====================================================== * Java 6 and Android compatible. diff --git a/core_impl/README.md b/core_impl/README.md index 901177c82d..4d4c64e7ce 100644 --- a/core_impl/README.md +++ b/core_impl/README.md @@ -1,4 +1,4 @@ -OpenCensus implementation +Will be ported to io.opencensus soon in impl_core/. ====================================================== * The main implementation shared between Java and Android. diff --git a/core_impl/build.gradle b/core_impl/build.gradle index 65a752a431..73593aa2b6 100644 --- a/core_impl/build.gradle +++ b/core_impl/build.gradle @@ -2,13 +2,17 @@ description = 'OpenCensus Core Impl' dependencies { compile project(':core'), + project(':opencensus-api'), + project(':opencensus-impl-core'), libraries.guava - compileOnly libraries.auto_value - testCompile project(':core') signature "org.codehaus.mojo.signature:java16:+@signature" } -javadoc.exclude 'io/opencensus/internal/**' \ No newline at end of file +// Disable javadoc because fails with the error: +// javadoc: error - No public or protected classes found to document. +javadoc { + enabled = false +} \ No newline at end of file diff --git a/core_impl_android/README.md b/core_impl_android/README.md index ad7bb9b165..f7ec5cdda7 100644 --- a/core_impl_android/README.md +++ b/core_impl_android/README.md @@ -1,4 +1,4 @@ -OpenCensus Android implementation +Will be ported to io.opencensus soon in impl_lite/. ====================================================== * Android compatible. diff --git a/core_impl_java/README.md b/core_impl_java/README.md index 3dee26f9de..0a33eee118 100644 --- a/core_impl_java/README.md +++ b/core_impl_java/README.md @@ -1,4 +1,4 @@ -OpenCensus Java implementation +Will be ported to io.opencensus soon in impl/. ====================================================== * Java 7 compatible. diff --git a/core_impl_java/build.gradle b/core_impl_java/build.gradle index da47efc578..4c17d2b50f 100644 --- a/core_impl_java/build.gradle +++ b/core_impl_java/build.gradle @@ -10,9 +10,7 @@ apply plugin: 'java' dependencies { compile project(':core'), project(':core_impl'), - libraries.disruptor + project(':opencensus-impl') signature "org.codehaus.mojo.signature:java17:+@signature" -} - -javadoc.exclude 'io/opencensus/internal/**' \ No newline at end of file +} \ No newline at end of file diff --git a/impl/README.md b/impl/README.md new file mode 100644 index 0000000000..3dee26f9de --- /dev/null +++ b/impl/README.md @@ -0,0 +1,5 @@ +OpenCensus Java implementation +====================================================== + +* Java 7 compatible. +* Contains any classes not compatible with Android. diff --git a/impl/build.gradle b/impl/build.gradle new file mode 100644 index 0000000000..be4e959cdc --- /dev/null +++ b/impl/build.gradle @@ -0,0 +1,18 @@ +description = 'OpenCensus Implementation' + +apply plugin: 'java' + +[compileJava, compileTestJava].each() { + it.sourceCompatibility = 1.7 + it.targetCompatibility = 1.7 +} + +dependencies { + compile project(':opencensus-api'), + project(':opencensus-impl-core'), + libraries.disruptor + + signature "org.codehaus.mojo.signature:java17:+@signature" +} + +javadoc.exclude 'io/opencensus/internal/**' \ No newline at end of file diff --git a/core_impl_java/src/main/java/io/opencensus/internal/DisruptorEventQueue.java b/impl/src/main/java/io/opencensus/internal/DisruptorEventQueue.java similarity index 100% rename from core_impl_java/src/main/java/io/opencensus/internal/DisruptorEventQueue.java rename to impl/src/main/java/io/opencensus/internal/DisruptorEventQueue.java diff --git a/core_impl_java/src/main/java/io/opencensus/trace/TraceComponentImpl.java b/impl/src/main/java/io/opencensus/trace/TraceComponentImpl.java similarity index 100% rename from core_impl_java/src/main/java/io/opencensus/trace/TraceComponentImpl.java rename to impl/src/main/java/io/opencensus/trace/TraceComponentImpl.java diff --git a/core_impl_java/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java b/impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java similarity index 100% rename from core_impl_java/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java rename to impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java diff --git a/core_impl_java/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java b/impl/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java similarity index 100% rename from core_impl_java/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java rename to impl/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java diff --git a/core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java b/impl/src/test/java/io/opencensus/trace/TracingTest.java similarity index 100% rename from core_impl_java/src/test/java/io/opencensus/trace/TracingTest.java rename to impl/src/test/java/io/opencensus/trace/TracingTest.java diff --git a/impl_core/README.md b/impl_core/README.md new file mode 100644 index 0000000000..901177c82d --- /dev/null +++ b/impl_core/README.md @@ -0,0 +1,5 @@ +OpenCensus implementation +====================================================== + +* The main implementation shared between Java and Android. +* Java 7 and Android compatible. diff --git a/impl_core/build.gradle b/impl_core/build.gradle new file mode 100644 index 0000000000..70de8aa63e --- /dev/null +++ b/impl_core/build.gradle @@ -0,0 +1,13 @@ +description = 'OpenCensus Core Implementation' + +dependencies { + compile project(':opencensus-api'), + libraries.guava + + compileOnly libraries.auto_value + + signature "org.codehaus.mojo.signature:java16:+@signature" +} + +javadoc.exclude 'io/opencensus/internal/**' +javadoc.exclude 'io/opencensus/trace/internal/**' \ No newline at end of file diff --git a/core_impl/src/main/java/io/opencensus/common/MillisClock.java b/impl_core/src/main/java/io/opencensus/common/MillisClock.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/common/MillisClock.java rename to impl_core/src/main/java/io/opencensus/common/MillisClock.java diff --git a/core_impl/src/main/java/io/opencensus/internal/EventQueue.java b/impl_core/src/main/java/io/opencensus/internal/EventQueue.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/internal/EventQueue.java rename to impl_core/src/main/java/io/opencensus/internal/EventQueue.java diff --git a/core_impl/src/main/java/io/opencensus/internal/SimpleEventQueue.java b/impl_core/src/main/java/io/opencensus/internal/SimpleEventQueue.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/internal/SimpleEventQueue.java rename to impl_core/src/main/java/io/opencensus/internal/SimpleEventQueue.java diff --git a/core_impl/src/main/java/io/opencensus/internal/TimestampConverter.java b/impl_core/src/main/java/io/opencensus/internal/TimestampConverter.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/internal/TimestampConverter.java rename to impl_core/src/main/java/io/opencensus/internal/TimestampConverter.java diff --git a/core_impl/src/main/java/io/opencensus/internal/VarInt.java b/impl_core/src/main/java/io/opencensus/internal/VarInt.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/internal/VarInt.java rename to impl_core/src/main/java/io/opencensus/internal/VarInt.java diff --git a/core_impl/src/main/java/io/opencensus/internal/package-info.java b/impl_core/src/main/java/io/opencensus/internal/package-info.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/internal/package-info.java rename to impl_core/src/main/java/io/opencensus/internal/package-info.java diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanFactoryImpl.java similarity index 98% rename from core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java rename to impl_core/src/main/java/io/opencensus/trace/SpanFactoryImpl.java index d9aadb5e37..4e816d975f 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanFactoryImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanFactoryImpl.java @@ -95,7 +95,7 @@ Span startSpanInternal( traceOptionsBuilder.setIsSampled(); } TraceOptions traceOptions = traceOptionsBuilder.build(); - EnumSet spanOptions = EnumSet.noneOf(Options.class); + EnumSet spanOptions = EnumSet.noneOf(Options.class); if (traceOptions.isSampled() || Boolean.TRUE.equals(startSpanOptions.getRecordEvents())) { spanOptions.add(Options.RECORD_EVENTS); } diff --git a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java similarity index 98% rename from core_impl/src/main/java/io/opencensus/trace/SpanImpl.java rename to impl_core/src/main/java/io/opencensus/trace/SpanImpl.java index 269eb76764..32992126e4 100644 --- a/core_impl/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java @@ -352,7 +352,7 @@ public void setPrev(SpanImpl element) { /** * Interface to handle the start and end operations for a {@link Span} only when the {@code Span} - * has {@link Span.Options#RECORD_EVENTS} option. + * has {@link Options#RECORD_EVENTS} option. * *

            Implementation must avoid high overhead work in any of the methods because the code is * executed on the critical path. @@ -430,8 +430,8 @@ private EventWithNanoTime(long nanoTime, T event) { this.event = event; } - private SpanData.TimedEvent toSpanDataTimedEvent(TimestampConverter timestampConverter) { - return SpanData.TimedEvent.create(timestampConverter.convertNanoTime(nanoTime), event); + private TimedEvent toSpanDataTimedEvent(TimestampConverter timestampConverter) { + return TimedEvent.create(timestampConverter.convertNanoTime(nanoTime), event); } } diff --git a/core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java rename to impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java diff --git a/core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java b/impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/trace/TraceComponentImplBase.java rename to impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java diff --git a/core_impl/src/main/java/io/opencensus/trace/TracerImpl.java b/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/trace/TracerImpl.java rename to impl_core/src/main/java/io/opencensus/trace/TracerImpl.java diff --git a/core_impl/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java b/impl_core/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java rename to impl_core/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java diff --git a/core_impl/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java rename to impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java diff --git a/core_impl/src/main/java/io/opencensus/trace/export/SpanExporterImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/SpanExporterImpl.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/trace/export/SpanExporterImpl.java rename to impl_core/src/main/java/io/opencensus/trace/export/SpanExporterImpl.java diff --git a/core_impl/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java b/impl_core/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java rename to impl_core/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java diff --git a/core_impl/src/main/java/io/opencensus/trace/internal/RandomHandler.java b/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/trace/internal/RandomHandler.java rename to impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java diff --git a/core_impl/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java b/impl_core/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java rename to impl_core/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java diff --git a/core_impl/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java b/impl_core/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java similarity index 100% rename from core_impl/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java rename to impl_core/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java diff --git a/core_impl/src/test/java/io/opencensus/internal/TimestampConverterTest.java b/impl_core/src/test/java/io/opencensus/internal/TimestampConverterTest.java similarity index 100% rename from core_impl/src/test/java/io/opencensus/internal/TimestampConverterTest.java rename to impl_core/src/test/java/io/opencensus/internal/TimestampConverterTest.java diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java similarity index 100% rename from core_impl/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java rename to impl_core/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java diff --git a/core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java similarity index 100% rename from core_impl/src/test/java/io/opencensus/trace/SpanImplTest.java rename to impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java diff --git a/core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java b/impl_core/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java similarity index 100% rename from core_impl/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java rename to impl_core/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java diff --git a/core_impl/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java b/impl_core/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java similarity index 100% rename from core_impl/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java rename to impl_core/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java diff --git a/core_impl/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java similarity index 100% rename from core_impl/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java rename to impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java diff --git a/core_impl/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java similarity index 100% rename from core_impl/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java rename to impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java diff --git a/core_impl/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java b/impl_core/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java similarity index 100% rename from core_impl/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java rename to impl_core/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java diff --git a/core_impl/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java b/impl_core/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java similarity index 100% rename from core_impl/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java rename to impl_core/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java diff --git a/core_impl/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java b/impl_core/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java similarity index 100% rename from core_impl/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java rename to impl_core/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java diff --git a/impl_lite/README.md b/impl_lite/README.md new file mode 100644 index 0000000000..ad7bb9b165 --- /dev/null +++ b/impl_lite/README.md @@ -0,0 +1,6 @@ +OpenCensus Android implementation +====================================================== + +* Android compatible. +* StatsManager specifies the stats implementation classes that should be used + with Android. diff --git a/impl_lite/build.gradle b/impl_lite/build.gradle new file mode 100644 index 0000000000..40cce82a82 --- /dev/null +++ b/impl_lite/build.gradle @@ -0,0 +1,8 @@ +description = 'OpenCensus Lite Implementation' + +dependencies { + compile project(':opencensus-api'), + project(':opencensus-impl-core') + + signature "net.sf.androidscents.signature:android-api-level-14:+@signature" +} diff --git a/core_impl_android/src/main/java/io/opencensus/trace/TraceComponentImpl.java b/impl_lite/src/main/java/io/opencensus/trace/TraceComponentImpl.java similarity index 100% rename from core_impl_android/src/main/java/io/opencensus/trace/TraceComponentImpl.java rename to impl_lite/src/main/java/io/opencensus/trace/TraceComponentImpl.java diff --git a/core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java b/impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplTest.java similarity index 100% rename from core_impl_android/src/test/java/io/opencensus/trace/TraceComponentImplTest.java rename to impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplTest.java diff --git a/settings.gradle b/settings.gradle index ade14ea5e3..e7a8c4c4b6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,9 @@ -rootProject.name = "instrumentation-java" +rootProject.name = "opencensus-java" include ":opencensus-api" +include ":opencensus-impl-core" +include ":opencensus-impl-lite" +include ":opencensus-impl" include ":all" include ":core" include ":core_impl" @@ -8,6 +11,9 @@ include ":core_impl_java" include ":core_impl_android" project(':opencensus-api').projectDir = "$rootDir/api" as File +project(':opencensus-impl-core').projectDir = "$rootDir/impl_core" as File +project(':opencensus-impl-lite').projectDir = "$rootDir/impl_lite" as File +project(':opencensus-impl').projectDir = "$rootDir/impl" as File // Java8 projects only if (JavaVersion.current().isJava8Compatible()) { From 5484bd0904ceb4950ed3ccd3b4c993ed2d4a8813 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 15 Jun 2017 17:09:30 -0700 Subject: [PATCH 0170/1581] Add support to load lite or full implementations. (#360) --- .../java/io/opencensus/trace/Tracing.java | 20 ++++++- .../java/io/opencensus/trace/TracingTest.java | 4 +- .../google/instrumentation/stats/Stats.java | 56 ++++++++++++++----- .../instrumentation/stats/StatsTest.java | 44 +++++++++++++-- ...gerImpl.java => StatsManagerImplLite.java} | 4 +- .../instrumentation/stats/StatsTest.java | 5 ++ .../instrumentation/stats/StatsTest.java | 6 ++ ...tImpl.java => TraceComponentImplLite.java} | 4 +- ...t.java => TraceComponentImplLiteTest.java} | 4 +- 9 files changed, 117 insertions(+), 30 deletions(-) rename core_impl_android/src/main/java/com/google/instrumentation/stats/{StatsManagerImpl.java => StatsManagerImplLite.java} (89%) rename impl_lite/src/main/java/io/opencensus/trace/{TraceComponentImpl.java => TraceComponentImplLite.java} (89%) rename impl_lite/src/test/java/io/opencensus/trace/{TraceComponentImplTest.java => TraceComponentImplLiteTest.java} (94%) diff --git a/api/src/main/java/io/opencensus/trace/Tracing.java b/api/src/main/java/io/opencensus/trace/Tracing.java index 3a4be46350..5255450a87 100644 --- a/api/src/main/java/io/opencensus/trace/Tracing.java +++ b/api/src/main/java/io/opencensus/trace/Tracing.java @@ -24,7 +24,7 @@ /** Class that manages a global instance of the {@link TraceComponent}. */ public final class Tracing { - private static final Logger logger = Logger.getLogger(Tracer.class.getName()); + private static final Logger logger = Logger.getLogger(Tracing.class.getName()); private static final TraceComponent traceComponent = loadTraceComponent(Provider.getCorrectClassLoader(TraceComponent.class)); @@ -82,7 +82,23 @@ static TraceComponent loadTraceComponent(ClassLoader classLoader) { Class.forName("io.opencensus.trace.TraceComponentImpl", true, classLoader), TraceComponent.class); } catch (ClassNotFoundException e) { - logger.log(Level.FINE, "Using default implementation for TraceComponent.", e); + logger.log( + Level.FINE, + "Couldn't load full implementation for TraceComponent, now trying to load lite " + + "implementation.", + e); + } + try { + // Call Class.forName with literal string name of the class to help shading tools. + return Provider.createInstance( + Class.forName("io.opencensus.trace.TraceComponentImplLite", true, classLoader), + TraceComponent.class); + } catch (ClassNotFoundException e) { + logger.log( + Level.FINE, + "Couldn't load lite implementation for TraceComponent, now using " + + "default implementation for TraceComponent.", + e); } return TraceComponent.getNoopTraceComponent(); } diff --git a/api/src/test/java/io/opencensus/trace/TracingTest.java b/api/src/test/java/io/opencensus/trace/TracingTest.java index 33303896a8..14e2607ce1 100644 --- a/api/src/test/java/io/opencensus/trace/TracingTest.java +++ b/api/src/test/java/io/opencensus/trace/TracingTest.java @@ -30,7 +30,7 @@ public class TracingTest { @Rule public ExpectedException thrown = ExpectedException.none(); @Test - public void loadTraceService_UsesProvidedClassLoader() { + public void loadTraceComponent_UsesProvidedClassLoader() { final RuntimeException toThrow = new RuntimeException("UseClassLoader"); thrown.expect(RuntimeException.class); thrown.expectMessage("UseClassLoader"); @@ -44,7 +44,7 @@ public Class loadClass(String name) { } @Test - public void loadSpanFactory_IgnoresMissingClasses() { + public void loadTraceComponent_IgnoresMissingClasses() { assertThat( Tracing.loadTraceComponent( new ClassLoader() { diff --git a/core/src/main/java/com/google/instrumentation/stats/Stats.java b/core/src/main/java/com/google/instrumentation/stats/Stats.java index 90f366c897..618eaacaa5 100644 --- a/core/src/main/java/com/google/instrumentation/stats/Stats.java +++ b/core/src/main/java/com/google/instrumentation/stats/Stats.java @@ -13,34 +13,62 @@ package com.google.instrumentation.stats; +import com.google.common.annotations.VisibleForTesting; import io.opencensus.internal.Provider; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.annotation.Nullable; -/** - * {@link Stats}. - */ +/** {@link Stats}. */ public final class Stats { - private static final StatsManager statsManager = Provider.newInstance( - "com.google.instrumentation.stats.StatsManagerImpl", null); + private static final Logger logger = Logger.getLogger(Stats.class.getName()); + + private static final StatsManager statsManager = + loadStatsManager(Provider.getCorrectClassLoader(StatsManager.class)); - /** - * Returns the default {@link StatsContextFactory}. - */ + /** Returns the default {@link StatsContextFactory}. */ @Nullable public static StatsContextFactory getStatsContextFactory() { return statsManager == null ? null : statsManager.getStatsContextFactory(); } - /** - * Returns the default {@link StatsManager}. - */ + /** Returns the default {@link StatsManager}. */ @Nullable public static StatsManager getStatsManager() { return statsManager; } - // VisibleForTesting - Stats() { - throw new AssertionError(); + // Any provider that may be used for StatsManager can be added here. + @VisibleForTesting + @Nullable + static StatsManager loadStatsManager(ClassLoader classLoader) { + try { + // Call Class.forName with literal string name of the class to help shading tools. + return Provider.createInstance( + Class.forName("com.google.instrumentation.stats.StatsManagerImpl", true, classLoader), + StatsManager.class); + } catch (ClassNotFoundException e) { + logger.log( + Level.FINE, + "Couldn't load full implementation for StatsManager, now trying to load lite " + + "implementation.", + e); + } + try { + // Call Class.forName with literal string name of the class to help shading tools. + return Provider.createInstance( + Class.forName("com.google.instrumentation.stats.StatsManagerImplLite", true, classLoader), + StatsManager.class); + } catch (ClassNotFoundException e) { + logger.log( + Level.FINE, + "Couldn't load lite implementation for StatsManager, now using " + + "default implementation for StatsManager.", + e); + } + // TODO: Add a no-op implementation. + return null; } + + private Stats() {} } diff --git a/core/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core/src/test/java/com/google/instrumentation/stats/StatsTest.java index 598aafa469..2e2ca75526 100644 --- a/core/src/test/java/com/google/instrumentation/stats/StatsTest.java +++ b/core/src/test/java/com/google/instrumentation/stats/StatsTest.java @@ -13,17 +13,49 @@ package com.google.instrumentation.stats; +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link Stats}. - */ +/** Tests for {@link Stats}. */ @RunWith(JUnit4.class) public final class StatsTest { - @Test(expected = AssertionError.class) - public void testConstructor() { - new Stats(); + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void loadStatsManager_UsesProvidedClassLoader() { + final RuntimeException toThrow = new RuntimeException("UseClassLoader"); + thrown.expect(RuntimeException.class); + thrown.expectMessage("UseClassLoader"); + Stats.loadStatsManager( + new ClassLoader() { + @Override + public Class loadClass(String name) { + throw toThrow; + } + }); + } + + @Test + public void loadStatsManager_IgnoresMissingClasses() { + assertThat( + Stats.loadStatsManager( + new ClassLoader() { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + throw new ClassNotFoundException(); + } + })) + .isNull(); + } + + @Test + public void defaultValues() { + assertThat(Stats.getStatsContextFactory()).isNull(); + assertThat(Stats.getStatsManager()).isNull(); } } diff --git a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImplLite.java similarity index 89% rename from core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java rename to core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImplLite.java index da09d3bc50..874d56323c 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImplLite.java @@ -19,9 +19,9 @@ /** * Android-compatible implementation of {@link StatsManager}. */ -public final class StatsManagerImpl extends StatsManagerImplBase { +public final class StatsManagerImplLite extends StatsManagerImplBase { - public StatsManagerImpl() { + public StatsManagerImplLite() { // TODO(sebright): Use a more efficient queue implementation. super(new SimpleEventQueue(), MillisClock.getInstance()); } diff --git a/core_impl_android/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core_impl_android/src/test/java/com/google/instrumentation/stats/StatsTest.java index e5ed1d9ee4..be0118496e 100644 --- a/core_impl_android/src/test/java/com/google/instrumentation/stats/StatsTest.java +++ b/core_impl_android/src/test/java/com/google/instrumentation/stats/StatsTest.java @@ -24,6 +24,11 @@ */ @RunWith(JUnit4.class) public final class StatsTest { + @Test + public void getStatsManager() { + assertThat(Stats.getStatsManager()).isInstanceOf(StatsManagerImplLite.class); + } + @Test public void getStatsContextFactory() { assertThat(Stats.getStatsContextFactory()).isNotNull(); diff --git a/core_impl_java/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core_impl_java/src/test/java/com/google/instrumentation/stats/StatsTest.java index 6f968a65aa..efcff032ba 100644 --- a/core_impl_java/src/test/java/com/google/instrumentation/stats/StatsTest.java +++ b/core_impl_java/src/test/java/com/google/instrumentation/stats/StatsTest.java @@ -22,6 +22,12 @@ /** Test for accessing the {@link StatsManager} through the {@link Stats} class. */ @RunWith(JUnit4.class) public final class StatsTest { + @Test + public void getStatsManager() { + assertThat(Stats.getStatsManager()).isInstanceOf(StatsManagerImpl.class); + } + + @Test public void getStatsContextFactory() { assertThat(Stats.getStatsContextFactory()).isNotNull(); diff --git a/impl_lite/src/main/java/io/opencensus/trace/TraceComponentImpl.java b/impl_lite/src/main/java/io/opencensus/trace/TraceComponentImplLite.java similarity index 89% rename from impl_lite/src/main/java/io/opencensus/trace/TraceComponentImpl.java rename to impl_lite/src/main/java/io/opencensus/trace/TraceComponentImplLite.java index ca8065085f..c3d7100b42 100644 --- a/impl_lite/src/main/java/io/opencensus/trace/TraceComponentImpl.java +++ b/impl_lite/src/main/java/io/opencensus/trace/TraceComponentImplLite.java @@ -18,9 +18,9 @@ import io.opencensus.trace.internal.RandomHandler.SecureRandomHandler; /** Android-compatible implementation of the {@link TraceComponent}. */ -public final class TraceComponentImpl extends TraceComponentImplBase { +public final class TraceComponentImplLite extends TraceComponentImplBase { - public TraceComponentImpl() { + public TraceComponentImplLite() { super(MillisClock.getInstance(), new SecureRandomHandler(), new SimpleEventQueue()); } } diff --git a/impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplTest.java b/impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplLiteTest.java similarity index 94% rename from impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplTest.java rename to impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplLiteTest.java index 024e8692d1..65afe66bd2 100644 --- a/impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplTest.java +++ b/impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplLiteTest.java @@ -22,9 +22,9 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@link TraceComponentImpl}. */ +/** Unit tests for {@link TraceComponentImplLite}. */ @RunWith(JUnit4.class) -public class TraceComponentImplTest { +public class TraceComponentImplLiteTest { @Test public void implementationOfTracer() { assertThat(Tracing.getTracer()).isInstanceOf(TracerImpl.class); From 082fae281e0e9eb6df2cfc0b7121c932b2819364 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 15 Jun 2017 20:35:31 -0700 Subject: [PATCH 0171/1581] Add initial implementation of the ActiveSpansExporter. (#356) --- .../java/io/opencensus/trace/SpanImpl.java | 4 +- .../opencensus/trace/StartEndHandlerImpl.java | 78 +++++++-- .../trace/TraceComponentImplBase.java | 16 +- .../trace/export/ActiveSpansExporterImpl.java | 84 +++++++++ .../trace/export/ExportComponentImpl.java | 36 +++- .../trace/export/ActiveSpansExporterTest.java | 164 ++++++++++++++++++ .../trace/export/ExportComponentImplTest.java | 15 +- .../trace/export/SpanExporterImplTest.java | 4 +- 8 files changed, 373 insertions(+), 28 deletions(-) create mode 100644 impl_core/src/main/java/io/opencensus/trace/export/ActiveSpansExporterImpl.java create mode 100644 impl_core/src/test/java/io/opencensus/trace/export/ActiveSpansExporterTest.java diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java index 32992126e4..04003c56d9 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java @@ -133,7 +133,7 @@ public static SpanImpl startSpan( * * @return the name of the {@code Span}. */ - String getName() { + public String getName() { return name; } @@ -278,9 +278,9 @@ public void end(EndSpanOptions options) { } status = options.getStatus(); endNanoTime = clock.nowNanos(); - startEndHandler.onEnd(this); hasBeenEnded = true; } + startEndHandler.onEnd(this); } @GuardedBy("this") diff --git a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java index 454f08eeac..fb7071908a 100644 --- a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java @@ -14,51 +14,105 @@ package io.opencensus.trace; import io.opencensus.internal.EventQueue; +import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.export.ActiveSpansExporterImpl; +import io.opencensus.trace.export.SampledSpanStore; import io.opencensus.trace.export.SpanData; import io.opencensus.trace.export.SpanExporterImpl; +import javax.annotation.Nullable; +import javax.annotation.concurrent.ThreadSafe; /** * Uses the provided {@link EventQueue} to defer processing/exporting of the {@link SpanData} to * avoid impacting the critical path. */ +@ThreadSafe public final class StartEndHandlerImpl implements StartEndHandler { + private final SpanExporterImpl spanExporter; + private final ActiveSpansExporterImpl activeSpansExporter; + private final SampledSpanStore sampledSpanStore; private final EventQueue eventQueue; - private final SpanExporterImpl sampledSpansServiceExporter; + // true if any of (activeSpansExporter OR sampledSpanStore) are different than null, which + // means the spans with RECORD_EVENTS should be enqueued in the queue. + private final boolean enqueueEventForNonSampledSpans; + /** + * Constructs a new {@code StartEndHandlerImpl}. + * + * @param spanExporter the {@code SpanExporter} implementation. + * @param activeSpansExporter the {@code ActiveSpansExporter} implementation. + * @param sampledSpanStore the {@code SampledSpanStore} implementation. + * @param eventQueue the event queue where all the events are enqueued. + */ public StartEndHandlerImpl( - SpanExporterImpl sampledSpansServiceExporter, EventQueue eventQueue) { - this.sampledSpansServiceExporter = sampledSpansServiceExporter; + SpanExporterImpl spanExporter, + @Nullable ActiveSpansExporterImpl activeSpansExporter, + @Nullable SampledSpanStore sampledSpanStore, + EventQueue eventQueue) { + this.spanExporter = spanExporter; + this.activeSpansExporter = activeSpansExporter; + this.sampledSpanStore = sampledSpanStore; + this.enqueueEventForNonSampledSpans = activeSpansExporter != null || sampledSpanStore != null; this.eventQueue = eventQueue; } @Override public void onStart(SpanImpl span) { - // Do nothing. When ActiveSpans functionality is implemented this will change to record the - // Span into the ActiveSpans list. + if (span.getOptions().contains(Options.RECORD_EVENTS) && enqueueEventForNonSampledSpans) { + eventQueue.enqueue(new SpanStartEvent(span, activeSpansExporter)); + } } @Override public void onEnd(SpanImpl span) { - // TODO(bdrutu): Change to RECORD_EVENTS option when active/samples is supported. - if (span.getContext().getTraceOptions().isSampled()) { - eventQueue.enqueue(new SpanEndEvent(span, sampledSpansServiceExporter)); + if ((span.getOptions().contains(Options.RECORD_EVENTS) && enqueueEventForNonSampledSpans) + || span.getContext().getTraceOptions().isSampled()) { + eventQueue.enqueue( + new SpanEndEvent(span, spanExporter, activeSpansExporter, sampledSpanStore)); + } + } + + // An EventQueue entry that records the start of the span event. + private static final class SpanStartEvent implements EventQueue.Entry { + private final SpanImpl span; + private final ActiveSpansExporterImpl activeSpansExporter; + + SpanStartEvent(SpanImpl span, @Nullable ActiveSpansExporterImpl activeSpansExporter) { + this.span = span; + this.activeSpansExporter = activeSpansExporter; + } + + @Override + public void process() { + if (activeSpansExporter != null) { + activeSpansExporter.onStart(span); + } } } // An EventQueue entry that records the end of the span event. private static final class SpanEndEvent implements EventQueue.Entry { private final SpanImpl span; - private final SpanExporterImpl sampledSpansServiceExporter; + private final ActiveSpansExporterImpl activeSpansExporter; + private final SpanExporterImpl spanExporter; - SpanEndEvent(SpanImpl span, SpanExporterImpl sampledSpansServiceExporter) { + SpanEndEvent( + SpanImpl span, + SpanExporterImpl spanExporter, + @Nullable ActiveSpansExporterImpl activeSpansExporter, + @Nullable SampledSpanStore sampledSpanStore) { this.span = span; - this.sampledSpansServiceExporter = sampledSpansServiceExporter; + this.activeSpansExporter = activeSpansExporter; + this.spanExporter = spanExporter; } @Override public void process() { - sampledSpansServiceExporter.addSpan(span); + spanExporter.addSpan(span); + if (activeSpansExporter != null) { + activeSpansExporter.onEnd(span); + } } } } diff --git a/impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java b/impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java index 23a13269df..1448d40e19 100644 --- a/impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java +++ b/impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java @@ -15,6 +15,7 @@ import io.opencensus.common.Clock; import io.opencensus.internal.EventQueue; +import io.opencensus.internal.SimpleEventQueue; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceConfigImpl; @@ -26,7 +27,7 @@ /** Base implementation of the {@link TraceComponent}. */ class TraceComponentImplBase extends TraceComponent { - private final ExportComponentImpl exportComponent = new ExportComponentImpl(); + private final ExportComponentImpl exportComponent; private final PropagationComponent propagationComponent = new PropagationComponentImpl(); private final Clock clock; private final StartEndHandler startEndHandler; @@ -35,7 +36,18 @@ class TraceComponentImplBase extends TraceComponent { TraceComponentImplBase(Clock clock, RandomHandler randomHandler, EventQueue eventQueue) { this.clock = clock; - startEndHandler = new StartEndHandlerImpl(exportComponent.getSpanExporter(), eventQueue); + // TODO(bdrutu): Add a config/argument for supportInProcessStores. + if (eventQueue instanceof SimpleEventQueue) { + exportComponent = ExportComponentImpl.createWithoutInProcessStores(); + } else { + exportComponent = ExportComponentImpl.createWithInProcessStores(); + } + startEndHandler = + new StartEndHandlerImpl( + exportComponent.getSpanExporter(), + exportComponent.getActiveSpansExporter(), + exportComponent.getSampledSpanStore(), + eventQueue); tracer = new TracerImpl(randomHandler, startEndHandler, clock, traceConfig); } diff --git a/impl_core/src/main/java/io/opencensus/trace/export/ActiveSpansExporterImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/ActiveSpansExporterImpl.java new file mode 100644 index 0000000000..69332585c6 --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/trace/export/ActiveSpansExporterImpl.java @@ -0,0 +1,84 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.export; + +import io.opencensus.trace.SpanImpl; +import io.opencensus.trace.internal.ConcurrentIntrusiveList; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.concurrent.ThreadSafe; + +/** Implementation of the {@link ActiveSpansExporter}. */ +@ThreadSafe +public final class ActiveSpansExporterImpl extends ActiveSpansExporter { + private final ConcurrentIntrusiveList activeSpans; + + public ActiveSpansExporterImpl() { + activeSpans = new ConcurrentIntrusiveList(); + } + + /** + * Adds the {@code Span} into the active spans list when the {@code Span} starts. + * + * @param span the {@code Span} that started. + */ + public void onStart(SpanImpl span) { + activeSpans.addElement(span); + } + + /** + * Removes the {@code Span} from the active spans list when the {@code Span} ends. + * + * @param span the {@code Span} that ended. + */ + public void onEnd(SpanImpl span) { + activeSpans.removeElement(span); + } + + @Override + public Summary getSummary() { + Collection allActiveSpans = activeSpans.getAll(); + Map numSpansPerName = new HashMap(); + for (SpanImpl span : allActiveSpans) { + Integer prevValue = numSpansPerName.get(span.getName()); + numSpansPerName.put(span.getName(), prevValue != null ? prevValue + 1 : 1); + } + Map perSpanNameSummary = new HashMap(); + for (Map.Entry it : numSpansPerName.entrySet()) { + perSpanNameSummary.put(it.getKey(), PerSpanNameSummary.create(it.getValue())); + } + Summary summary = Summary.create(perSpanNameSummary); + return summary; + } + + @Override + public Collection getActiveSpans(Filter filter) { + Collection allActiveSpans = activeSpans.getAll(); + int maxSpansToReturn = + filter.getMaxSpansToReturn() == 0 ? allActiveSpans.size() : filter.getMaxSpansToReturn(); + List ret = new ArrayList(maxSpansToReturn); + for (SpanImpl span : allActiveSpans) { + if (ret.size() == maxSpansToReturn) { + break; + } + if (span.getName().equals(filter.getSpanName())) { + ret.add(span.toSpanData()); + } + } + return ret; + } +} diff --git a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java index a6286083bb..2554b1ecd5 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java @@ -22,6 +22,7 @@ public final class ExportComponentImpl extends ExportComponent { private static final long EXPORTER_SCHEDULE_DELAY_MS = 2000; private final SpanExporterImpl spanExporter; + private final ActiveSpansExporterImpl activeSpansExporter; @Override public SpanExporterImpl getSpanExporter() { @@ -30,9 +31,8 @@ public SpanExporterImpl getSpanExporter() { @Nullable @Override - public ActiveSpansExporter getActiveSpansExporter() { - // TODO(bdrutu): Implement this. - return null; + public ActiveSpansExporterImpl getActiveSpansExporter() { + return activeSpansExporter; } @Nullable @@ -42,8 +42,34 @@ public SampledSpanStore getSampledSpanStore() { return null; } - /** Constructs a new {@code ExportComponentImpl}. */ - public ExportComponentImpl() { + /** + * Returns a new {@code ExportComponentImpl} that has valid instances for {@link + * ActiveSpansExporter} and {@link SampledSpanStore}. + * + * @return a new {@code ExportComponentImpl}. + */ + public static ExportComponentImpl createWithInProcessStores() { + return new ExportComponentImpl(true); + } + + /** + * Returns a new {@code ExportComponentImpl} that has {@code null} instances for {@link + * ActiveSpansExporter} and {@link SampledSpanStore}. + * + * @return a new {@code ExportComponentImpl}. + */ + public static ExportComponentImpl createWithoutInProcessStores() { + return new ExportComponentImpl(false); + } + + /** + * Constructs a new {@code ExportComponentImpl}. + * + * @param supportInProcessStores {@code true} to instantiate {@link ActiveSpansExporter} and + * {@link SampledSpanStore}. + */ + private ExportComponentImpl(boolean supportInProcessStores) { this.spanExporter = SpanExporterImpl.create(EXPORTER_BUFFER_SIZE, EXPORTER_SCHEDULE_DELAY_MS); + this.activeSpansExporter = supportInProcessStores ? new ActiveSpansExporterImpl() : null; } } diff --git a/impl_core/src/test/java/io/opencensus/trace/export/ActiveSpansExporterTest.java b/impl_core/src/test/java/io/opencensus/trace/export/ActiveSpansExporterTest.java new file mode 100644 index 0000000000..af7bdc4c2f --- /dev/null +++ b/impl_core/src/test/java/io/opencensus/trace/export/ActiveSpansExporterTest.java @@ -0,0 +1,164 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.export; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.common.MillisClock; +import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.trace.Span.Options; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanImpl; +import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.StartEndHandlerImpl; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.export.ActiveSpansExporter.Filter; +import java.util.EnumSet; +import java.util.Random; +import org.junit.Test; + +/** Unit tests for {@link ActiveSpansExporter}. */ +public class ActiveSpansExporterTest { + + private static final String SPAN_NAME_1 = "MySpanName/1"; + private static final String SPAN_NAME_2 = "MySpanName/2"; + private final Random random = new Random(1234); + private final SpanExporterImpl sampledSpansServiceExporter = SpanExporterImpl.create(4, 1000); + private final ActiveSpansExporterImpl activeSpansExporter = new ActiveSpansExporterImpl(); + private final StartEndHandler startEndHandler = + new StartEndHandlerImpl( + sampledSpansServiceExporter, activeSpansExporter, null, new SimpleEventQueue()); + private EnumSet recordSpanOptions = EnumSet.of(Options.RECORD_EVENTS); + + private final SpanImpl createSpan(String spanName) { + final SpanContext spanContext = + SpanContext.create( + TraceId.generateRandomId(random), + SpanId.generateRandomId(random), + TraceOptions.DEFAULT); + SpanImpl span = + SpanImpl.startSpan( + spanContext, + recordSpanOptions, + spanName, + SpanId.generateRandomId(random), + false, + TraceParams.DEFAULT, + startEndHandler, + null, + MillisClock.getInstance()); + return span; + } + + @Test + public void getSummary_SpansWithDifferentNames() { + SpanImpl span1 = createSpan(SPAN_NAME_1); + SpanImpl span2 = createSpan(SPAN_NAME_2); + assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(2); + assertThat( + activeSpansExporter + .getSummary() + .getPerSpanNameSummary() + .get(SPAN_NAME_1) + .getNumActiveSpans()) + .isEqualTo(1); + assertThat( + activeSpansExporter + .getSummary() + .getPerSpanNameSummary() + .get(SPAN_NAME_2) + .getNumActiveSpans()) + .isEqualTo(1); + span1.end(); + assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(1); + assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().get(SPAN_NAME_1)).isNull(); + assertThat( + activeSpansExporter + .getSummary() + .getPerSpanNameSummary() + .get(SPAN_NAME_2) + .getNumActiveSpans()) + .isEqualTo(1); + span2.end(); + assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(0); + } + + @Test + public void getSummary_SpansWithSameName() { + SpanImpl span1 = createSpan(SPAN_NAME_1); + SpanImpl span2 = createSpan(SPAN_NAME_1); + SpanImpl span3 = createSpan(SPAN_NAME_1); + assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(1); + assertThat( + activeSpansExporter + .getSummary() + .getPerSpanNameSummary() + .get(SPAN_NAME_1) + .getNumActiveSpans()) + .isEqualTo(3); + span1.end(); + assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(1); + assertThat( + activeSpansExporter + .getSummary() + .getPerSpanNameSummary() + .get(SPAN_NAME_1) + .getNumActiveSpans()) + .isEqualTo(2); + span2.end(); + assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(1); + assertThat( + activeSpansExporter + .getSummary() + .getPerSpanNameSummary() + .get(SPAN_NAME_1) + .getNumActiveSpans()) + .isEqualTo(1); + span3.end(); + assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(0); + } + + @Test + public void getActiveSpans_SpansWithDifferentNames() { + SpanImpl span1 = createSpan(SPAN_NAME_1); + SpanImpl span2 = createSpan(SPAN_NAME_2); + assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_1, 0))) + .containsExactly(span1.toSpanData()); + assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_1, 2))) + .containsExactly(span1.toSpanData()); + assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_2, 0))) + .containsExactly(span2.toSpanData()); + span1.end(); + span2.end(); + } + + @Test + public void getActiveSpans_SpansWithSameName() { + SpanImpl span1 = createSpan(SPAN_NAME_1); + SpanImpl span2 = createSpan(SPAN_NAME_1); + SpanImpl span3 = createSpan(SPAN_NAME_1); + assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_1, 0))) + .containsExactly(span1.toSpanData(), span2.toSpanData(), span3.toSpanData()); + assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_1, 2)).size()) + .isEqualTo(2); + assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_1, 2))) + .containsAnyOf(span1.toSpanData(), span2.toSpanData(), span3.toSpanData()); + span1.end(); + span2.end(); + span3.end(); + } +} diff --git a/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java index 52e578d55a..244b49fcc1 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java @@ -22,22 +22,27 @@ /** Unit tests for {@link ExportComponentImpl}. */ @RunWith(JUnit4.class) public class ExportComponentImplTest { - private final ExportComponent exportComponent = new ExportComponentImpl(); + private final ExportComponent exportComponentWithInProcess = + ExportComponentImpl.createWithInProcessStores(); + private final ExportComponent exportComponentWithoutInProcess = + ExportComponentImpl.createWithoutInProcessStores(); @Test public void implementationOfSpanExporter() { - assertThat(exportComponent.getSpanExporter()).isInstanceOf(SpanExporterImpl.class); + assertThat(exportComponentWithInProcess.getSpanExporter()).isInstanceOf(SpanExporterImpl.class); } @Test public void implementationOfActiveSpans() { - // TODO(bdrutu): Change this when implementation is available. - assertThat(exportComponent.getActiveSpansExporter()).isNull(); + assertThat(exportComponentWithInProcess.getActiveSpansExporter()) + .isInstanceOf(ActiveSpansExporterImpl.class); + assertThat(exportComponentWithoutInProcess.getActiveSpansExporter()).isNull(); } @Test public void implementationOfSampledSpanStore() { // TODO(bdrutu): Change this when implementation is available. - assertThat(exportComponent.getSampledSpanStore()).isNull(); + assertThat(exportComponentWithInProcess.getSampledSpanStore()).isNull(); + assertThat(exportComponentWithoutInProcess.getSampledSpanStore()).isNull(); } } diff --git a/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java index 52251107c2..b46987c50e 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java @@ -43,7 +43,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -/** Unit tests for {@link ExportComponentImpl}. */ +/** Unit tests for {@link SpanExporterImpl}. */ @RunWith(JUnit4.class) public class SpanExporterImplTest { private static final String SPAN_NAME_1 = "MySpanName/1"; @@ -59,7 +59,7 @@ public class SpanExporterImplTest { TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); private final SpanExporterImpl sampledSpansServiceExporter = SpanExporterImpl.create(4, 1000); private final StartEndHandler startEndHandler = - new StartEndHandlerImpl(sampledSpansServiceExporter, new SimpleEventQueue()); + new StartEndHandlerImpl(sampledSpansServiceExporter, null, null, new SimpleEventQueue()); private EnumSet recordSpanOptions = EnumSet.of(Options.RECORD_EVENTS); private final FakeServiceHandler serviceHandler = new FakeServiceHandler(); @Mock private Handler mockServiceHandler; From e49a8abc653d5a8b2eb0e04ead8cd33a6d727c12 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 16 Jun 2017 03:53:30 -0700 Subject: [PATCH 0172/1581] Enable checkstyle for all tests in io.opencensus.*. (#361) --- api/build.gradle | 3 +- .../io/opencensus/common/DurationTest.java | 13 ++++++++ .../io/opencensus/common/TimestampTest.java | 13 ++++++++ .../io/opencensus/internal/ProviderTest.java | 2 +- .../java/io/opencensus/trace/TracingTest.java | 18 +++++------ build.gradle | 8 +---- checkstyle.xml | 8 +++-- .../java/io/opencensus/tags/TagKeyTest.java | 2 +- .../trace/export/ActiveSpansExporterTest.java | 32 +++++++++---------- 9 files changed, 59 insertions(+), 40 deletions(-) diff --git a/api/build.gradle b/api/build.gradle index 99000c2c60..8d2967bc42 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -8,4 +8,5 @@ dependencies { signature "org.codehaus.mojo.signature:java16:+@signature" } -javadoc.exclude 'io/opencensus/internal/**' \ No newline at end of file +javadoc.exclude 'io/opencensus/internal/**' +javadoc.exclude 'io/opencensus/trace/internal/**' \ No newline at end of file diff --git a/api/src/test/java/io/opencensus/common/DurationTest.java b/api/src/test/java/io/opencensus/common/DurationTest.java index b9861eea4b..e0dd7a9906 100644 --- a/api/src/test/java/io/opencensus/common/DurationTest.java +++ b/api/src/test/java/io/opencensus/common/DurationTest.java @@ -1,3 +1,16 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.opencensus.common; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/common/TimestampTest.java b/api/src/test/java/io/opencensus/common/TimestampTest.java index 5a02264b30..263bc66d9a 100644 --- a/api/src/test/java/io/opencensus/common/TimestampTest.java +++ b/api/src/test/java/io/opencensus/common/TimestampTest.java @@ -1,3 +1,16 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.opencensus.common; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/internal/ProviderTest.java b/api/src/test/java/io/opencensus/internal/ProviderTest.java index f6aba5ec9b..30f5f0e87f 100644 --- a/api/src/test/java/io/opencensus/internal/ProviderTest.java +++ b/api/src/test/java/io/opencensus/internal/ProviderTest.java @@ -20,7 +20,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link Provider} */ +/** Tests for {@link Provider}. */ @RunWith(JUnit4.class) public class ProviderTest { static class GoodClass { diff --git a/api/src/test/java/io/opencensus/trace/TracingTest.java b/api/src/test/java/io/opencensus/trace/TracingTest.java index 14e2607ce1..be11ff5fa3 100644 --- a/api/src/test/java/io/opencensus/trace/TracingTest.java +++ b/api/src/test/java/io/opencensus/trace/TracingTest.java @@ -45,16 +45,14 @@ public Class loadClass(String name) { @Test public void loadTraceComponent_IgnoresMissingClasses() { - assertThat( - Tracing.loadTraceComponent( - new ClassLoader() { - @Override - public Class loadClass(String name) throws ClassNotFoundException { - throw new ClassNotFoundException(); - } - }) - .getClass() - .getName()) + ClassLoader classLoader = + new ClassLoader() { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + throw new ClassNotFoundException(); + } + }; + assertThat(Tracing.loadTraceComponent(classLoader).getClass().getName()) .isEqualTo("io.opencensus.trace.TraceComponent$NoopTraceComponent"); } diff --git a/build.gradle b/build.gradle index c1ea9c3286..483d2be233 100644 --- a/build.gradle +++ b/build.gradle @@ -163,15 +163,9 @@ subprojects { } checkstyleTest { - // TODO(bdrutu): Enable this when we have tests checkstyle clean. - // source = fileTree(dir: "src/test", include: "**/*.java") - excludes = ["**"] + excludes = ["com/google/instrumentation/**"] } - // Disable checkstyle for shared. - checkstyleMain.onlyIf { !name.contains("shared") } - checkstyleTest.onlyIf { !name.contains("shared") } - // Disable checkstyle if no java8. checkstyleMain.enabled = JavaVersion.current().isJava8Compatible() checkstyleTest.enabled = JavaVersion.current().isJava8Compatible() diff --git a/checkstyle.xml b/checkstyle.xml index c7dee1ee75..d1ddfdfe80 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -208,7 +208,9 @@ - + + + @@ -217,8 +219,8 @@ value="Method name ''{0}'' must match pattern ''{1}''."/> - + + diff --git a/core/src/test/java/io/opencensus/tags/TagKeyTest.java b/core/src/test/java/io/opencensus/tags/TagKeyTest.java index aed02d3fc8..2628b73e63 100644 --- a/core/src/test/java/io/opencensus/tags/TagKeyTest.java +++ b/core/src/test/java/io/opencensus/tags/TagKeyTest.java @@ -24,7 +24,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link TagKey} */ +/** Tests for {@link TagKey}. */ @RunWith(JUnit4.class) public final class TagKeyTest { diff --git a/impl_core/src/test/java/io/opencensus/trace/export/ActiveSpansExporterTest.java b/impl_core/src/test/java/io/opencensus/trace/export/ActiveSpansExporterTest.java index af7bdc4c2f..d7d80b19d8 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/ActiveSpansExporterTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/ActiveSpansExporterTest.java @@ -50,24 +50,22 @@ private final SpanImpl createSpan(String spanName) { TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); - SpanImpl span = - SpanImpl.startSpan( - spanContext, - recordSpanOptions, - spanName, - SpanId.generateRandomId(random), - false, - TraceParams.DEFAULT, - startEndHandler, - null, - MillisClock.getInstance()); - return span; + return SpanImpl.startSpan( + spanContext, + recordSpanOptions, + spanName, + SpanId.generateRandomId(random), + false, + TraceParams.DEFAULT, + startEndHandler, + null, + MillisClock.getInstance()); } @Test public void getSummary_SpansWithDifferentNames() { - SpanImpl span1 = createSpan(SPAN_NAME_1); - SpanImpl span2 = createSpan(SPAN_NAME_2); + final SpanImpl span1 = createSpan(SPAN_NAME_1); + final SpanImpl span2 = createSpan(SPAN_NAME_2); assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(2); assertThat( activeSpansExporter @@ -99,9 +97,9 @@ public void getSummary_SpansWithDifferentNames() { @Test public void getSummary_SpansWithSameName() { - SpanImpl span1 = createSpan(SPAN_NAME_1); - SpanImpl span2 = createSpan(SPAN_NAME_1); - SpanImpl span3 = createSpan(SPAN_NAME_1); + final SpanImpl span1 = createSpan(SPAN_NAME_1); + final SpanImpl span2 = createSpan(SPAN_NAME_1); + final SpanImpl span3 = createSpan(SPAN_NAME_1); assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(1); assertThat( activeSpansExporter From e4393e56af8c0ca48ae65a64ea07ddae902b2f9b Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 16 Jun 2017 15:29:39 +0200 Subject: [PATCH 0173/1581] .gitignore the files generated by the NetBeans Gradle plugin. --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 1b7eeab49f..922bc70b64 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,10 @@ target .settings bin +# NetBeans +/.nb-gradle +/.nb-gradle-properties + # OS X .DS_Store From a7e1b0cb733a5c6b7cbe5b90a2ab57507be0c5bd Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 16 Jun 2017 12:29:28 -0700 Subject: [PATCH 0174/1581] Rename ActiveSpansExporter to RunningSpanStore. (#362) --- .../trace/export/ExportComponent.java | 10 ++--- ...ansExporter.java => RunningSpanStore.java} | 40 +++++++++---------- .../trace/export/ExportComponentTest.java | 2 +- .../opencensus/trace/StartEndHandlerImpl.java | 32 +++++++-------- .../trace/TraceComponentImplBase.java | 2 +- .../trace/export/ExportComponentImpl.java | 12 +++--- ...terImpl.java => RunningSpanStoreImpl.java} | 30 +++++++------- .../trace/export/ExportComponentImplTest.java | 6 +-- ...terTest.java => RunningSpanStoreTest.java} | 32 +++++++-------- 9 files changed, 83 insertions(+), 83 deletions(-) rename api/src/main/java/io/opencensus/trace/export/{ActiveSpansExporter.java => RunningSpanStore.java} (77%) rename impl_core/src/main/java/io/opencensus/trace/export/{ActiveSpansExporterImpl.java => RunningSpanStoreImpl.java} (69%) rename impl_core/src/test/java/io/opencensus/trace/export/{ActiveSpansExporterTest.java => RunningSpanStoreTest.java} (84%) diff --git a/api/src/main/java/io/opencensus/trace/export/ExportComponent.java b/api/src/main/java/io/opencensus/trace/export/ExportComponent.java index 99e73a6cd1..f1199e3984 100644 --- a/api/src/main/java/io/opencensus/trace/export/ExportComponent.java +++ b/api/src/main/java/io/opencensus/trace/export/ExportComponent.java @@ -18,7 +18,7 @@ /** * Class that holds the implementation instances for {@link SpanExporter}, {@link - * ActiveSpansExporter} and {@link SampledSpanStore}. + * RunningSpanStore} and {@link SampledSpanStore}. * *

            Unless otherwise noted all methods (on component) results are cacheable. */ @@ -45,13 +45,13 @@ public static ExportComponent getNoopExportComponent() { public abstract SpanExporter getSpanExporter(); /** - * Returns the {@link ActiveSpansExporter} that can be used to get useful debugging information + * Returns the {@link RunningSpanStore} that can be used to get useful debugging information * about all the current active spans. * - * @return the {@code ActiveSpansExporter} or {@code null} if not supported. + * @return the {@code RunningSpanStore} or {@code null} if not supported. */ @Nullable - public abstract ActiveSpansExporter getActiveSpansExporter(); + public abstract RunningSpanStore getRunningSpanStore(); /** * Returns the {@link SampledSpanStore} that can be used to get useful debugging information, such @@ -70,7 +70,7 @@ public SpanExporter getSpanExporter() { @Nullable @Override - public ActiveSpansExporter getActiveSpansExporter() { + public RunningSpanStore getRunningSpanStore() { return null; } diff --git a/api/src/main/java/io/opencensus/trace/export/ActiveSpansExporter.java b/api/src/main/java/io/opencensus/trace/export/RunningSpanStore.java similarity index 77% rename from api/src/main/java/io/opencensus/trace/export/ActiveSpansExporter.java rename to api/src/main/java/io/opencensus/trace/export/RunningSpanStore.java index c6c5b8da3d..19facc8a76 100644 --- a/api/src/main/java/io/opencensus/trace/export/ActiveSpansExporter.java +++ b/api/src/main/java/io/opencensus/trace/export/RunningSpanStore.java @@ -26,31 +26,31 @@ import javax.annotation.concurrent.ThreadSafe; /** - * This class allows users to access in-process information about all active spans. + * This class allows users to access in-process information about all running spans. * - *

            The active spans tracking is available for all the spans with the option {@link + *

            The running spans tracking is available for all the spans with the option {@link * Span.Options#RECORD_EVENTS}. This functionality allows users to debug stuck operations or long * living operations. */ @ThreadSafe -public abstract class ActiveSpansExporter { +public abstract class RunningSpanStore { - protected ActiveSpansExporter() {} + protected RunningSpanStore() {} /** - * Returns the summary of all available data such, as number of active spans. + * Returns the summary of all available data such, as number of running spans. * * @return the summary of all available data. */ public abstract Summary getSummary(); /** - * Returns a list of active spans that match the {@code Filter}. + * Returns a list of running spans that match the {@code Filter}. * * @param filter used to filter the returned spans. - * @return a list of active spans that match the {@code Filter}. + * @return a list of running spans that match the {@code Filter}. */ - public abstract Collection getActiveSpans(Filter filter); + public abstract Collection getRunningSpans(Filter filter); /** The summary of all available data. */ @AutoValue @@ -67,7 +67,7 @@ public abstract static class Summary { * @throws NullPointerException if {@code perSpanNameSummary} is {@code null}. */ public static Summary create(Map perSpanNameSummary) { - return new AutoValue_ActiveSpansExporter_Summary( + return new AutoValue_RunningSpanStore_Summary( Collections.unmodifiableMap( new HashMap( checkNotNull(perSpanNameSummary, "perSpanNameSummary")))); @@ -91,26 +91,26 @@ public abstract static class PerSpanNameSummary { /** * Returns a new instance of {@code PerSpanNameSummary}. * - * @param numActiveSpans the number of sampled spans. + * @param numRunningSpans the number of running spans. * @return a new instance of {@code PerSpanNameSummary}. - * @throws IllegalArgumentException if {@code numActiveSpans} is negative. + * @throws IllegalArgumentException if {@code numRunningSpans} is negative. */ - public static PerSpanNameSummary create(int numActiveSpans) { - checkArgument(numActiveSpans >= 0, "Negative numActiveSpans."); - return new AutoValue_ActiveSpansExporter_PerSpanNameSummary(numActiveSpans); + public static PerSpanNameSummary create(int numRunningSpans) { + checkArgument(numRunningSpans >= 0, "Negative numRunningSpans."); + return new AutoValue_RunningSpanStore_PerSpanNameSummary(numRunningSpans); } /** - * Returns the number of active spans. + * Returns the number of running spans. * - * @return the number of active spans. + * @return the number of running spans. */ - public abstract int getNumActiveSpans(); + public abstract int getNumRunningSpans(); } /** - * Filter for active spans. Used to filter results returned by the {@link #getActiveSpans(Filter)} - * request. + * Filter for running spans. Used to filter results returned by the + * {@link #getRunningSpans(Filter)} request. */ @AutoValue @Immutable @@ -132,7 +132,7 @@ public abstract static class Filter { */ public static Filter create(String spanName, int maxSpansToReturn) { checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); - return new AutoValue_ActiveSpansExporter_Filter(spanName, maxSpansToReturn); + return new AutoValue_RunningSpanStore_Filter(spanName, maxSpansToReturn); } /** diff --git a/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java b/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java index f3a3b13726..efff03ba1e 100644 --- a/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java +++ b/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java @@ -30,7 +30,7 @@ public void implementationOfSpanExporter() { } public void implementationOfActiveSpans() { - assertThat(exportComponent.getActiveSpansExporter()).isNull(); + assertThat(exportComponent.getRunningSpanStore()).isNull(); } @Test diff --git a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java index fb7071908a..89b797be5c 100644 --- a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java @@ -16,7 +16,7 @@ import io.opencensus.internal.EventQueue; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; -import io.opencensus.trace.export.ActiveSpansExporterImpl; +import io.opencensus.trace.export.RunningSpanStoreImpl; import io.opencensus.trace.export.SampledSpanStore; import io.opencensus.trace.export.SpanData; import io.opencensus.trace.export.SpanExporterImpl; @@ -30,10 +30,10 @@ @ThreadSafe public final class StartEndHandlerImpl implements StartEndHandler { private final SpanExporterImpl spanExporter; - private final ActiveSpansExporterImpl activeSpansExporter; + private final RunningSpanStoreImpl runningSpanStore; private final SampledSpanStore sampledSpanStore; private final EventQueue eventQueue; - // true if any of (activeSpansExporter OR sampledSpanStore) are different than null, which + // true if any of (runningSpanStore OR sampledSpanStore) are different than null, which // means the spans with RECORD_EVENTS should be enqueued in the queue. private final boolean enqueueEventForNonSampledSpans; @@ -41,26 +41,26 @@ public final class StartEndHandlerImpl implements StartEndHandler { * Constructs a new {@code StartEndHandlerImpl}. * * @param spanExporter the {@code SpanExporter} implementation. - * @param activeSpansExporter the {@code ActiveSpansExporter} implementation. + * @param runningSpanStore the {@code RunningSpanStore} implementation. * @param sampledSpanStore the {@code SampledSpanStore} implementation. * @param eventQueue the event queue where all the events are enqueued. */ public StartEndHandlerImpl( SpanExporterImpl spanExporter, - @Nullable ActiveSpansExporterImpl activeSpansExporter, + @Nullable RunningSpanStoreImpl runningSpanStore, @Nullable SampledSpanStore sampledSpanStore, EventQueue eventQueue) { this.spanExporter = spanExporter; - this.activeSpansExporter = activeSpansExporter; + this.runningSpanStore = runningSpanStore; this.sampledSpanStore = sampledSpanStore; - this.enqueueEventForNonSampledSpans = activeSpansExporter != null || sampledSpanStore != null; + this.enqueueEventForNonSampledSpans = runningSpanStore != null || sampledSpanStore != null; this.eventQueue = eventQueue; } @Override public void onStart(SpanImpl span) { if (span.getOptions().contains(Options.RECORD_EVENTS) && enqueueEventForNonSampledSpans) { - eventQueue.enqueue(new SpanStartEvent(span, activeSpansExporter)); + eventQueue.enqueue(new SpanStartEvent(span, runningSpanStore)); } } @@ -69,16 +69,16 @@ public void onEnd(SpanImpl span) { if ((span.getOptions().contains(Options.RECORD_EVENTS) && enqueueEventForNonSampledSpans) || span.getContext().getTraceOptions().isSampled()) { eventQueue.enqueue( - new SpanEndEvent(span, spanExporter, activeSpansExporter, sampledSpanStore)); + new SpanEndEvent(span, spanExporter, runningSpanStore, sampledSpanStore)); } } // An EventQueue entry that records the start of the span event. private static final class SpanStartEvent implements EventQueue.Entry { private final SpanImpl span; - private final ActiveSpansExporterImpl activeSpansExporter; + private final RunningSpanStoreImpl activeSpansExporter; - SpanStartEvent(SpanImpl span, @Nullable ActiveSpansExporterImpl activeSpansExporter) { + SpanStartEvent(SpanImpl span, @Nullable RunningSpanStoreImpl activeSpansExporter) { this.span = span; this.activeSpansExporter = activeSpansExporter; } @@ -94,24 +94,24 @@ public void process() { // An EventQueue entry that records the end of the span event. private static final class SpanEndEvent implements EventQueue.Entry { private final SpanImpl span; - private final ActiveSpansExporterImpl activeSpansExporter; + private final RunningSpanStoreImpl runningSpanStore; private final SpanExporterImpl spanExporter; SpanEndEvent( SpanImpl span, SpanExporterImpl spanExporter, - @Nullable ActiveSpansExporterImpl activeSpansExporter, + @Nullable RunningSpanStoreImpl runningSpanStore, @Nullable SampledSpanStore sampledSpanStore) { this.span = span; - this.activeSpansExporter = activeSpansExporter; + this.runningSpanStore = runningSpanStore; this.spanExporter = spanExporter; } @Override public void process() { spanExporter.addSpan(span); - if (activeSpansExporter != null) { - activeSpansExporter.onEnd(span); + if (runningSpanStore != null) { + runningSpanStore.onEnd(span); } } } diff --git a/impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java b/impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java index 1448d40e19..6e1db07f20 100644 --- a/impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java +++ b/impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java @@ -45,7 +45,7 @@ class TraceComponentImplBase extends TraceComponent { startEndHandler = new StartEndHandlerImpl( exportComponent.getSpanExporter(), - exportComponent.getActiveSpansExporter(), + exportComponent.getRunningSpanStore(), exportComponent.getSampledSpanStore(), eventQueue); tracer = new TracerImpl(randomHandler, startEndHandler, clock, traceConfig); diff --git a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java index 2554b1ecd5..8ff40df0b4 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java @@ -22,7 +22,7 @@ public final class ExportComponentImpl extends ExportComponent { private static final long EXPORTER_SCHEDULE_DELAY_MS = 2000; private final SpanExporterImpl spanExporter; - private final ActiveSpansExporterImpl activeSpansExporter; + private final RunningSpanStoreImpl activeSpansExporter; @Override public SpanExporterImpl getSpanExporter() { @@ -31,7 +31,7 @@ public SpanExporterImpl getSpanExporter() { @Nullable @Override - public ActiveSpansExporterImpl getActiveSpansExporter() { + public RunningSpanStoreImpl getRunningSpanStore() { return activeSpansExporter; } @@ -44,7 +44,7 @@ public SampledSpanStore getSampledSpanStore() { /** * Returns a new {@code ExportComponentImpl} that has valid instances for {@link - * ActiveSpansExporter} and {@link SampledSpanStore}. + * RunningSpanStore} and {@link SampledSpanStore}. * * @return a new {@code ExportComponentImpl}. */ @@ -54,7 +54,7 @@ public static ExportComponentImpl createWithInProcessStores() { /** * Returns a new {@code ExportComponentImpl} that has {@code null} instances for {@link - * ActiveSpansExporter} and {@link SampledSpanStore}. + * RunningSpanStore} and {@link SampledSpanStore}. * * @return a new {@code ExportComponentImpl}. */ @@ -65,11 +65,11 @@ public static ExportComponentImpl createWithoutInProcessStores() { /** * Constructs a new {@code ExportComponentImpl}. * - * @param supportInProcessStores {@code true} to instantiate {@link ActiveSpansExporter} and + * @param supportInProcessStores {@code true} to instantiate {@link RunningSpanStore} and * {@link SampledSpanStore}. */ private ExportComponentImpl(boolean supportInProcessStores) { this.spanExporter = SpanExporterImpl.create(EXPORTER_BUFFER_SIZE, EXPORTER_SCHEDULE_DELAY_MS); - this.activeSpansExporter = supportInProcessStores ? new ActiveSpansExporterImpl() : null; + this.activeSpansExporter = supportInProcessStores ? new RunningSpanStoreImpl() : null; } } diff --git a/impl_core/src/main/java/io/opencensus/trace/export/ActiveSpansExporterImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/RunningSpanStoreImpl.java similarity index 69% rename from impl_core/src/main/java/io/opencensus/trace/export/ActiveSpansExporterImpl.java rename to impl_core/src/main/java/io/opencensus/trace/export/RunningSpanStoreImpl.java index 69332585c6..d1053599bd 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/ActiveSpansExporterImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/export/RunningSpanStoreImpl.java @@ -22,38 +22,38 @@ import java.util.Map; import javax.annotation.concurrent.ThreadSafe; -/** Implementation of the {@link ActiveSpansExporter}. */ +/** Implementation of the {@link RunningSpanStore}. */ @ThreadSafe -public final class ActiveSpansExporterImpl extends ActiveSpansExporter { - private final ConcurrentIntrusiveList activeSpans; +public final class RunningSpanStoreImpl extends RunningSpanStore { + private final ConcurrentIntrusiveList runningSpans; - public ActiveSpansExporterImpl() { - activeSpans = new ConcurrentIntrusiveList(); + public RunningSpanStoreImpl() { + runningSpans = new ConcurrentIntrusiveList(); } /** - * Adds the {@code Span} into the active spans list when the {@code Span} starts. + * Adds the {@code Span} into the running spans list when the {@code Span} starts. * * @param span the {@code Span} that started. */ public void onStart(SpanImpl span) { - activeSpans.addElement(span); + runningSpans.addElement(span); } /** - * Removes the {@code Span} from the active spans list when the {@code Span} ends. + * Removes the {@code Span} from the running spans list when the {@code Span} ends. * * @param span the {@code Span} that ended. */ public void onEnd(SpanImpl span) { - activeSpans.removeElement(span); + runningSpans.removeElement(span); } @Override public Summary getSummary() { - Collection allActiveSpans = activeSpans.getAll(); + Collection allRunningSpans = runningSpans.getAll(); Map numSpansPerName = new HashMap(); - for (SpanImpl span : allActiveSpans) { + for (SpanImpl span : allRunningSpans) { Integer prevValue = numSpansPerName.get(span.getName()); numSpansPerName.put(span.getName(), prevValue != null ? prevValue + 1 : 1); } @@ -66,12 +66,12 @@ public Summary getSummary() { } @Override - public Collection getActiveSpans(Filter filter) { - Collection allActiveSpans = activeSpans.getAll(); + public Collection getRunningSpans(Filter filter) { + Collection allRunningSpans = runningSpans.getAll(); int maxSpansToReturn = - filter.getMaxSpansToReturn() == 0 ? allActiveSpans.size() : filter.getMaxSpansToReturn(); + filter.getMaxSpansToReturn() == 0 ? allRunningSpans.size() : filter.getMaxSpansToReturn(); List ret = new ArrayList(maxSpansToReturn); - for (SpanImpl span : allActiveSpans) { + for (SpanImpl span : allRunningSpans) { if (ret.size() == maxSpansToReturn) { break; } diff --git a/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java index 244b49fcc1..73425ca36f 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java @@ -34,9 +34,9 @@ public void implementationOfSpanExporter() { @Test public void implementationOfActiveSpans() { - assertThat(exportComponentWithInProcess.getActiveSpansExporter()) - .isInstanceOf(ActiveSpansExporterImpl.class); - assertThat(exportComponentWithoutInProcess.getActiveSpansExporter()).isNull(); + assertThat(exportComponentWithInProcess.getRunningSpanStore()) + .isInstanceOf(RunningSpanStoreImpl.class); + assertThat(exportComponentWithoutInProcess.getRunningSpanStore()).isNull(); } @Test diff --git a/impl_core/src/test/java/io/opencensus/trace/export/ActiveSpansExporterTest.java b/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreTest.java similarity index 84% rename from impl_core/src/test/java/io/opencensus/trace/export/ActiveSpansExporterTest.java rename to impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreTest.java index d7d80b19d8..dba5cecc7b 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/ActiveSpansExporterTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreTest.java @@ -26,19 +26,19 @@ import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceParams; -import io.opencensus.trace.export.ActiveSpansExporter.Filter; +import io.opencensus.trace.export.RunningSpanStore.Filter; import java.util.EnumSet; import java.util.Random; import org.junit.Test; -/** Unit tests for {@link ActiveSpansExporter}. */ -public class ActiveSpansExporterTest { +/** Unit tests for {@link RunningSpanStore}. */ +public class RunningSpanStoreTest { private static final String SPAN_NAME_1 = "MySpanName/1"; private static final String SPAN_NAME_2 = "MySpanName/2"; private final Random random = new Random(1234); private final SpanExporterImpl sampledSpansServiceExporter = SpanExporterImpl.create(4, 1000); - private final ActiveSpansExporterImpl activeSpansExporter = new ActiveSpansExporterImpl(); + private final RunningSpanStoreImpl activeSpansExporter = new RunningSpanStoreImpl(); private final StartEndHandler startEndHandler = new StartEndHandlerImpl( sampledSpansServiceExporter, activeSpansExporter, null, new SimpleEventQueue()); @@ -72,14 +72,14 @@ public void getSummary_SpansWithDifferentNames() { .getSummary() .getPerSpanNameSummary() .get(SPAN_NAME_1) - .getNumActiveSpans()) + .getNumRunningSpans()) .isEqualTo(1); assertThat( activeSpansExporter .getSummary() .getPerSpanNameSummary() .get(SPAN_NAME_2) - .getNumActiveSpans()) + .getNumRunningSpans()) .isEqualTo(1); span1.end(); assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(1); @@ -89,7 +89,7 @@ public void getSummary_SpansWithDifferentNames() { .getSummary() .getPerSpanNameSummary() .get(SPAN_NAME_2) - .getNumActiveSpans()) + .getNumRunningSpans()) .isEqualTo(1); span2.end(); assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(0); @@ -106,7 +106,7 @@ public void getSummary_SpansWithSameName() { .getSummary() .getPerSpanNameSummary() .get(SPAN_NAME_1) - .getNumActiveSpans()) + .getNumRunningSpans()) .isEqualTo(3); span1.end(); assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(1); @@ -115,7 +115,7 @@ public void getSummary_SpansWithSameName() { .getSummary() .getPerSpanNameSummary() .get(SPAN_NAME_1) - .getNumActiveSpans()) + .getNumRunningSpans()) .isEqualTo(2); span2.end(); assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(1); @@ -124,7 +124,7 @@ public void getSummary_SpansWithSameName() { .getSummary() .getPerSpanNameSummary() .get(SPAN_NAME_1) - .getNumActiveSpans()) + .getNumRunningSpans()) .isEqualTo(1); span3.end(); assertThat(activeSpansExporter.getSummary().getPerSpanNameSummary().size()).isEqualTo(0); @@ -134,11 +134,11 @@ public void getSummary_SpansWithSameName() { public void getActiveSpans_SpansWithDifferentNames() { SpanImpl span1 = createSpan(SPAN_NAME_1); SpanImpl span2 = createSpan(SPAN_NAME_2); - assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_1, 0))) + assertThat(activeSpansExporter.getRunningSpans(Filter.create(SPAN_NAME_1, 0))) .containsExactly(span1.toSpanData()); - assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_1, 2))) + assertThat(activeSpansExporter.getRunningSpans(Filter.create(SPAN_NAME_1, 2))) .containsExactly(span1.toSpanData()); - assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_2, 0))) + assertThat(activeSpansExporter.getRunningSpans(Filter.create(SPAN_NAME_2, 0))) .containsExactly(span2.toSpanData()); span1.end(); span2.end(); @@ -149,11 +149,11 @@ public void getActiveSpans_SpansWithSameName() { SpanImpl span1 = createSpan(SPAN_NAME_1); SpanImpl span2 = createSpan(SPAN_NAME_1); SpanImpl span3 = createSpan(SPAN_NAME_1); - assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_1, 0))) + assertThat(activeSpansExporter.getRunningSpans(Filter.create(SPAN_NAME_1, 0))) .containsExactly(span1.toSpanData(), span2.toSpanData(), span3.toSpanData()); - assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_1, 2)).size()) + assertThat(activeSpansExporter.getRunningSpans(Filter.create(SPAN_NAME_1, 2)).size()) .isEqualTo(2); - assertThat(activeSpansExporter.getActiveSpans(Filter.create(SPAN_NAME_1, 2))) + assertThat(activeSpansExporter.getRunningSpans(Filter.create(SPAN_NAME_1, 2))) .containsAnyOf(span1.toSpanData(), span2.toSpanData(), span3.toSpanData()); span1.end(); span2.end(); From 4aa6e80c8efac571e3017b70d599eb52db23a6f3 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 16 Jun 2017 14:33:42 -0700 Subject: [PATCH 0175/1581] Move TestClock in opencensus-testing package. (#368) --- api/build.gradle | 3 ++- core/build.gradle | 4 ++++ core_impl/build.gradle | 5 ++++- .../stats/MeasurementDescriptorToViewMapTest.java | 2 +- .../instrumentation/stats/StatsContextFactoryTest.java | 2 +- .../google/instrumentation/stats/StatsContextTest.java | 2 +- .../instrumentation/stats/StatsManagerImplTest.java | 2 +- core_impl_android/build.gradle | 6 ++++++ core_impl_java/build.gradle | 6 ++++++ examples/build.gradle | 4 +++- impl/build.gradle | 3 +++ impl_core/build.gradle | 3 +++ .../java/io/opencensus/trace/config/TraceConfigImpl.java | 4 +--- .../java/io/opencensus/trace/SpanFactoryImplTest.java | 2 +- .../src/test/java/io/opencensus/trace/SpanImplTest.java | 2 +- .../trace/propagation/PropagationComponentImplTest.java | 3 +-- impl_lite/build.gradle | 3 +++ settings.gradle | 2 ++ testing/README.md | 5 +++++ testing/build.gradle | 9 +++++++++ .../java/io/opencensus/testing/common}/TestClock.java | 2 +- .../io/opencensus/testing/common}/TestClockTest.java | 2 +- 22 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 testing/README.md create mode 100644 testing/build.gradle rename {api/src/main/java/io/opencensus/internal => testing/src/main/java/io/opencensus/testing/common}/TestClock.java (98%) rename {api/src/test/java/io/opencensus/internal => testing/src/test/java/io/opencensus/testing/common}/TestClockTest.java (98%) diff --git a/api/build.gradle b/api/build.gradle index 8d2967bc42..3834f051d9 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -1,8 +1,9 @@ -description = 'OpenCensus: API' +description = 'OpenCensus API' dependencies { compile libraries.grpc_context, libraries.guava + compileOnly libraries.auto_value signature "org.codehaus.mojo.signature:java16:+@signature" diff --git a/core/build.gradle b/core/build.gradle index 333dea0a49..1d2266c168 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -8,8 +8,12 @@ dependencies { compile project(':opencensus-api'), libraries.grpc_context, libraries.guava + compileOnly libraries.auto_value + testCompile project(':opencensus-api'), + project(':opencensus-testing') + signature "org.codehaus.mojo.signature:java16:+@signature" } diff --git a/core_impl/build.gradle b/core_impl/build.gradle index 73593aa2b6..44e02423ce 100644 --- a/core_impl/build.gradle +++ b/core_impl/build.gradle @@ -6,7 +6,10 @@ dependencies { project(':opencensus-impl-core'), libraries.guava - testCompile project(':core') + testCompile project(':core'), + project(':opencensus-api'), + project(':opencensus-impl-core'), + project(':opencensus-testing') signature "org.codehaus.mojo.signature:java16:+@signature" } diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java index 1b4bdf7bbc..86f344be41 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java @@ -18,7 +18,7 @@ import io.opencensus.common.Function; import io.opencensus.common.Timestamp; -import io.opencensus.internal.TestClock; +import io.opencensus.testing.common.TestClock; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; import com.google.instrumentation.stats.View.DistributionView; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java index 1bc7cfd3c5..e2ca9beb6d 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java @@ -17,7 +17,7 @@ import io.opencensus.common.NonThrowingCloseable; import io.opencensus.internal.SimpleEventQueue; -import io.opencensus.internal.TestClock; +import io.opencensus.testing.common.TestClock; import io.opencensus.internal.VarInt; import io.grpc.Context; import java.io.ByteArrayInputStream; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java index 783506ba36..c30750c999 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java @@ -20,7 +20,7 @@ import com.google.common.testing.EqualsTester; import io.opencensus.common.Function; import io.opencensus.internal.SimpleEventQueue; -import io.opencensus.internal.TestClock; +import io.opencensus.testing.common.TestClock; import io.opencensus.internal.VarInt; import com.google.instrumentation.stats.View.DistributionView; import com.google.instrumentation.stats.View.IntervalView; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java index a5f74211fd..7297540b6b 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java @@ -19,7 +19,7 @@ import io.opencensus.common.Duration; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.common.Timestamp; -import io.opencensus.internal.TestClock; +import io.opencensus.testing.common.TestClock; import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; import com.google.instrumentation.stats.View.DistributionView; diff --git a/core_impl_android/build.gradle b/core_impl_android/build.gradle index 4d830586ad..d5dc088a77 100644 --- a/core_impl_android/build.gradle +++ b/core_impl_android/build.gradle @@ -4,5 +4,11 @@ dependencies { compile project(':core'), project(':core_impl') + testCompile project(':core'), + project(':core_impl'), + project(':opencensus-api'), + project(':opencensus-impl-core'), + project(':opencensus-impl-lite') + signature "net.sf.androidscents.signature:android-api-level-14:+@signature" } diff --git a/core_impl_java/build.gradle b/core_impl_java/build.gradle index 4c17d2b50f..de9b06370d 100644 --- a/core_impl_java/build.gradle +++ b/core_impl_java/build.gradle @@ -12,5 +12,11 @@ dependencies { project(':core_impl'), project(':opencensus-impl') + testCompile project(':core'), + project(':core_impl'), + project(':opencensus-api'), + project(':opencensus-impl-core'), + project(':opencensus-impl') + signature "org.codehaus.mojo.signature:java17:+@signature" } \ No newline at end of file diff --git a/examples/build.gradle b/examples/build.gradle index 480374a102..9439bba934 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -8,7 +8,9 @@ tasks.withType(JavaCompile) { dependencies { compile project(':core'), project(':core_impl'), - project(':core_impl_java') + project(':core_impl_java'), + project(':opencensus-api'), + project(':opencensus-impl') } // Provide convenience executables for trying out the examples. diff --git a/impl/build.gradle b/impl/build.gradle index be4e959cdc..e8852049a1 100644 --- a/impl/build.gradle +++ b/impl/build.gradle @@ -12,6 +12,9 @@ dependencies { project(':opencensus-impl-core'), libraries.disruptor + testCompile project(':opencensus-api'), + project(':opencensus-impl-core') + signature "org.codehaus.mojo.signature:java17:+@signature" } diff --git a/impl_core/build.gradle b/impl_core/build.gradle index 70de8aa63e..4458d537d0 100644 --- a/impl_core/build.gradle +++ b/impl_core/build.gradle @@ -6,6 +6,9 @@ dependencies { compileOnly libraries.auto_value + testCompile project(':opencensus-api'), + project(':opencensus-testing') + signature "org.codehaus.mojo.signature:java16:+@signature" } diff --git a/impl_core/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java b/impl_core/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java index cf3dc59ee2..3b42c2b0dd 100644 --- a/impl_core/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java @@ -22,9 +22,7 @@ public final class TraceConfigImpl extends TraceConfig { // operations are visible on other CPUs as well. private volatile TraceParams activeTraceParams = TraceParams.DEFAULT; - /** - * Constructs a new {@code TraceConfigImpl}. - */ + /** Constructs a new {@code TraceConfigImpl}. */ public TraceConfigImpl() {} @Override diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java index 00d051a6ae..1d5cf3acd4 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java @@ -16,7 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; -import io.opencensus.internal.TestClock; +import io.opencensus.testing.common.TestClock; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.base.SpanId; diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java index 62052dd2d8..ed4aae7415 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java @@ -17,8 +17,8 @@ import io.opencensus.common.Duration; import io.opencensus.common.Timestamp; -import io.opencensus.internal.TestClock; import io.opencensus.internal.TimestampConverter; +import io.opencensus.testing.common.TestClock; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.base.Annotation; diff --git a/impl_core/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java b/impl_core/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java index dd7812ab07..9c1228ac8b 100644 --- a/impl_core/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java @@ -26,7 +26,6 @@ public class PropagationComponentImplTest { @Test public void implementationOfBinary() { - assertThat(propagationComponent.getBinaryFormat()) - .isInstanceOf(BinaryFormatImpl.class); + assertThat(propagationComponent.getBinaryFormat()).isInstanceOf(BinaryFormatImpl.class); } } diff --git a/impl_lite/build.gradle b/impl_lite/build.gradle index 40cce82a82..30ba7873fa 100644 --- a/impl_lite/build.gradle +++ b/impl_lite/build.gradle @@ -4,5 +4,8 @@ dependencies { compile project(':opencensus-api'), project(':opencensus-impl-core') + testCompile project(':opencensus-api'), + project(':opencensus-impl-core') + signature "net.sf.androidscents.signature:android-api-level-14:+@signature" } diff --git a/settings.gradle b/settings.gradle index e7a8c4c4b6..41395b1ddb 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,6 +4,7 @@ include ":opencensus-api" include ":opencensus-impl-core" include ":opencensus-impl-lite" include ":opencensus-impl" +include ":opencensus-testing" include ":all" include ":core" include ":core_impl" @@ -14,6 +15,7 @@ project(':opencensus-api').projectDir = "$rootDir/api" as File project(':opencensus-impl-core').projectDir = "$rootDir/impl_core" as File project(':opencensus-impl-lite').projectDir = "$rootDir/impl_lite" as File project(':opencensus-impl').projectDir = "$rootDir/impl" as File +project(':opencensus-testing').projectDir = "$rootDir/testing" as File // Java8 projects only if (JavaVersion.current().isJava8Compatible()) { diff --git a/testing/README.md b/testing/README.md new file mode 100644 index 0000000000..268bbf3de7 --- /dev/null +++ b/testing/README.md @@ -0,0 +1,5 @@ +OpenCensus Testing Package +====================================================== + +* Java 6 and Android compatible. +* The classes in this directory can be used to test the API integration. diff --git a/testing/build.gradle b/testing/build.gradle new file mode 100644 index 0000000000..179ab71b72 --- /dev/null +++ b/testing/build.gradle @@ -0,0 +1,9 @@ +description = 'OpenCensus Testing' + +dependencies { + compile project(':opencensus-api') + + testCompile project(':opencensus-api') + + signature "org.codehaus.mojo.signature:java16:+@signature" +} diff --git a/api/src/main/java/io/opencensus/internal/TestClock.java b/testing/src/main/java/io/opencensus/testing/common/TestClock.java similarity index 98% rename from api/src/main/java/io/opencensus/internal/TestClock.java rename to testing/src/main/java/io/opencensus/testing/common/TestClock.java index d181da3a32..2a604f2a1f 100644 --- a/api/src/main/java/io/opencensus/internal/TestClock.java +++ b/testing/src/main/java/io/opencensus/testing/common/TestClock.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.internal; +package io.opencensus.testing.common; import com.google.common.math.LongMath; import io.opencensus.common.Clock; diff --git a/api/src/test/java/io/opencensus/internal/TestClockTest.java b/testing/src/test/java/io/opencensus/testing/common/TestClockTest.java similarity index 98% rename from api/src/test/java/io/opencensus/internal/TestClockTest.java rename to testing/src/test/java/io/opencensus/testing/common/TestClockTest.java index fe3f80cb65..f67080c7e9 100644 --- a/api/src/test/java/io/opencensus/internal/TestClockTest.java +++ b/testing/src/test/java/io/opencensus/testing/common/TestClockTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.internal; +package io.opencensus.testing.common; import static com.google.common.truth.Truth.assertThat; From 08b8962fb72f56b091dcd805b0d9df483a83b2ca Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 16 Jun 2017 17:36:30 -0700 Subject: [PATCH 0176/1581] Move stats classes to io.opencensus.stats. The stats classes are still in different directories from tracing, so they won't be included in the next release. --- build.gradle | 3 +- core/build.gradle | 2 +- .../opencensus}/stats/BucketBoundaries.java | 2 +- .../opencensus}/stats/ContextUtils.java | 2 +- .../opencensus}/stats/Distribution.java | 2 +- .../stats/DistributionAggregation.java | 2 +- .../DistributionAggregationDescriptor.java | 2 +- .../stats/IntervalAggregation.java | 2 +- .../stats/IntervalAggregationDescriptor.java | 2 +- .../stats/MeasurementDescriptor.java | 2 +- .../opencensus}/stats/MeasurementMap.java | 2 +- .../opencensus}/stats/MeasurementValue.java | 2 +- .../stats/MutableDistribution.java | 2 +- .../opencensus}/stats/RpcConstants.java | 11 ++-- .../stats/RpcMeasurementConstants.java | 6 +- .../opencensus}/stats/RpcViewConstants.java | 61 +++++++++---------- .../opencensus}/stats/Stats.java | 6 +- .../opencensus}/stats/StatsContext.java | 2 +- .../stats/StatsContextFactory.java | 2 +- .../opencensus}/stats/StatsManager.java | 2 +- .../opencensus}/stats/Tag.java | 2 +- .../opencensus}/stats/TagKey.java | 2 +- .../opencensus}/stats/TagValue.java | 2 +- .../opencensus}/stats/View.java | 7 +-- .../opencensus}/stats/ViewDescriptor.java | 2 +- .../stats/BucketBoundariesTest.java | 4 +- .../opencensus}/stats/ContextUtilsTest.java | 4 +- ...DistributionAggregationDescriptorTest.java | 2 +- .../stats/DistributionAggregationTest.java | 4 +- .../opencensus}/stats/DistributionTest.java | 4 +- .../IntervalAggregationDescriptorTest.java | 2 +- .../stats/IntervalAggregationTest.java | 4 +- .../stats/MeasurementDescriptorTest.java | 6 +- .../opencensus}/stats/MeasurementMapTest.java | 6 +- .../stats/MutableDistributionTest.java | 4 +- .../opencensus}/stats/RpcConstantsTest.java | 2 +- .../stats/RpcMeasurementConstantsTest.java | 2 +- .../stats/RpcViewConstantsTest.java | 2 +- .../opencensus}/stats/StatsTest.java | 2 +- .../opencensus}/stats/TagKeyTest.java | 2 +- .../opencensus}/stats/TagTest.java | 2 +- .../opencensus}/stats/TagValueTest.java | 2 +- .../opencensus}/stats/ViewDescriptorTest.java | 12 ++-- .../opencensus}/stats/ViewTest.java | 18 +++--- .../stats/MeasurementDescriptorToViewMap.java | 11 ++-- .../opencensus}/stats/MutableView.java | 9 ++- .../stats/StatsContextFactoryImpl.java | 2 +- .../opencensus}/stats/StatsContextImpl.java | 2 +- .../stats/StatsManagerImplBase.java | 2 +- .../opencensus}/stats/StatsSerializer.java | 2 +- .../opencensus}/stats/ViewManager.java | 4 +- .../MeasurementDescriptorToViewMapTest.java | 12 ++-- .../opencensus}/stats/MutableViewTest.java | 2 +- .../stats/StatsContextFactoryTest.java | 2 +- .../opencensus}/stats/StatsContextTest.java | 6 +- .../stats/StatsManagerImplTest.java | 16 ++--- .../opencensus}/stats/StatsTestUtil.java | 2 +- .../stats/StatsManagerImplLite.java | 2 +- .../opencensus}/stats/StatsTest.java | 2 +- .../opencensus}/stats/StatsManagerImpl.java | 2 +- .../opencensus}/stats/StatsTest.java | 2 +- examples/build.gradle | 2 +- .../examples/stats/StatsRunner.java | 21 +++---- findbugs-exclude.xml | 2 +- 64 files changed, 157 insertions(+), 164 deletions(-) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/BucketBoundaries.java (98%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/ContextUtils.java (98%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/Distribution.java (99%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/DistributionAggregation.java (99%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/DistributionAggregationDescriptor.java (98%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/IntervalAggregation.java (98%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/IntervalAggregationDescriptor.java (98%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/MeasurementDescriptor.java (99%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/MeasurementMap.java (99%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/MeasurementValue.java (96%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/MutableDistribution.java (99%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/RpcConstants.java (98%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/RpcMeasurementConstants.java (97%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/RpcViewConstants.java (87%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/Stats.java (91%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/StatsContext.java (98%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/StatsContextFactory.java (98%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/StatsManager.java (96%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/Tag.java (96%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/TagKey.java (97%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/TagValue.java (97%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/View.java (95%) rename core/src/main/java/{com/google/instrumentation => io/opencensus}/stats/ViewDescriptor.java (99%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/BucketBoundariesTest.java (95%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/ContextUtilsTest.java (98%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/DistributionAggregationDescriptorTest.java (98%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/DistributionAggregationTest.java (96%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/DistributionTest.java (96%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/IntervalAggregationDescriptorTest.java (98%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/IntervalAggregationTest.java (95%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/MeasurementDescriptorTest.java (96%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/MeasurementMapTest.java (95%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/MutableDistributionTest.java (98%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/RpcConstantsTest.java (99%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/RpcMeasurementConstantsTest.java (98%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/RpcViewConstantsTest.java (99%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/StatsTest.java (97%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/TagKeyTest.java (97%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/TagTest.java (97%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/TagValueTest.java (97%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/ViewDescriptorTest.java (95%) rename core/src/test/java/{com/google/instrumentation => io/opencensus}/stats/ViewTest.java (92%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/stats/MeasurementDescriptorToViewMap.java (92%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/stats/MutableView.java (96%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/stats/StatsContextFactoryImpl.java (97%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/stats/StatsContextImpl.java (98%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/stats/StatsManagerImplBase.java (98%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/stats/StatsSerializer.java (99%) rename core_impl/src/main/java/{com/google/instrumentation => io/opencensus}/stats/ViewManager.java (95%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/stats/MeasurementDescriptorToViewMapTest.java (87%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/stats/MutableViewTest.java (95%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/stats/StatsContextFactoryTest.java (99%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/stats/StatsContextTest.java (98%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/stats/StatsManagerImplTest.java (97%) rename core_impl/src/test/java/{com/google/instrumentation => io/opencensus}/stats/StatsTestUtil.java (99%) rename core_impl_android/src/main/java/{com/google/instrumentation => io/opencensus}/stats/StatsManagerImplLite.java (95%) rename core_impl_android/src/test/java/{com/google/instrumentation => io/opencensus}/stats/StatsTest.java (96%) rename core_impl_java/src/main/java/{com/google/instrumentation => io/opencensus}/stats/StatsManagerImpl.java (95%) rename core_impl_java/src/test/java/{com/google/instrumentation => io/opencensus}/stats/StatsTest.java (96%) rename examples/src/main/java/{com/google/instrumentation => io/opencensus}/examples/stats/StatsRunner.java (83%) diff --git a/build.gradle b/build.gradle index 483d2be233..23cab392bd 100644 --- a/build.gradle +++ b/build.gradle @@ -163,7 +163,8 @@ subprojects { } checkstyleTest { - excludes = ["com/google/instrumentation/**"] + // TODO(sebright): Fix style errors in stats tests. + excludes = ["io/opencensus/stats/**"] } // Disable checkstyle if no java8. diff --git a/core/build.gradle b/core/build.gradle index 1d2266c168..ba3b45d34a 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -17,4 +17,4 @@ dependencies { signature "org.codehaus.mojo.signature:java16:+@signature" } -javadoc.exclude 'com/google/instrumentation/internal/**' \ No newline at end of file +javadoc.exclude 'io/opencensus/internal/**' \ No newline at end of file diff --git a/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java b/core/src/main/java/io/opencensus/stats/BucketBoundaries.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java rename to core/src/main/java/io/opencensus/stats/BucketBoundaries.java index a6aec37ffb..07f5ad1eb3 100644 --- a/core/src/main/java/com/google/instrumentation/stats/BucketBoundaries.java +++ b/core/src/main/java/io/opencensus/stats/BucketBoundaries.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/stats/ContextUtils.java b/core/src/main/java/io/opencensus/stats/ContextUtils.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/stats/ContextUtils.java rename to core/src/main/java/io/opencensus/stats/ContextUtils.java index 745db2d9cc..6705945e50 100644 --- a/core/src/main/java/com/google/instrumentation/stats/ContextUtils.java +++ b/core/src/main/java/io/opencensus/stats/ContextUtils.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import io.grpc.Context; import io.opencensus.common.NonThrowingCloseable; diff --git a/core/src/main/java/com/google/instrumentation/stats/Distribution.java b/core/src/main/java/io/opencensus/stats/Distribution.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/stats/Distribution.java rename to core/src/main/java/io/opencensus/stats/Distribution.java index f9f685a70a..a2806727e9 100644 --- a/core/src/main/java/com/google/instrumentation/stats/Distribution.java +++ b/core/src/main/java/io/opencensus/stats/Distribution.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.auto.value.AutoValue; import java.util.ArrayList; diff --git a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java b/core/src/main/java/io/opencensus/stats/DistributionAggregation.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java rename to core/src/main/java/io/opencensus/stats/DistributionAggregation.java index 397679370a..64bc248576 100644 --- a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregation.java +++ b/core/src/main/java/io/opencensus/stats/DistributionAggregation.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.auto.value.AutoValue; import com.google.common.base.Preconditions; diff --git a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregationDescriptor.java b/core/src/main/java/io/opencensus/stats/DistributionAggregationDescriptor.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/stats/DistributionAggregationDescriptor.java rename to core/src/main/java/io/opencensus/stats/DistributionAggregationDescriptor.java index e0d9167bbf..88b2bfea4e 100644 --- a/core/src/main/java/com/google/instrumentation/stats/DistributionAggregationDescriptor.java +++ b/core/src/main/java/io/opencensus/stats/DistributionAggregationDescriptor.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.auto.value.AutoValue; import java.util.List; diff --git a/core/src/main/java/com/google/instrumentation/stats/IntervalAggregation.java b/core/src/main/java/io/opencensus/stats/IntervalAggregation.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/stats/IntervalAggregation.java rename to core/src/main/java/io/opencensus/stats/IntervalAggregation.java index 97c8c6cdfb..c7c548ca48 100644 --- a/core/src/main/java/com/google/instrumentation/stats/IntervalAggregation.java +++ b/core/src/main/java/io/opencensus/stats/IntervalAggregation.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import io.opencensus.common.Duration; diff --git a/core/src/main/java/com/google/instrumentation/stats/IntervalAggregationDescriptor.java b/core/src/main/java/io/opencensus/stats/IntervalAggregationDescriptor.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/stats/IntervalAggregationDescriptor.java rename to core/src/main/java/io/opencensus/stats/IntervalAggregationDescriptor.java index 3af843bb90..01477f399d 100644 --- a/core/src/main/java/com/google/instrumentation/stats/IntervalAggregationDescriptor.java +++ b/core/src/main/java/io/opencensus/stats/IntervalAggregationDescriptor.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import io.opencensus.common.Duration; diff --git a/core/src/main/java/com/google/instrumentation/stats/MeasurementDescriptor.java b/core/src/main/java/io/opencensus/stats/MeasurementDescriptor.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/stats/MeasurementDescriptor.java rename to core/src/main/java/io/opencensus/stats/MeasurementDescriptor.java index e34c76fa1b..996686977b 100644 --- a/core/src/main/java/com/google/instrumentation/stats/MeasurementDescriptor.java +++ b/core/src/main/java/io/opencensus/stats/MeasurementDescriptor.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.auto.value.AutoValue; import io.opencensus.internal.StringUtil; diff --git a/core/src/main/java/com/google/instrumentation/stats/MeasurementMap.java b/core/src/main/java/io/opencensus/stats/MeasurementMap.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/stats/MeasurementMap.java rename to core/src/main/java/io/opencensus/stats/MeasurementMap.java index a0f2545efc..a961bf17d5 100644 --- a/core/src/main/java/com/google/instrumentation/stats/MeasurementMap.java +++ b/core/src/main/java/io/opencensus/stats/MeasurementMap.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import java.util.ArrayList; import java.util.Iterator; diff --git a/core/src/main/java/com/google/instrumentation/stats/MeasurementValue.java b/core/src/main/java/io/opencensus/stats/MeasurementValue.java similarity index 96% rename from core/src/main/java/com/google/instrumentation/stats/MeasurementValue.java rename to core/src/main/java/io/opencensus/stats/MeasurementValue.java index 3502b97b62..6c9cc3a65f 100644 --- a/core/src/main/java/com/google/instrumentation/stats/MeasurementValue.java +++ b/core/src/main/java/io/opencensus/stats/MeasurementValue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; /** * Immutable representation of a MeasurementValue. diff --git a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java b/core/src/main/java/io/opencensus/stats/MutableDistribution.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java rename to core/src/main/java/io/opencensus/stats/MutableDistribution.java index 5fefe2400f..4cf93c4d0b 100644 --- a/core/src/main/java/com/google/instrumentation/stats/MutableDistribution.java +++ b/core/src/main/java/io/opencensus/stats/MutableDistribution.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/stats/RpcConstants.java b/core/src/main/java/io/opencensus/stats/RpcConstants.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/stats/RpcConstants.java rename to core/src/main/java/io/opencensus/stats/RpcConstants.java index c2663368a0..095cdfea61 100644 --- a/core/src/main/java/com/google/instrumentation/stats/RpcConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcConstants.java @@ -11,14 +11,13 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; -import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; -import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; -import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; import io.opencensus.common.Duration; - +import io.opencensus.stats.MeasurementDescriptor.BasicUnit; +import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; +import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; +import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/com/google/instrumentation/stats/RpcMeasurementConstants.java b/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java similarity index 97% rename from core/src/main/java/com/google/instrumentation/stats/RpcMeasurementConstants.java rename to core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java index 6de20bc4a1..42ac4e448f 100644 --- a/core/src/main/java/com/google/instrumentation/stats/RpcMeasurementConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java @@ -11,10 +11,10 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; -import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; -import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; +import io.opencensus.stats.MeasurementDescriptor.BasicUnit; +import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; import java.util.Arrays; import java.util.List; diff --git a/core/src/main/java/com/google/instrumentation/stats/RpcViewConstants.java b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java similarity index 87% rename from core/src/main/java/com/google/instrumentation/stats/RpcViewConstants.java rename to core/src/main/java/io/opencensus/stats/RpcViewConstants.java index 2da8bc1cc3..79d743b56e 100644 --- a/core/src/main/java/com/google/instrumentation/stats/RpcViewConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java @@ -11,38 +11,37 @@ * limitations under the License. */ -package com.google.instrumentation.stats; - -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_ERROR_COUNT; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_FINISHED_COUNT; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_METHOD; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_REQUEST_BYTES; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_REQUEST_COUNT; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_RESPONSE_BYTES; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_RESPONSE_COUNT; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_SERVER_ELAPSED_TIME; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_STARTED_COUNT; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_ERROR_COUNT; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_FINISHED_COUNT; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_METHOD; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_REQUEST_BYTES; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_REQUEST_COUNT; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_RESPONSE_BYTES; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_RESPONSE_COUNT; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_SERVER_ELAPSED_TIME; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_SERVER_LATENCY; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_STARTED_COUNT; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES; -import static com.google.instrumentation.stats.RpcMeasurementConstants.RPC_STATUS; - -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; -import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; -import io.opencensus.common.Duration; +package io.opencensus.stats; + +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_ERROR_COUNT; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_FINISHED_COUNT; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_METHOD; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_REQUEST_BYTES; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_REQUEST_COUNT; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_RESPONSE_BYTES; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_RESPONSE_COUNT; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_SERVER_ELAPSED_TIME; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_STARTED_COUNT; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_ERROR_COUNT; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_FINISHED_COUNT; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_METHOD; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_REQUEST_BYTES; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_REQUEST_COUNT; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_RESPONSE_BYTES; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_RESPONSE_COUNT; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_SERVER_ELAPSED_TIME; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_SERVER_LATENCY; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_STARTED_COUNT; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES; +import static io.opencensus.stats.RpcMeasurementConstants.RPC_STATUS; +import io.opencensus.common.Duration; +import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; +import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/com/google/instrumentation/stats/Stats.java b/core/src/main/java/io/opencensus/stats/Stats.java similarity index 91% rename from core/src/main/java/com/google/instrumentation/stats/Stats.java rename to core/src/main/java/io/opencensus/stats/Stats.java index 618eaacaa5..05e44d9a15 100644 --- a/core/src/main/java/com/google/instrumentation/stats/Stats.java +++ b/core/src/main/java/io/opencensus/stats/Stats.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.common.annotations.VisibleForTesting; import io.opencensus.internal.Provider; @@ -45,7 +45,7 @@ static StatsManager loadStatsManager(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. return Provider.createInstance( - Class.forName("com.google.instrumentation.stats.StatsManagerImpl", true, classLoader), + Class.forName("io.opencensus.stats.StatsManagerImpl", true, classLoader), StatsManager.class); } catch (ClassNotFoundException e) { logger.log( @@ -57,7 +57,7 @@ static StatsManager loadStatsManager(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. return Provider.createInstance( - Class.forName("com.google.instrumentation.stats.StatsManagerImplLite", true, classLoader), + Class.forName("io.opencensus.stats.StatsManagerImplLite", true, classLoader), StatsManager.class); } catch (ClassNotFoundException e) { logger.log( diff --git a/core/src/main/java/com/google/instrumentation/stats/StatsContext.java b/core/src/main/java/io/opencensus/stats/StatsContext.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/stats/StatsContext.java rename to core/src/main/java/io/opencensus/stats/StatsContext.java index 8858299136..1be9434452 100644 --- a/core/src/main/java/com/google/instrumentation/stats/StatsContext.java +++ b/core/src/main/java/io/opencensus/stats/StatsContext.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import java.io.IOException; import java.io.OutputStream; diff --git a/core/src/main/java/com/google/instrumentation/stats/StatsContextFactory.java b/core/src/main/java/io/opencensus/stats/StatsContextFactory.java similarity index 98% rename from core/src/main/java/com/google/instrumentation/stats/StatsContextFactory.java rename to core/src/main/java/io/opencensus/stats/StatsContextFactory.java index 88ac718e46..75b5026d96 100644 --- a/core/src/main/java/com/google/instrumentation/stats/StatsContextFactory.java +++ b/core/src/main/java/io/opencensus/stats/StatsContextFactory.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/core/src/main/java/com/google/instrumentation/stats/StatsManager.java b/core/src/main/java/io/opencensus/stats/StatsManager.java similarity index 96% rename from core/src/main/java/com/google/instrumentation/stats/StatsManager.java rename to core/src/main/java/io/opencensus/stats/StatsManager.java index 16a4743723..bfdbee644b 100644 --- a/core/src/main/java/com/google/instrumentation/stats/StatsManager.java +++ b/core/src/main/java/io/opencensus/stats/StatsManager.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; /** * Provides facillities to register {@link ViewDescriptor}s for collecting stats and retrieving diff --git a/core/src/main/java/com/google/instrumentation/stats/Tag.java b/core/src/main/java/io/opencensus/stats/Tag.java similarity index 96% rename from core/src/main/java/com/google/instrumentation/stats/Tag.java rename to core/src/main/java/io/opencensus/stats/Tag.java index 7486055884..995af976d5 100644 --- a/core/src/main/java/com/google/instrumentation/stats/Tag.java +++ b/core/src/main/java/io/opencensus/stats/Tag.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.auto.value.AutoValue; import javax.annotation.concurrent.Immutable; diff --git a/core/src/main/java/com/google/instrumentation/stats/TagKey.java b/core/src/main/java/io/opencensus/stats/TagKey.java similarity index 97% rename from core/src/main/java/com/google/instrumentation/stats/TagKey.java rename to core/src/main/java/io/opencensus/stats/TagKey.java index c0531e77b2..1732b4c6f0 100644 --- a/core/src/main/java/com/google/instrumentation/stats/TagKey.java +++ b/core/src/main/java/io/opencensus/stats/TagKey.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.auto.value.AutoValue; import io.opencensus.internal.StringUtil; diff --git a/core/src/main/java/com/google/instrumentation/stats/TagValue.java b/core/src/main/java/io/opencensus/stats/TagValue.java similarity index 97% rename from core/src/main/java/com/google/instrumentation/stats/TagValue.java rename to core/src/main/java/io/opencensus/stats/TagValue.java index 18cfd19275..84f795c273 100644 --- a/core/src/main/java/com/google/instrumentation/stats/TagValue.java +++ b/core/src/main/java/io/opencensus/stats/TagValue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.auto.value.AutoValue; import io.opencensus.internal.StringUtil; diff --git a/core/src/main/java/com/google/instrumentation/stats/View.java b/core/src/main/java/io/opencensus/stats/View.java similarity index 95% rename from core/src/main/java/com/google/instrumentation/stats/View.java rename to core/src/main/java/io/opencensus/stats/View.java index 56fbb767d4..ed8841fbd5 100644 --- a/core/src/main/java/com/google/instrumentation/stats/View.java +++ b/core/src/main/java/io/opencensus/stats/View.java @@ -11,14 +11,13 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.auto.value.AutoValue; -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; -import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; import io.opencensus.common.Function; import io.opencensus.common.Timestamp; - +import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; +import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java b/core/src/main/java/io/opencensus/stats/ViewDescriptor.java similarity index 99% rename from core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java rename to core/src/main/java/io/opencensus/stats/ViewDescriptor.java index 99e408acad..bef15cc5b1 100644 --- a/core/src/main/java/com/google/instrumentation/stats/ViewDescriptor.java +++ b/core/src/main/java/io/opencensus/stats/ViewDescriptor.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.auto.value.AutoValue; import io.opencensus.common.Function; diff --git a/core/src/test/java/com/google/instrumentation/stats/BucketBoundariesTest.java b/core/src/test/java/io/opencensus/stats/BucketBoundariesTest.java similarity index 95% rename from core/src/test/java/com/google/instrumentation/stats/BucketBoundariesTest.java rename to core/src/test/java/io/opencensus/stats/BucketBoundariesTest.java index 7b6ed8e79a..8b850d248d 100644 --- a/core/src/test/java/com/google/instrumentation/stats/BucketBoundariesTest.java +++ b/core/src/test/java/io/opencensus/stats/BucketBoundariesTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; @@ -26,7 +26,7 @@ import org.junit.runners.JUnit4; /** - * Unit tests for {@link com.google.instrumentation.stats.BucketBoundaries}. + * Unit tests for {@link io.opencensus.stats.BucketBoundaries}. */ @RunWith(JUnit4.class) public class BucketBoundariesTest { diff --git a/core/src/test/java/com/google/instrumentation/stats/ContextUtilsTest.java b/core/src/test/java/io/opencensus/stats/ContextUtilsTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/stats/ContextUtilsTest.java rename to core/src/test/java/io/opencensus/stats/ContextUtilsTest.java index 5affcf3f4f..48e1504d62 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ContextUtilsTest.java +++ b/core/src/test/java/io/opencensus/stats/ContextUtilsTest.java @@ -11,12 +11,12 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; -import io.opencensus.common.NonThrowingCloseable; import io.grpc.Context; +import io.opencensus.common.NonThrowingCloseable; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationDescriptorTest.java b/core/src/test/java/io/opencensus/stats/DistributionAggregationDescriptorTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/stats/DistributionAggregationDescriptorTest.java rename to core/src/test/java/io/opencensus/stats/DistributionAggregationDescriptorTest.java index 4eb77d6f65..065c6bb5f4 100644 --- a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationDescriptorTest.java +++ b/core/src/test/java/io/opencensus/stats/DistributionAggregationDescriptorTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java b/core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java similarity index 96% rename from core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java rename to core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java index 6094adfcb4..eceb9bb29c 100644 --- a/core/src/test/java/com/google/instrumentation/stats/DistributionAggregationTest.java +++ b/core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java @@ -11,12 +11,12 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import com.google.instrumentation.stats.DistributionAggregation.Range; +import io.opencensus.stats.DistributionAggregation.Range; import java.util.Arrays; import java.util.List; import org.junit.Test; diff --git a/core/src/test/java/com/google/instrumentation/stats/DistributionTest.java b/core/src/test/java/io/opencensus/stats/DistributionTest.java similarity index 96% rename from core/src/test/java/com/google/instrumentation/stats/DistributionTest.java rename to core/src/test/java/io/opencensus/stats/DistributionTest.java index 1871e68a82..f6c2ccb0da 100644 --- a/core/src/test/java/com/google/instrumentation/stats/DistributionTest.java +++ b/core/src/test/java/io/opencensus/stats/DistributionTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; @@ -21,7 +21,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@link com.google.instrumentation.stats.Distribution}. */ +/** Unit tests for {@link io.opencensus.stats.Distribution}. */ @RunWith(JUnit4.class) public class DistributionTest { private static final double TOLERANCE = 1e-6; diff --git a/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationDescriptorTest.java b/core/src/test/java/io/opencensus/stats/IntervalAggregationDescriptorTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/stats/IntervalAggregationDescriptorTest.java rename to core/src/test/java/io/opencensus/stats/IntervalAggregationDescriptorTest.java index 7becbc22ad..62b658f0d6 100644 --- a/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationDescriptorTest.java +++ b/core/src/test/java/io/opencensus/stats/IntervalAggregationDescriptorTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationTest.java b/core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java similarity index 95% rename from core/src/test/java/com/google/instrumentation/stats/IntervalAggregationTest.java rename to core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java index 0f92035af1..fe3d42e015 100644 --- a/core/src/test/java/com/google/instrumentation/stats/IntervalAggregationTest.java +++ b/core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java @@ -11,12 +11,12 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.Duration; -import com.google.instrumentation.stats.IntervalAggregation.Interval; +import io.opencensus.stats.IntervalAggregation.Interval; import java.util.Arrays; import java.util.List; import org.junit.Test; diff --git a/core/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorTest.java b/core/src/test/java/io/opencensus/stats/MeasurementDescriptorTest.java similarity index 96% rename from core/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorTest.java rename to core/src/test/java/io/opencensus/stats/MeasurementDescriptorTest.java index a34b9897bd..47b6bc5759 100644 --- a/core/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorTest.java +++ b/core/src/test/java/io/opencensus/stats/MeasurementDescriptorTest.java @@ -11,14 +11,14 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; import io.opencensus.internal.StringUtil; -import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; -import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; +import io.opencensus.stats.MeasurementDescriptor.BasicUnit; +import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; import java.util.Arrays; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core/src/test/java/com/google/instrumentation/stats/MeasurementMapTest.java b/core/src/test/java/io/opencensus/stats/MeasurementMapTest.java similarity index 95% rename from core/src/test/java/com/google/instrumentation/stats/MeasurementMapTest.java rename to core/src/test/java/io/opencensus/stats/MeasurementMapTest.java index 562183b04d..0f9f52f155 100644 --- a/core/src/test/java/com/google/instrumentation/stats/MeasurementMapTest.java +++ b/core/src/test/java/io/opencensus/stats/MeasurementMapTest.java @@ -11,13 +11,13 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; -import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; -import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; +import io.opencensus.stats.MeasurementDescriptor.BasicUnit; +import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; diff --git a/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java b/core/src/test/java/io/opencensus/stats/MutableDistributionTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java rename to core/src/test/java/io/opencensus/stats/MutableDistributionTest.java index 11cce7350a..029de76db0 100644 --- a/core/src/test/java/com/google/instrumentation/stats/MutableDistributionTest.java +++ b/core/src/test/java/io/opencensus/stats/MutableDistributionTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; @@ -23,7 +23,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@link com.google.instrumentation.stats.MutableDistribution}. */ +/** Unit tests for {@link io.opencensus.stats.MutableDistribution}. */ @RunWith(JUnit4.class) public class MutableDistributionTest { private static final double TOLERANCE = 1e-5; diff --git a/core/src/test/java/com/google/instrumentation/stats/RpcConstantsTest.java b/core/src/test/java/io/opencensus/stats/RpcConstantsTest.java similarity index 99% rename from core/src/test/java/com/google/instrumentation/stats/RpcConstantsTest.java rename to core/src/test/java/io/opencensus/stats/RpcConstantsTest.java index 1ac1626543..01e220652b 100644 --- a/core/src/test/java/com/google/instrumentation/stats/RpcConstantsTest.java +++ b/core/src/test/java/io/opencensus/stats/RpcConstantsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/stats/RpcMeasurementConstantsTest.java b/core/src/test/java/io/opencensus/stats/RpcMeasurementConstantsTest.java similarity index 98% rename from core/src/test/java/com/google/instrumentation/stats/RpcMeasurementConstantsTest.java rename to core/src/test/java/io/opencensus/stats/RpcMeasurementConstantsTest.java index 3999be531a..e15ffc2f6d 100644 --- a/core/src/test/java/com/google/instrumentation/stats/RpcMeasurementConstantsTest.java +++ b/core/src/test/java/io/opencensus/stats/RpcMeasurementConstantsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/stats/RpcViewConstantsTest.java b/core/src/test/java/io/opencensus/stats/RpcViewConstantsTest.java similarity index 99% rename from core/src/test/java/com/google/instrumentation/stats/RpcViewConstantsTest.java rename to core/src/test/java/io/opencensus/stats/RpcViewConstantsTest.java index e79b6b6a27..6ddaf938a0 100644 --- a/core/src/test/java/com/google/instrumentation/stats/RpcViewConstantsTest.java +++ b/core/src/test/java/io/opencensus/stats/RpcViewConstantsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core/src/test/java/io/opencensus/stats/StatsTest.java similarity index 97% rename from core/src/test/java/com/google/instrumentation/stats/StatsTest.java rename to core/src/test/java/io/opencensus/stats/StatsTest.java index 2e2ca75526..2dcd680edf 100644 --- a/core/src/test/java/com/google/instrumentation/stats/StatsTest.java +++ b/core/src/test/java/io/opencensus/stats/StatsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/stats/TagKeyTest.java b/core/src/test/java/io/opencensus/stats/TagKeyTest.java similarity index 97% rename from core/src/test/java/com/google/instrumentation/stats/TagKeyTest.java rename to core/src/test/java/io/opencensus/stats/TagKeyTest.java index c0c8657beb..e412b53c77 100644 --- a/core/src/test/java/com/google/instrumentation/stats/TagKeyTest.java +++ b/core/src/test/java/io/opencensus/stats/TagKeyTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/stats/TagTest.java b/core/src/test/java/io/opencensus/stats/TagTest.java similarity index 97% rename from core/src/test/java/com/google/instrumentation/stats/TagTest.java rename to core/src/test/java/io/opencensus/stats/TagTest.java index c628485c53..4ab7a201b8 100644 --- a/core/src/test/java/com/google/instrumentation/stats/TagTest.java +++ b/core/src/test/java/io/opencensus/stats/TagTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/stats/TagValueTest.java b/core/src/test/java/io/opencensus/stats/TagValueTest.java similarity index 97% rename from core/src/test/java/com/google/instrumentation/stats/TagValueTest.java rename to core/src/test/java/io/opencensus/stats/TagValueTest.java index b3e663ec21..d69a18d69c 100644 --- a/core/src/test/java/com/google/instrumentation/stats/TagValueTest.java +++ b/core/src/test/java/io/opencensus/stats/TagValueTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java b/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java similarity index 95% rename from core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java rename to core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java index f9f3bc2d18..c0ee71437e 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ViewDescriptorTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java @@ -11,20 +11,18 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; - import static org.junit.Assert.assertTrue; import com.google.common.testing.EqualsTester; import io.opencensus.common.Duration; import io.opencensus.common.Function; -import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; -import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; -import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; - +import io.opencensus.stats.MeasurementDescriptor.BasicUnit; +import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; +import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; +import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Arrays; import java.util.List; import org.junit.Test; diff --git a/core/src/test/java/com/google/instrumentation/stats/ViewTest.java b/core/src/test/java/io/opencensus/stats/ViewTest.java similarity index 92% rename from core/src/test/java/com/google/instrumentation/stats/ViewTest.java rename to core/src/test/java/io/opencensus/stats/ViewTest.java index 6f899f168c..1089af5dea 100644 --- a/core/src/test/java/com/google/instrumentation/stats/ViewTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertTrue; @@ -20,14 +20,14 @@ import io.opencensus.common.Duration; import io.opencensus.common.Function; import io.opencensus.common.Timestamp; -import com.google.instrumentation.stats.DistributionAggregation.Range; -import com.google.instrumentation.stats.IntervalAggregation.Interval; -import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; -import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; -import com.google.instrumentation.stats.View.DistributionView; -import com.google.instrumentation.stats.View.IntervalView; -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; -import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.stats.DistributionAggregation.Range; +import io.opencensus.stats.IntervalAggregation.Interval; +import io.opencensus.stats.MeasurementDescriptor.BasicUnit; +import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.View.IntervalView; +import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; +import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/io/opencensus/stats/MeasurementDescriptorToViewMap.java similarity index 92% rename from core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java rename to core_impl/src/main/java/io/opencensus/stats/MeasurementDescriptorToViewMap.java index 8bd35aaeb3..5b39ef97ad 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/io/opencensus/stats/MeasurementDescriptorToViewMap.java @@ -11,17 +11,16 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; -import com.google.instrumentation.stats.MutableView.MutableDistributionView; -import com.google.instrumentation.stats.MutableView.MutableIntervalView; -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; -import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; import io.opencensus.common.Clock; import io.opencensus.common.Function; - +import io.opencensus.stats.MutableView.MutableDistributionView; +import io.opencensus.stats.MutableView.MutableIntervalView; +import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; +import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Collection; import java.util.HashMap; import java.util.Map; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java b/core_impl/src/main/java/io/opencensus/stats/MutableView.java similarity index 96% rename from core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java rename to core_impl/src/main/java/io/opencensus/stats/MutableView.java index 141c4a910f..688991cb00 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/MutableView.java +++ b/core_impl/src/main/java/io/opencensus/stats/MutableView.java @@ -11,15 +11,14 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.common.annotations.VisibleForTesting; -import com.google.instrumentation.stats.View.DistributionView; -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; -import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; import io.opencensus.common.Clock; import io.opencensus.common.Timestamp; - +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; +import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.ArrayList; import java.util.HashMap; import java.util.List; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java b/core_impl/src/main/java/io/opencensus/stats/StatsContextFactoryImpl.java similarity index 97% rename from core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java rename to core_impl/src/main/java/io/opencensus/stats/StatsContextFactoryImpl.java index 149e8c12d4..ca23cbb9f5 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsContextFactoryImpl.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.common.base.Preconditions; import java.io.IOException; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java b/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java similarity index 98% rename from core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java rename to core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java index c4924df2d1..2faf0b0315 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsContextImpl.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.common.base.Preconditions; import java.io.IOException; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java b/core_impl/src/main/java/io/opencensus/stats/StatsManagerImplBase.java similarity index 98% rename from core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java rename to core_impl/src/main/java/io/opencensus/stats/StatsManagerImplBase.java index 76a84fcdab..a523fcf7cb 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsManagerImplBase.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsManagerImplBase.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import io.opencensus.common.Clock; import io.opencensus.internal.EventQueue; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java b/core_impl/src/main/java/io/opencensus/stats/StatsSerializer.java similarity index 99% rename from core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java rename to core_impl/src/main/java/io/opencensus/stats/StatsSerializer.java index 13e5450a82..945ead384b 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsSerializer.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.common.annotations.VisibleForTesting; import com.google.common.io.ByteStreams; diff --git a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java b/core_impl/src/main/java/io/opencensus/stats/ViewManager.java similarity index 95% rename from core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java rename to core_impl/src/main/java/io/opencensus/stats/ViewManager.java index f69a688016..cade127eaa 100644 --- a/core_impl/src/main/java/com/google/instrumentation/stats/ViewManager.java +++ b/core_impl/src/main/java/io/opencensus/stats/ViewManager.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.common.Clock; import io.opencensus.internal.EventQueue; +import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; /** Object that stores all views and stats. */ final class ViewManager { diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java b/core_impl/src/test/java/io/opencensus/stats/MeasurementDescriptorToViewMapTest.java similarity index 87% rename from core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java rename to core_impl/src/test/java/io/opencensus/stats/MeasurementDescriptorToViewMapTest.java index 86f344be41..0f61803e51 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/MeasurementDescriptorToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MeasurementDescriptorToViewMapTest.java @@ -11,19 +11,19 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import io.opencensus.common.Function; import io.opencensus.common.Timestamp; +import io.opencensus.stats.MeasurementDescriptor.BasicUnit; +import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.View.IntervalView; +import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.testing.common.TestClock; -import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; -import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; -import com.google.instrumentation.stats.View.DistributionView; -import com.google.instrumentation.stats.View.IntervalView; -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; import java.util.Arrays; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/MutableViewTest.java b/core_impl/src/test/java/io/opencensus/stats/MutableViewTest.java similarity index 95% rename from core_impl/src/test/java/com/google/instrumentation/stats/MutableViewTest.java rename to core_impl/src/test/java/io/opencensus/stats/MutableViewTest.java index e8741ee399..51265d7cc8 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/MutableViewTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MutableViewTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java similarity index 99% rename from core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java rename to core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java index e2ca9beb6d..f38c1d6e2e 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextFactoryTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java similarity index 98% rename from core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java rename to core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index c30750c999..9c77f5f418 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; @@ -22,8 +22,8 @@ import io.opencensus.internal.SimpleEventQueue; import io.opencensus.testing.common.TestClock; import io.opencensus.internal.VarInt; -import com.google.instrumentation.stats.View.DistributionView; -import com.google.instrumentation.stats.View.IntervalView; +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.View.IntervalView; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsManagerImplTest.java similarity index 97% rename from core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java rename to core_impl/src/test/java/io/opencensus/stats/StatsManagerImplTest.java index 7297540b6b..a964db102d 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsManagerImplTest.java @@ -11,20 +11,20 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; -import static com.google.instrumentation.stats.StatsTestUtil.createContext; +import static io.opencensus.stats.StatsTestUtil.createContext; import io.opencensus.common.Duration; -import io.opencensus.internal.SimpleEventQueue; import io.opencensus.common.Timestamp; +import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.stats.MeasurementDescriptor.BasicUnit; +import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; +import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import io.opencensus.testing.common.TestClock; -import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; -import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; -import com.google.instrumentation.stats.View.DistributionView; -import com.google.instrumentation.stats.ViewDescriptor.DistributionViewDescriptor; -import com.google.instrumentation.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Arrays; import java.util.Collection; import java.util.List; diff --git a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java similarity index 99% rename from core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java rename to core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java index 58b9ef2c8d..6d2bfb9909 100644 --- a/core_impl/src/test/java/com/google/instrumentation/stats/StatsTestUtil.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import com.google.common.base.Function; import com.google.common.base.Predicates; diff --git a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImplLite.java b/core_impl_android/src/main/java/io/opencensus/stats/StatsManagerImplLite.java similarity index 95% rename from core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImplLite.java rename to core_impl_android/src/main/java/io/opencensus/stats/StatsManagerImplLite.java index 874d56323c..612de6f20e 100644 --- a/core_impl_android/src/main/java/com/google/instrumentation/stats/StatsManagerImplLite.java +++ b/core_impl_android/src/main/java/io/opencensus/stats/StatsManagerImplLite.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import io.opencensus.common.MillisClock; import io.opencensus.internal.SimpleEventQueue; diff --git a/core_impl_android/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java similarity index 96% rename from core_impl_android/src/test/java/com/google/instrumentation/stats/StatsTest.java rename to core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java index be0118496e..346c1e2e55 100644 --- a/core_impl_android/src/test/java/com/google/instrumentation/stats/StatsTest.java +++ b/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java b/core_impl_java/src/main/java/io/opencensus/stats/StatsManagerImpl.java similarity index 95% rename from core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java rename to core_impl_java/src/main/java/io/opencensus/stats/StatsManagerImpl.java index 913a1ef959..67370631ab 100644 --- a/core_impl_java/src/main/java/com/google/instrumentation/stats/StatsManagerImpl.java +++ b/core_impl_java/src/main/java/io/opencensus/stats/StatsManagerImpl.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import io.opencensus.common.MillisClock; import io.opencensus.internal.DisruptorEventQueue; diff --git a/core_impl_java/src/test/java/com/google/instrumentation/stats/StatsTest.java b/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java similarity index 96% rename from core_impl_java/src/test/java/com/google/instrumentation/stats/StatsTest.java rename to core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java index efcff032ba..57b0291012 100644 --- a/core_impl_java/src/test/java/com/google/instrumentation/stats/StatsTest.java +++ b/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package com.google.instrumentation.stats; +package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; diff --git a/examples/build.gradle b/examples/build.gradle index 9439bba934..f471b11c4c 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -19,7 +19,7 @@ apply plugin: 'application' startScripts.enabled = false task statsRunner(type: CreateStartScripts) { - mainClassName = 'com.google.instrumentation.examples.stats.StatsRunner' + mainClassName = 'io.opencensus.examples.stats.StatsRunner' applicationName = 'StatsRunner' outputDir = new File(project.buildDir, 'tmp') classpath = jar.outputs.files + project.configurations.runtime diff --git a/examples/src/main/java/com/google/instrumentation/examples/stats/StatsRunner.java b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java similarity index 83% rename from examples/src/main/java/com/google/instrumentation/examples/stats/StatsRunner.java rename to examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java index 831ce59169..86a4e3dc04 100644 --- a/examples/src/main/java/com/google/instrumentation/examples/stats/StatsRunner.java +++ b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java @@ -11,19 +11,18 @@ * limitations under the License. */ -package com.google.instrumentation.examples.stats; +package io.opencensus.examples.stats; -import com.google.instrumentation.stats.MeasurementDescriptor; -import com.google.instrumentation.stats.MeasurementDescriptor.BasicUnit; -import com.google.instrumentation.stats.MeasurementDescriptor.MeasurementUnit; -import com.google.instrumentation.stats.MeasurementMap; -import com.google.instrumentation.stats.Stats; -import com.google.instrumentation.stats.StatsContext; -import com.google.instrumentation.stats.StatsContextFactory; -import com.google.instrumentation.stats.TagKey; -import com.google.instrumentation.stats.TagValue; import io.opencensus.common.NonThrowingCloseable; - +import io.opencensus.stats.MeasurementDescriptor; +import io.opencensus.stats.MeasurementDescriptor.BasicUnit; +import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; +import io.opencensus.stats.MeasurementMap; +import io.opencensus.stats.Stats; +import io.opencensus.stats.StatsContext; +import io.opencensus.stats.StatsContextFactory; +import io.opencensus.stats.TagKey; +import io.opencensus.stats.TagValue; import java.util.Arrays; /** Simple program that uses Stats contexts. */ diff --git a/findbugs-exclude.xml b/findbugs-exclude.xml index 2993296899..8444032a0d 100644 --- a/findbugs-exclude.xml +++ b/findbugs-exclude.xml @@ -2,7 +2,7 @@ - + From f9857b1875d4a0b3fb2e6194099f3df760bcbaa2 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 16 Jun 2017 18:04:55 -0700 Subject: [PATCH 0177/1581] Enable coverage and Javadocs for all directories. --- all/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/all/build.gradle b/all/build.gradle index ebd032774b..32feb26320 100644 --- a/all/build.gradle +++ b/all/build.gradle @@ -11,15 +11,15 @@ buildscript { } } -// TODO(bdrutu): core_impl_android subproject currently isn't included because Javadoc cannot -// handle multiple classes with the same name, such as StatsManagerImpl. def subprojects = [ project(':opencensus-api'), project(':core'), project(':opencensus-impl-core'), project(':core_impl'), + project(':core_impl_android'), project(':core_impl_java'), project(':opencensus-impl'), + project(':opencensus-impl-lite'), ] for (subproject in rootProject.subprojects) { From 34bf735101af5e4ef1fbf4a375ee2ea8a4b01e4b Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Sun, 18 Jun 2017 18:13:06 +0200 Subject: [PATCH 0178/1581] Add the *OpenCensus Agent for Java* to the build process. (#365) * Add the *OpenCensus Agent for Java* to the build process. * Moved agent to contrib/agent/ (was agent/). --- settings.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/settings.gradle b/settings.gradle index 41395b1ddb..c87aed4a81 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,6 @@ rootProject.name = "opencensus-java" +include ":opencensus-agent" include ":opencensus-api" include ":opencensus-impl-core" include ":opencensus-impl-lite" @@ -11,6 +12,7 @@ include ":core_impl" include ":core_impl_java" include ":core_impl_android" +project(':opencensus-agent').projectDir = "$rootDir/contrib/agent" as File project(':opencensus-api').projectDir = "$rootDir/api" as File project(':opencensus-impl-core').projectDir = "$rootDir/impl_core" as File project(':opencensus-impl-lite').projectDir = "$rootDir/impl_lite" as File From 175ff384e1a8a50d836c9f97621c09e40d195c0a Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Sun, 18 Jun 2017 19:32:34 +0200 Subject: [PATCH 0179/1581] =?UTF-8?q?Initial=20import=20of=20a=20prelimina?= =?UTF-8?q?ry=20README.md=20for=20the=20*OpenCensus=20Agent=20f=E2=80=A6?= =?UTF-8?q?=20(#364)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initial import of a preliminary README.md for the *OpenCensus Agent for Java*, grabbing the name and directory. --- contrib/agent/README.md | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 contrib/agent/README.md diff --git a/contrib/agent/README.md b/contrib/agent/README.md new file mode 100644 index 0000000000..59125cadaf --- /dev/null +++ b/contrib/agent/README.md @@ -0,0 +1,44 @@ +# OpenCensus Agent for Java + +[![Build Status](https://travis-ci.org/census-instrumentation/instrumentation-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/instrumentation-java) [![Build status](https://ci.appveyor.com/api/projects/status/v5dbthkucuewsu33/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/instrumentation-java/branch/master) + +The *OpenCensus Agent for Java* collects and sends latency data about your Java process to +OpenCensus backends such as Zipkin, Stackdriver Trace, etc. for analysis and visualization. + + +## Features + +The *OpenCensus Agent for Java* is in an early development stage. The following features are +currently implemented: + +TODO(stschmidt): Update README.md along with implementation. + + +## Design Ideas + +We see tracing as a cross-cutting concern which the *OpenCensus Agent for Java* weaves into +existing Java bytecode (the application and its libraries) at runtime, typically when first loading +the concerned bytecode. + +This approach allows us to instrument arbitrary code without having to touch the source code of the +application or its dependencies. Furthermore, we don't require the application owner to upgrade any +of the application's third-party dependencies to specific versions. As long as the interface (e.g. +[java.sql.Driver#connect](https://docs.oracle.com/javase/8/docs/api/java/sql/Driver.html#connect-java.lang.String-java.util.Properties-)) +stays as-is across the supported versions, the Java agent's bytecode weaver will be able to +instrument the code. + +The *OpenCensus Agent for Java* uses [Byte Buddy](http://bytebuddy.net/), a widely used and +well-maintained bytecode manipulation library, for instrumenting selected Java methods at class +load-time. Which Java methods we want to intercept/instrument obviously depends on the library +(MongoDB vs. Redis, etc.) and the application. + + +## Installation + +To enable the *OpenCensus Agent for Java* for your application, add the option +`-javaagent:path/to/opencensus-agent.jar` to the invocation of the `java` executable as shown in +the following example: + +```shell +java -javaagent:path/to/opencensus-agent.jar ... +``` From a5c24719305da9d102767de24cd929c60c8c6df6 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 19 Jun 2017 12:15:53 +0200 Subject: [PATCH 0180/1581] Add a skeleton Java agent, which hooks up Bytebuddy, but doesn't do anything yet besides logging. Also add it to the build process, bundling the required classes and dependencies in a single agent JAR file. --- contrib/agent/build.gradle | 40 ++++++++++ .../contrib/agent/AgentBuilderListener.java | 73 +++++++++++++++++++ .../opencensus/contrib/agent/AgentMain.java | 66 +++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 contrib/agent/build.gradle create mode 100644 contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentBuilderListener.java create mode 100644 contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle new file mode 100644 index 0000000000..4bc6065b6e --- /dev/null +++ b/contrib/agent/build.gradle @@ -0,0 +1,40 @@ +plugins { + id 'com.github.johnrengelman.shadow' version '2.0.0' +} + +description = 'OpenCensus Agent' + +sourceCompatibility = 1.7 +targetCompatibility = 1.7 + +def agentPackage = 'io.opencensus.contrib.agent' +def agentMainClass = "${agentPackage}.AgentMain" + +dependencies { + compile group: 'net.bytebuddy', name: 'byte-buddy', version: '1.7.1' + + signature 'org.codehaus.mojo.signature:java17:+@signature' +} + +jar { + // Set required manifest attributes, cf. + // https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html. + manifest { + attributes 'Premain-Class': agentMainClass + attributes 'Can-Retransform-Classes': true + } +} + +// Bundle the agent's classes and dependencies into a single, self-contained JAR file. +shadowJar { + // Output to opencensus-agent-VERSION.jar. + baseName = 'opencensus-agent' + classifier = null + + // TODO(stschmidt): Relocate third party packages to avoid any conflicts of the agent's classes + // with the app's classes, which are loaded by the same classloader (the system classloader). + + // TODO(stschmidt): Assert that there's nothing unexpected left outside of ${agentPackage}. +} + +jar.finalizedBy shadowJar diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentBuilderListener.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentBuilderListener.java new file mode 100644 index 0000000000..08521a2c04 --- /dev/null +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentBuilderListener.java @@ -0,0 +1,73 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent; + +import java.util.logging.Level; +import java.util.logging.Logger; +import net.bytebuddy.agent.builder.AgentBuilder; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.dynamic.DynamicType; +import net.bytebuddy.utility.JavaModule; + +/** + * An {@link AgentBuilder.Listener} which uses {@link java.util.logging} for logging events of + * interest. + */ +final class AgentBuilderListener implements AgentBuilder.Listener { + + private static final Logger logger = Logger.getLogger(AgentBuilderListener.class.getName()); + + @Override + public void onTransformation( + TypeDescription typeDescription, + ClassLoader classLoader, + JavaModule module, + boolean loaded, + DynamicType dynamicType) { + logger.log(Level.FINE, "{0}", typeDescription); + } + + @Override + public void onIgnored( + TypeDescription typeDescription, + ClassLoader classLoader, + JavaModule module, + boolean loaded) { + } + + @Override + public void onError( + String typeName, + ClassLoader classLoader, + JavaModule module, + boolean loaded, + Throwable throwable) { + logger.log(Level.WARNING, "Failed to handle " + typeName, throwable); + } + + @Override + public void onComplete( + String typeName, + ClassLoader classLoader, + JavaModule module, + boolean loaded) { + } + + @Override + public void onDiscovery(String typeName, + ClassLoader classLoader, + JavaModule module, + boolean loaded) { + } +} diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java new file mode 100644 index 0000000000..4e62697f0f --- /dev/null +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -0,0 +1,66 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent; + +import static net.bytebuddy.matcher.ElementMatchers.none; + +import java.lang.instrument.Instrumentation; +import java.util.logging.Logger; +import net.bytebuddy.agent.builder.AgentBuilder; + +/** + * The OpenCensus Agent for Java collects and sends latency data about your Java + * process to OpenCensus backends such as Stackdriver Trace for analysis and visualization. + * + *

            To enable the *OpenCensus Agent for Java* for your application, add the option + * -javaagent:path/to/opencensus-agent.jar to the invocation of the + * java executable as shown in the following example: + * + *

            + * java -javaagent:path/to/opencensus-agent.jar ...
            + * 
            + * + * @see https://github.com/census-instrumentation/instrumentation-java/tree/master/agent + */ +public final class AgentMain { + + private static final Logger logger = Logger.getLogger(AgentMain.class.getName()); + + private AgentMain() { + } + + /** + * Initializes the OpenCensus Agent for Java. + * + * @param agentArgs agent options, passed as a single string by the JVM + * @param inst the {@link Instrumentation} object provided by the JVM for instrumenting Java + * programming language code + * @throws Exception if initialization of the agent fails + * + * @see java.lang.instrument + */ + public static void premain(String agentArgs, Instrumentation inst) throws Exception { + logger.info("Initializing."); + + AgentBuilder agentBuilder = new AgentBuilder.Default() + .disableClassFormatChanges() + .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) + .with(new AgentBuilderListener()) + .ignore(none()); + // TODO(stschmidt): Add instrumentation for context propagation. + agentBuilder.installOn(inst); + + logger.info("Initialized."); + } +} From 83d3453503922014fb11632788c190affa532c2c Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 19 Jun 2017 16:20:07 -0700 Subject: [PATCH 0181/1581] Clean minor things. (#372) --- api/src/main/java/io/opencensus/trace/Span.java | 5 ++--- .../main/java/io/opencensus/trace/base/TraceOptions.java | 5 ++--- .../java/io/opencensus/trace/config/TraceParams.java | 3 +-- .../io/opencensus/trace/export/RunningSpanStore.java | 9 ++++----- .../io/opencensus/trace/export/ExportComponentTest.java | 1 + .../trace/internal/ThreadLocalRandomHandler.java | 1 - .../java/io/opencensus/trace/internal/RandomHandler.java | 6 ++++++ .../io/opencensus/trace/export/RunningSpanStoreTest.java | 3 +++ 8 files changed, 19 insertions(+), 14 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/Span.java b/api/src/main/java/io/opencensus/trace/Span.java index f1661901a0..af6e3adb40 100644 --- a/api/src/main/java/io/opencensus/trace/Span.java +++ b/api/src/main/java/io/opencensus/trace/Span.java @@ -21,7 +21,6 @@ import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; -import io.opencensus.trace.base.StartSpanOptions; import java.util.Collections; import java.util.EnumSet; import java.util.Map; @@ -51,8 +50,8 @@ public abstract class Span { */ public enum Options { /** - * This option is set if the Span is part of a sampled distributed trace OR the {@link - * StartSpanOptions#getRecordEvents()} is true. + * This option is set if the Span is part of a sampled distributed trace OR {@link + * SpanBuilder#setRecordEvents(boolean)} was called with true. */ RECORD_EVENTS; } diff --git a/api/src/main/java/io/opencensus/trace/base/TraceOptions.java b/api/src/main/java/io/opencensus/trace/base/TraceOptions.java index 57733238f8..3f20bb99b6 100644 --- a/api/src/main/java/io/opencensus/trace/base/TraceOptions.java +++ b/api/src/main/java/io/opencensus/trace/base/TraceOptions.java @@ -20,13 +20,12 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; -import io.opencensus.trace.Span; import javax.annotation.concurrent.Immutable; /** * A class that represents global trace options. These options are propagated to all child {@link - * Span spans}. These determine features such as whether a {@code Span} should be traced. It is - * implemented as a bitmask. + * io.opencensus.trace.Span spans}. These determine features such as whether a {@code Span} should + * be traced. It is implemented as a bitmask. */ @Immutable public final class TraceOptions { diff --git a/api/src/main/java/io/opencensus/trace/config/TraceParams.java b/api/src/main/java/io/opencensus/trace/config/TraceParams.java index 74953cfd39..5f1ba3b054 100644 --- a/api/src/main/java/io/opencensus/trace/config/TraceParams.java +++ b/api/src/main/java/io/opencensus/trace/config/TraceParams.java @@ -21,7 +21,6 @@ import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; import io.opencensus.trace.base.Sampler; -import io.opencensus.trace.base.StartSpanOptions; import io.opencensus.trace.samplers.Samplers; import javax.annotation.concurrent.Immutable; @@ -48,7 +47,7 @@ public abstract class TraceParams { /** * Returns the global default {@code Sampler}. Used if no {@code Sampler} is provided in {@link - * StartSpanOptions}. + * io.opencensus.trace.SpanBuilder#setSampler(Sampler)}. * * @return the global default {@code Sampler}. */ diff --git a/api/src/main/java/io/opencensus/trace/export/RunningSpanStore.java b/api/src/main/java/io/opencensus/trace/export/RunningSpanStore.java index 19facc8a76..e87036c4d6 100644 --- a/api/src/main/java/io/opencensus/trace/export/RunningSpanStore.java +++ b/api/src/main/java/io/opencensus/trace/export/RunningSpanStore.java @@ -17,7 +17,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.auto.value.AutoValue; -import io.opencensus.trace.Span; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -29,8 +28,8 @@ * This class allows users to access in-process information about all running spans. * *

            The running spans tracking is available for all the spans with the option {@link - * Span.Options#RECORD_EVENTS}. This functionality allows users to debug stuck operations or long - * living operations. + * io.opencensus.trace.Span.Options#RECORD_EVENTS}. This functionality allows users to debug stuck + * operations or long living operations. */ @ThreadSafe public abstract class RunningSpanStore { @@ -109,8 +108,8 @@ public static PerSpanNameSummary create(int numRunningSpans) { } /** - * Filter for running spans. Used to filter results returned by the - * {@link #getRunningSpans(Filter)} request. + * Filter for running spans. Used to filter results returned by the {@link + * #getRunningSpans(Filter)} request. */ @AutoValue @Immutable diff --git a/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java b/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java index efff03ba1e..82a29b959f 100644 --- a/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java +++ b/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java @@ -29,6 +29,7 @@ public void implementationOfSpanExporter() { assertThat(exportComponent.getSpanExporter()).isEqualTo(SpanExporter.getNoopSpanExporter()); } + @Test public void implementationOfActiveSpans() { assertThat(exportComponent.getRunningSpanStore()).isNull(); } diff --git a/impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java b/impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java index 7cb9b2f25a..c291036bdb 100644 --- a/impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java +++ b/impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java @@ -13,7 +13,6 @@ package io.opencensus.trace.internal; -import io.opencensus.trace.internal.RandomHandler; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; import javax.annotation.concurrent.ThreadSafe; diff --git a/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java b/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java index 8d4060a90f..602a0acc49 100644 --- a/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java +++ b/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java @@ -31,10 +31,16 @@ public abstract class RandomHandler { */ public abstract Random current(); + /** + * Implementation of the {@link RandomHandler} using {@link SecureRandom}. + */ @ThreadSafe public static final class SecureRandomHandler extends RandomHandler { private final Random random = new SecureRandom(); + /** + * Constructs a new {@link SecureRandomHandler}. + */ public SecureRandomHandler() {} @Override diff --git a/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreTest.java b/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreTest.java index dba5cecc7b..16fc1f6e85 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreTest.java @@ -30,8 +30,11 @@ import java.util.EnumSet; import java.util.Random; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Unit tests for {@link RunningSpanStore}. */ +@RunWith(JUnit4.class) public class RunningSpanStoreTest { private static final String SPAN_NAME_1 = "MySpanName/1"; From 181b9b87b504659bcbf5c5eb4a5eba1e96bb278c Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 19 Jun 2017 17:47:58 -0700 Subject: [PATCH 0182/1581] Rename TagMap to TagContext. --- .../tags/{TagMap.java => TagContext.java} | 22 +++++++++---------- .../main/java/io/opencensus/tags/TagKey.java | 2 +- .../{TagMapTest.java => TagContextTest.java} | 20 ++++++++--------- 3 files changed, 22 insertions(+), 22 deletions(-) rename core/src/main/java/io/opencensus/tags/{TagMap.java => TagContext.java} (87%) rename core/src/test/java/io/opencensus/tags/{TagMapTest.java => TagContextTest.java} (86%) diff --git a/core/src/main/java/io/opencensus/tags/TagMap.java b/core/src/main/java/io/opencensus/tags/TagContext.java similarity index 87% rename from core/src/main/java/io/opencensus/tags/TagMap.java rename to core/src/main/java/io/opencensus/tags/TagContext.java index 8edbda0d0e..6b617e4d1d 100644 --- a/core/src/main/java/io/opencensus/tags/TagMap.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -26,18 +26,18 @@ * A map from keys to values that can be used to label anything that is associated with a specific * operation. * - *

            For example, {@code TagMap}s can be used to label stats, log messages, or debugging + *

            For example, {@code TagContext}s can be used to label stats, log messages, or debugging * information. */ @Immutable -public final class TagMap { +public final class TagContext { /** The maximum length for a string tag value. */ public static final int MAX_STRING_LENGTH = StringUtil.MAX_LENGTH; // The types of the TagKey and value must match for each entry. private final Map, Object> tags; - TagMap(Map, Object> tags) { + TagContext(Map, Object> tags) { this.tags = Collections.unmodifiableMap(new HashMap, Object>(tags)); } @@ -46,15 +46,15 @@ Map, Object> getTags() { } /** - * Returns a builder based on this {@code TagMap}. + * Returns a builder based on this {@code TagContext}. * - * @return a builder based on this {@code TagMap}. + * @return a builder based on this {@code TagContext}. */ public Builder toBuilder() { return new Builder(getTags()); } - /** Builder for the {@link TagMap} class. */ + /** Builder for the {@link TagContext} class. */ public static final class Builder { private final Map, Object> tags; @@ -74,7 +74,7 @@ private Builder(Map, Object> tags) { * @return this * @throws IllegalArgumentException if either argument is null, the key is the wrong type, or * the value contains unprintable characters or is longer than {@link - * TagMap#MAX_STRING_LENGTH}. + * TagContext#MAX_STRING_LENGTH}. */ public Builder set(TagKey key, String value) { checkArgument(key.getTagType() == TagType.TAG_STRING); @@ -130,12 +130,12 @@ public Builder clear(TagKey key) { } /** - * Creates a {@code TagMap} from this builder. + * Creates a {@code TagContext} from this builder. * - * @return a {@code TagMap} with the same tags as this builder. + * @return a {@code TagContext} with the same tags as this builder. */ - public TagMap build() { - return new TagMap(new HashMap, Object>(tags)); + public TagContext build() { + return new TagContext(new HashMap, Object>(tags)); } } } diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index efd3e6e9e9..ba93573ddf 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -23,7 +23,7 @@ import javax.annotation.concurrent.Immutable; /** - * A key to a value stored in a {@link TagMap}. + * A key to a value stored in a {@link TagContext}. * * @param The type of value that can be paired with this {@code TagKey}. {@code TagKey}s * can only be instantiated with types {@code String}, {@code Long}, and {@code Boolean}. diff --git a/core/src/test/java/io/opencensus/tags/TagMapTest.java b/core/src/test/java/io/opencensus/tags/TagContextTest.java similarity index 86% rename from core/src/test/java/io/opencensus/tags/TagMapTest.java rename to core/src/test/java/io/opencensus/tags/TagContextTest.java index 41b3b24735..a64cbbeabc 100644 --- a/core/src/test/java/io/opencensus/tags/TagMapTest.java +++ b/core/src/test/java/io/opencensus/tags/TagContextTest.java @@ -23,10 +23,10 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link TagMap}. */ +/** Tests for {@link TagContext}. */ // TODO(sebright): Add more tests once the API is finalized. @RunWith(JUnit4.class) -public class TagMapTest { +public class TagContextTest { @Rule public final ExpectedException thrown = ExpectedException.none(); @@ -56,7 +56,7 @@ public void allowMutlipleKeysWithSameNameButDifferentTypes() { @Test public void testSet() { - TagMap tags = singletonTagMap(KS1, "v1"); + TagContext tags = singletonTagMap(KS1, "v1"); assertThat(tags.toBuilder().set(KS1, "v2").build().getTags()).containsExactly(KS1, "v2"); assertThat(tags.toBuilder().set(KS2, "v2").build().getTags()) .containsExactly(KS1, "v1", KS2, "v2"); @@ -64,14 +64,14 @@ public void testSet() { @Test public void testClear() { - TagMap tags = singletonTagMap(KS1, "v1"); + TagContext tags = singletonTagMap(KS1, "v1"); assertThat(tags.toBuilder().clear(KS1).build().getTags()).isEmpty(); assertThat(tags.toBuilder().clear(KS2).build().getTags()).containsExactly(KS1, "v1"); } @Test public void allowStringTagValueWithMaxLength() { - char[] chars = new char[TagMap.MAX_STRING_LENGTH]; + char[] chars = new char[TagContext.MAX_STRING_LENGTH]; Arrays.fill(chars, 'v'); String value = new String(chars); TagKey key = TagKey.createStringKey("K"); @@ -80,7 +80,7 @@ public void allowStringTagValueWithMaxLength() { @Test public void disallowStringTagValueOverMaxLength() { - char[] chars = new char[TagMap.MAX_STRING_LENGTH + 1]; + char[] chars = new char[TagContext.MAX_STRING_LENGTH + 1]; Arrays.fill(chars, 'v'); String value = new String(chars); TagKey key = TagKey.createStringKey("K"); @@ -104,11 +104,11 @@ public void disallowSettingWrongTypeOfKey() { newBuilder().set(badLongKey, 123); } - private static TagMap.Builder newBuilder() { - return new TagMap.Builder(); + private static TagContext.Builder newBuilder() { + return new TagContext.Builder(); } - private static TagMap singletonTagMap(TagKey key, TagValueT value) { - return new TagMap(ImmutableMap., Object>of(key, value)); + private static TagContext singletonTagMap(TagKey key, TagValueT value) { + return new TagContext(ImmutableMap., Object>of(key, value)); } } From 65f8bda11b6712d42a942bb4d51fd56d618a132b Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 19 Jun 2017 19:33:35 -0700 Subject: [PATCH 0183/1581] =?UTF-8?q?Refactor=20Timestamp=20class=20to=20b?= =?UTF-8?q?e=20safer.=20Add=20methods=20to=20minus=20a=20timestam=E2=80=A6?= =?UTF-8?q?=20(#367)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/opencensus/common/Duration.java | 90 ++++------- .../java/io/opencensus/common/TimeUtil.java | 23 +++ .../java/io/opencensus/common/Timestamp.java | 149 ++++++++++-------- .../io/opencensus/common/TimestampTest.java | 53 +++++++ .../opencensus/testing/common/TestClock.java | 8 +- 5 files changed, 191 insertions(+), 132 deletions(-) create mode 100644 api/src/main/java/io/opencensus/common/TimeUtil.java diff --git a/api/src/main/java/io/opencensus/common/Duration.java b/api/src/main/java/io/opencensus/common/Duration.java index bf490c39f4..dad3ccdb95 100644 --- a/api/src/main/java/io/opencensus/common/Duration.java +++ b/api/src/main/java/io/opencensus/common/Duration.java @@ -13,12 +13,24 @@ package io.opencensus.common; +import static io.opencensus.common.TimeUtil.MAX_NANOS; +import static io.opencensus.common.TimeUtil.MAX_SECONDS; +import static io.opencensus.common.TimeUtil.MILLIS_PER_SECOND; +import static io.opencensus.common.TimeUtil.NANOS_PER_MILLI; + +import com.google.auto.value.AutoValue; +import javax.annotation.concurrent.Immutable; + /** * Represents a signed, fixed-length span of time represented as a count of seconds and fractions of * seconds at nanosecond resolution. It is independent of any calendar and concepts like "day" or * "month". Range is approximately +-10,000 years. */ -public class Duration { +@Immutable +@AutoValue +public abstract class Duration { + private static final Duration ZERO = create(0, 0); + /** * Creates a new time duration from given seconds and nanoseconds. * @@ -29,88 +41,48 @@ public class Duration { * negative `nanos` field. For durations of one second or more, a non-zero value for the * `nanos` field must be of the same sign as the `seconds` field. Must be from -999,999,999 to * +999,999,999 inclusive. - * @return new {@link Duration} with specified fields. For invalid inputs, a {@link Duration} of + * @return new {@code Duration} with specified fields. For invalid inputs, a {@code Duration} of * zero is returned. */ public static Duration create(long seconds, int nanos) { if (seconds < -MAX_SECONDS || seconds > MAX_SECONDS) { - return new Duration(0, 0); + return ZERO; } if (nanos < -MAX_NANOS || nanos > MAX_NANOS) { - return new Duration(0, 0); + return ZERO; } if ((seconds < 0 && nanos > 0) || (seconds > 0 && nanos < 0)) { - return new Duration(0, 0); + return ZERO; } - return new Duration(seconds, nanos); + return new AutoValue_Duration(seconds, nanos); } /** - * Creates a new {@link Duration} from given milliseconds. + * Creates a new {@code Duration} from given milliseconds. * * @param millis the duration in milliseconds. - * @return a new {@link Duration} from given milliseconds. + * @return a new {@code Duration} from given milliseconds. For invalid inputs, a {@code Duration} + * of zero is returned. */ public static Duration fromMillis(long millis) { - long seconds = millis / NUM_MILLIS_PER_SECOND; - int nanos = (int) (millis % NUM_MILLIS_PER_SECOND) * NUM_NANOS_PER_MILLI; - return new Duration(seconds, nanos); + long seconds = millis / MILLIS_PER_SECOND; + int nanos = (int) (millis % MILLIS_PER_SECOND * NANOS_PER_MILLI); + return Duration.create(seconds, nanos); } /** - * Returns the number of seconds in the {@link Duration}. + * Returns the number of seconds in the {@code Duration}. * - * @return the number of seconds in the {@link Duration}. + * @return the number of seconds in the {@code Duration}. */ - public long getSeconds() { - return seconds; - } + public abstract long getSeconds(); /** - * Returns the number of nanoseconds in the {@link Duration}. + * Returns the number of nanoseconds in the {@code Duration}. * - * @return the number of nanoseconds in the {@link Duration}. + * @return the number of nanoseconds in the {@code Duration}. */ - public int getNanos() { - return nanos; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof Duration)) { - return false; - } + public abstract int getNanos(); - Duration that = (Duration) obj; - return seconds == that.seconds && nanos == that.nanos; - } - - @Override - public int hashCode() { - int result = 17; - result = 31 * result + (int) (seconds ^ (seconds >>> 32)); - result = 31 * result + nanos; - return result; - } - - @Override - public String toString() { - return "Duration<" + seconds + "," + nanos + ">"; - } - - private static final long MAX_SECONDS = 315576000000L; - private static final int MAX_NANOS = 999999999; - private static final long NUM_MILLIS_PER_SECOND = 1000L; - private static final int NUM_NANOS_PER_MILLI = 1000000; - private final long seconds; - private final int nanos; - - private Duration(long seconds, int nanos) { - this.seconds = seconds; - this.nanos = nanos; - } + Duration() {} } diff --git a/api/src/main/java/io/opencensus/common/TimeUtil.java b/api/src/main/java/io/opencensus/common/TimeUtil.java new file mode 100644 index 0000000000..d3d8e6471d --- /dev/null +++ b/api/src/main/java/io/opencensus/common/TimeUtil.java @@ -0,0 +1,23 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.common; + +/** Created by bdrutu on 6/14/17. */ +final class TimeUtil { + static final long MAX_SECONDS = 315576000000L; + static final int MAX_NANOS = 999999999; + static final long MILLIS_PER_SECOND = 1000L; + static final long NANOS_PER_MILLI = 1000 * 1000; + static final long NANOS_PER_SECOND = NANOS_PER_MILLI * MILLIS_PER_SECOND; +} diff --git a/api/src/main/java/io/opencensus/common/Timestamp.java b/api/src/main/java/io/opencensus/common/Timestamp.java index 9a1dd8bbeb..68b5efc788 100644 --- a/api/src/main/java/io/opencensus/common/Timestamp.java +++ b/api/src/main/java/io/opencensus/common/Timestamp.java @@ -13,6 +13,15 @@ package io.opencensus.common; +import static io.opencensus.common.TimeUtil.MAX_NANOS; +import static io.opencensus.common.TimeUtil.MAX_SECONDS; +import static io.opencensus.common.TimeUtil.MILLIS_PER_SECOND; +import static io.opencensus.common.TimeUtil.NANOS_PER_MILLI; +import static io.opencensus.common.TimeUtil.NANOS_PER_SECOND; + +import com.google.auto.value.AutoValue; +import com.google.common.math.LongMath; +import java.math.RoundingMode; import javax.annotation.concurrent.Immutable; /** @@ -23,19 +32,11 @@ * (1970-01-01T00:00:00Z). */ @Immutable -public final class Timestamp { - private static final long MAX_SECONDS = 315576000000L; - private static final int MAX_NANOS = 999999999; - private static final long NUM_MILLIS_PER_SECOND = 1000L; - private static final int NUM_NANOS_PER_MILLI = 1000 * 1000; - private static final long NUM_NANOS_PER_SECOND = NUM_NANOS_PER_MILLI * NUM_MILLIS_PER_SECOND; - private final long seconds; - private final int nanos; - - private Timestamp(long seconds, int nanos) { - this.seconds = seconds; - this.nanos = nanos; - } +@AutoValue +public abstract class Timestamp { + private static final Timestamp EPOCH = new AutoValue_Timestamp(0, 0); + + Timestamp() {} /** * Creates a new timestamp from given seconds and nanoseconds. @@ -45,33 +46,30 @@ private Timestamp(long seconds, int nanos) { * @param nanos Non-negative fractions of a second at nanosecond resolution. Negative second * values with fractions must still have non-negative nanos values that count forward in time. * Must be from 0 to 999,999,999 inclusive. - * @return new {@link Timestamp} with specified fields. For invalid inputs, a {@link Timestamp} of + * @return new {@code Timestamp} with specified fields. For invalid inputs, a {@code Timestamp} of * zero is returned. */ public static Timestamp create(long seconds, int nanos) { if (seconds < -MAX_SECONDS || seconds > MAX_SECONDS) { - return new Timestamp(0, 0); + return EPOCH; } if (nanos < 0 || nanos > MAX_NANOS) { - return new Timestamp(0, 0); + return EPOCH; } - return new Timestamp(seconds, nanos); + return new AutoValue_Timestamp(seconds, nanos); } /** * Creates a new timestamp from the given milliseconds. * - * @param millis the timestamp represented in milliseconds since epoch. - * @return a new timestamp from the given milliseconds. + * @param epochMilli the timestamp represented in milliseconds since epoch. + * @return new {@code Timestamp} with specified fields. For invalid inputs, a {@code Timestamp} of + * zero is returned. */ - public static Timestamp fromMillis(long millis) { - long seconds = millis / NUM_MILLIS_PER_SECOND; - int nanos = (int) (millis % NUM_MILLIS_PER_SECOND) * NUM_NANOS_PER_MILLI; - if (nanos < 0) { - return new Timestamp(seconds - 1, (int) (nanos + NUM_NANOS_PER_SECOND)); - } else { - return new Timestamp(seconds, nanos); - } + public static Timestamp fromMillis(long epochMilli) { + long secs = floorDiv(epochMilli, MILLIS_PER_SECOND); + int mos = (int) floorMod(epochMilli, MILLIS_PER_SECOND); + return create(secs, (int) (mos * NANOS_PER_MILLI)); // Safe int * NANOS_PER_MILLI } /** @@ -79,9 +77,7 @@ public static Timestamp fromMillis(long millis) { * * @return the number of seconds since the Unix Epoch. */ - public long getSeconds() { - return seconds; - } + public abstract long getSeconds(); /** * Returns the number of nanoseconds after the number of seconds since the Unix Epoch represented @@ -89,57 +85,78 @@ public long getSeconds() { * * @return the number of nanoseconds after the number of seconds since the Unix Epoch. */ - public int getNanos() { - return nanos; - } + public abstract int getNanos(); /** * Returns a {@code Timestamp} calculated as this {@code Timestamp} plus some number of * nanoseconds. * - * @param nanos the nanoseconds to be added to the current timestamp. - * @return a {@code Timestamp} calculated as this {@code Timestamp} plus some number of - * nanoseconds. + * @param nanosToAdd the nanos to add, positive or negative. + * @return the calculated {@code Timestamp}. For invalid inputs, a {@code Timestamp} of zero is + * returned. + * @throws ArithmeticException if numeric overflow occurs. */ - public Timestamp addNanos(long nanos) { - long newSeconds = seconds + nanos / NUM_NANOS_PER_SECOND; - nanos %= NUM_NANOS_PER_SECOND; - // Cannot overflow because: abs(nanos) < NUM_NANOS_PER_SECOND AND - // this.nanos < NUM_NANOS_PER_SECOND. - long newNanos = nanos + this.nanos; - newSeconds += (newNanos / NUM_NANOS_PER_SECOND); - newNanos %= NUM_NANOS_PER_SECOND; - if (newNanos >= 0) { - return Timestamp.create(newSeconds, (int) newNanos); - } else { - return Timestamp.create(newSeconds - 1, (int) (newNanos + NUM_NANOS_PER_SECOND)); - } + public Timestamp addNanos(long nanosToAdd) { + return plus(0, nanosToAdd); + } + + /** + * Returns a {@code Timestamp} calculated as this {@code Timestamp} plus some {@code Duration}. + * + * @param duration the {@code Duration} to add. + * @return a {@code Timestamp} with the specified {@code Duration} added. + */ + public Timestamp addDuration(Duration duration) { + return plus(duration.getSeconds(), duration.getNanos()); } - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; + /** + * Returns a {@link Duration} calculated as: {@code this - timestamp}. + * + * @param timestamp the {@code Timestamp} to subtract. + * @return the calculated {@code Duration}. For invalid inputs, a {@code Duration} of zero is + * returned. + */ + public Duration subtractTimestamp(Timestamp timestamp) { + long durationSeconds = getSeconds() - timestamp.getSeconds(); + int durationNanos = getNanos() - timestamp.getNanos(); + if (durationSeconds < 0 && durationNanos > 0) { + durationSeconds += 1; + durationNanos -= NANOS_PER_SECOND; + } else if (durationSeconds > 0 && durationNanos < 0) { + durationSeconds -= 1; + durationNanos += NANOS_PER_SECOND; } + return Duration.create(durationSeconds, durationNanos); + } - if (!(obj instanceof Timestamp)) { - return false; + // Returns a Timestamp with the specified duration added. + private Timestamp plus(long secondsToAdd, long nanosToAdd) { + if ((secondsToAdd | nanosToAdd) == 0) { + return this; } + long epochSec = LongMath.checkedAdd(getSeconds(), secondsToAdd); + epochSec = LongMath.checkedAdd(epochSec, nanosToAdd / NANOS_PER_SECOND); + nanosToAdd = nanosToAdd % NANOS_PER_SECOND; + long nanoAdjustment = getNanos() + nanosToAdd; // safe int + NANOS_PER_SECOND + return ofEpochSecond(epochSec, nanoAdjustment); + } - Timestamp that = (Timestamp) obj; - return seconds == that.seconds && nanos == that.nanos; + // Returns a Timestamp calculated using seconds from the epoch and nanosecond fraction of + // second (arbitrary number of nanoseconds). + private static Timestamp ofEpochSecond(long epochSecond, long nanoAdjustment) { + long secs = LongMath.checkedAdd(epochSecond, floorDiv(nanoAdjustment, NANOS_PER_SECOND)); + int nos = (int) floorMod(nanoAdjustment, NANOS_PER_SECOND); + return create(secs, nos); } - @Override - public int hashCode() { - int result = 17; - result = 31 * result + (int) (seconds ^ (seconds >>> 32)); - result = 31 * result + nanos; - return result; + // Returns the result of dividing x by y rounded using floor. + private static long floorDiv(long x, long y) { + return LongMath.divide(x, y, RoundingMode.FLOOR); } - @Override - public String toString() { - return "Timestamp<" + seconds + "," + nanos + ">"; + // Returns the floor modulus "x - (floorDiv(x, y) * y)" + private static long floorMod(long x, long y) { + return x - floorDiv(x, y) * y; } } diff --git a/api/src/test/java/io/opencensus/common/TimestampTest.java b/api/src/test/java/io/opencensus/common/TimestampTest.java index 263bc66d9a..e384b5ca70 100644 --- a/api/src/test/java/io/opencensus/common/TimestampTest.java +++ b/api/src/test/java/io/opencensus/common/TimestampTest.java @@ -80,6 +80,59 @@ public void timestampAddNanos_Negative() { assertThat(timestamp.addNanos(Long.MIN_VALUE)) .isEqualTo(Timestamp.create(1234L - 9223372036L - 1, 223 + 145224192)); } + + @Test + public void timestampAddDuration() { + Timestamp timestamp = Timestamp.create(1234, 223); + assertThat(timestamp.addDuration(Duration.create(1, 0))).isEqualTo(Timestamp.create(1235, 223)); + assertThat(timestamp.addDuration(Duration.create(0, 1))).isEqualTo(Timestamp.create(1234, 224)); + assertThat(timestamp.addDuration(Duration.create(1, 1))).isEqualTo(Timestamp.create(1235, 224)); + assertThat(timestamp.addDuration(Duration.create(1, 999999900))) + .isEqualTo(Timestamp.create(1236, 123)); + } + + @Test + public void timestampAddDuration_Negative() { + Timestamp timestamp = Timestamp.create(1234, 223); + assertThat(timestamp.addDuration(Duration.create(-1234, -223))) + .isEqualTo(Timestamp.create(0, 0)); + assertThat(timestamp.addDuration(Duration.create(-1, 0))) + .isEqualTo(Timestamp.create(1233, 223)); + assertThat(timestamp.addDuration(Duration.create(-1, -1))) + .isEqualTo(Timestamp.create(1233, 222)); + assertThat(timestamp.addDuration(Duration.create(-1, -323))) + .isEqualTo(Timestamp.create(1232, 999999900)); + assertThat(timestamp.addDuration(Duration.create(-33, -999999999))) + .isEqualTo(Timestamp.create(1200, 224)); + } + + @Test + public void timestampSubtractTimestamp() { + Timestamp timestamp = Timestamp.create(1234, 223); + assertThat(timestamp.subtractTimestamp(Timestamp.create(0, 0))) + .isEqualTo(Duration.create(1234, 223)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1233, 223))) + .isEqualTo(Duration.create(1, 0)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1233, 222))) + .isEqualTo(Duration.create(1, 1)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1232, 999999900))) + .isEqualTo(Duration.create(1, 323)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1200, 224))) + .isEqualTo(Duration.create(33, 999999999)); + } + + @Test + public void timestampSubtractTimestamp_NegativeResult() { + Timestamp timestamp = Timestamp.create(1234, 223); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1235, 223))) + .isEqualTo(Duration.create(-1, 0)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1234, 224))) + .isEqualTo(Duration.create(0, -1)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1235, 224))) + .isEqualTo(Duration.create(-1, -1)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1236, 123))) + .isEqualTo(Duration.create(-1, -999999900)); + } @Test public void testTimestampEqual() { diff --git a/testing/src/main/java/io/opencensus/testing/common/TestClock.java b/testing/src/main/java/io/opencensus/testing/common/TestClock.java index 2a604f2a1f..ef287456f7 100644 --- a/testing/src/main/java/io/opencensus/testing/common/TestClock.java +++ b/testing/src/main/java/io/opencensus/testing/common/TestClock.java @@ -66,14 +66,8 @@ public synchronized void setTime(Timestamp time) { * * @param duration the increase in time. */ - // TODO(sebright): Consider adding an 'addDuration' method to Timestamp. public synchronized void advanceTime(Duration duration) { - currentTime = - validateNanos( - Timestamp.create( - LongMath.checkedAdd(currentTime.getSeconds(), duration.getSeconds()), - currentTime.getNanos()) - .addNanos(duration.getNanos())); + currentTime = validateNanos(currentTime.addDuration(duration)); } @Override From 1d2eda65c51e2528e7c6ccb41d9f046ae307d97b Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 19 Jun 2017 23:54:11 -0700 Subject: [PATCH 0184/1581] Update main build.gradle for export to use OpenCensus. (#374) --- RELEASING.md | 6 +++--- build.gradle | 26 ++++++++++++-------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index dffbb2456c..c46725e7ed 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -78,7 +78,7 @@ token](https://help.github.com/articles/creating-a-personal-access-token-for-the ```bash $ git checkout -b bump-version master # Change version to next minor (and keep -SNAPSHOT) - $ sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_INSTRUMENTATION_VERSION\)/'$MAJOR.$((MINOR+1)).0'\1/' \ + $ sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_OPENCENSUS_VERSION\)/'$MAJOR.$((MINOR+1)).0'\1/' \ "${VERSION_FILES[@]}" $ ./gradlew build $ git commit -a -m "Start $MAJOR.$((MINOR+1)).0 development cycle" @@ -100,7 +100,7 @@ token](https://help.github.com/articles/creating-a-personal-access-token-for-the ```bash $ git checkout -b release v$MAJOR.$MINOR.x # Change version to remove -SNAPSHOT - $ sed -i 's/-SNAPSHOT\(.*CURRENT_INSTRUMENTATION_VERSION\)/\1/' "${VERSION_FILES[@]}" + $ sed -i 's/-SNAPSHOT\(.*CURRENT_OPENCENSUS_VERSION\)/\1/' "${VERSION_FILES[@]}" $ ./gradlew build $ git commit -a -m "Bump version to $MAJOR.$MINOR.$PATCH" $ git tag -a v$MAJOR.$MINOR.$PATCH -m "Version $MAJOR.$MINOR.$PATCH" @@ -111,7 +111,7 @@ token](https://help.github.com/articles/creating-a-personal-access-token-for-the ```bash # Change version to next patch and add -SNAPSHOT - $ sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_INSTRUMENTATION_VERSION\)/'$MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT'\1/' \ + $ sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_OPENCENSUS_VERSION\)/'$MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT'\1/' \ "${VERSION_FILES[@]}" $ ./gradlew build $ git commit -a -m "Bump version to $MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT" diff --git a/build.gradle b/build.gradle index 23cab392bd..b410b3a141 100644 --- a/build.gradle +++ b/build.gradle @@ -30,8 +30,8 @@ subprojects { apply plugin: "net.ltgt.errorprone" } - group = "com.google.instrumentation" - version = "0.5.0-SNAPSHOT" // CURRENT_INSTRUMENTATION_VERSION + group = "io.opencensus" + version = "0.5.0-SNAPSHOT" // CURRENT_OPENCENSUS_VERSION sourceCompatibility = 1.6 targetCompatibility = 1.6 @@ -206,18 +206,15 @@ subprojects { snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/", configureAuth) pom.project { - name "Instrumentation" + name "OpenCensus" packaging 'jar' - // Add a map with all the project.name -> artifactId when we - // are going to upload more artifacts. - artifactId jar.baseName description project.description - url 'https://github.com/google/instrumentation-java' + url 'https://github.com/census-instrumentation/instrumentation-java' scm { - connection 'scm:svn:https://github.com/google/instrumentation-java' - developerConnection 'scm:git:git@github.com/google/instrumentation-java' - url 'https://github.com/google/instrumentation-java' + connection 'scm:svn:https://github.com/census-instrumentation/instrumentation-java' + developerConnection 'scm:git:git@github.com/census-instrumentation/instrumentation-java' + url 'https://github.com/census-instrumentation/instrumentation-java' } licenses { @@ -229,9 +226,10 @@ subprojects { developers { developer { - id 'com.google.instrumentation' - name 'Instrumentation Developers' - email 'instrumentation-developers@googlegroups.com' + id 'io.opencensus' + name 'OpenCensus Contributors' + email 'opencensus-io@googlegroups.com' + url 'opencensus.io' // https://issues.gradle.org/browse/GRADLE-2719 organization = 'Google, Inc.' organizationUrl 'https://www.google.com' @@ -242,7 +240,7 @@ subprojects { } } // For the moment we upload only the artifact for the API - uploadArchives.onlyIf { name == 'core'} + uploadArchives.onlyIf { name == 'opencensus-api' || name == 'opencensus-impl-core' || name == 'opencensus-impl-lite' || name == 'opencensus-impl' || name == 'opencensus-testing'} // At a test failure, log the stack trace to the console so that we don't // have to open the HTML in a browser. From 75291d20f08159c4c426c45d7c7b4657dafc1c15 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 20 Jun 2017 11:27:04 -0700 Subject: [PATCH 0185/1581] Add initial implementation of the SampleSpanStore. (#358) --- .../java/io/opencensus/trace/base/Status.java | 9 +- .../trace/export/SampledSpanStore.java | 15 +- .../java/io/opencensus/trace/SpanImpl.java | 35 ++ .../opencensus/trace/StartEndHandlerImpl.java | 13 +- .../trace/export/ExportComponentImpl.java | 13 +- .../trace/export/SampledSpanStoreImpl.java | 288 +++++++++++++++ .../trace/export/ExportComponentImplTest.java | 4 +- .../export/SampledSpanStoreImplTest.java | 330 ++++++++++++++++++ 8 files changed, 689 insertions(+), 18 deletions(-) create mode 100644 impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java create mode 100644 impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java diff --git a/api/src/main/java/io/opencensus/trace/base/Status.java b/api/src/main/java/io/opencensus/trace/base/Status.java index 6166c17ca7..e0ab490463 100644 --- a/api/src/main/java/io/opencensus/trace/base/Status.java +++ b/api/src/main/java/io/opencensus/trace/base/Status.java @@ -15,6 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; import io.opencensus.trace.Span; @@ -164,7 +165,13 @@ public int value() { return value; } - Status toStatus() { + /** + * Returns the status that has the current {@code CanonicalCode}.. + * + * @return the status that has the current {@code CanonicalCode}. + */ + @VisibleForTesting + public Status toStatus() { return STATUS_LIST.get(value); } } diff --git a/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java b/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java index 1fae1750ed..00074a076b 100644 --- a/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java +++ b/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.ThreadSafe; @@ -314,16 +315,19 @@ public abstract static class ErrorFilter { * maximum of {@code maxSpansToReturn}. * * @param spanName the name of the span. - * @param canonicalCode the error code of the span. + * @param canonicalCode the error code of the span. {@code null} can be used to query all + * error codes. * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. * @return a new instance of {@code ErrorFilter}. - * @throws NullPointerException if {@code spanName} or {@code canonicalCode} are {@code null}. + * @throws NullPointerException if {@code spanName} is {@code null}. * @throws IllegalArgumentException if {@code canonicalCode} is {@link CanonicalCode#OK} or * {@code maxSpansToReturn} is negative. */ public static ErrorFilter create( - String spanName, CanonicalCode canonicalCode, int maxSpansToReturn) { - checkArgument(canonicalCode != CanonicalCode.OK, "Invalid canonical code."); + String spanName, @Nullable CanonicalCode canonicalCode, int maxSpansToReturn) { + if (canonicalCode != null) { + checkArgument(canonicalCode != CanonicalCode.OK, "Invalid canonical code."); + } checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); return new AutoValue_SampledSpanStore_ErrorFilter(spanName, canonicalCode, maxSpansToReturn); } @@ -337,10 +341,11 @@ public static ErrorFilter create( /** * Returns the canonical code used by this filter. Always different than {@link - * CanonicalCode#OK}. + * CanonicalCode#OK}. If {@code null} then all errors match. * * @return the canonical code used by this filter. */ + @Nullable public abstract CanonicalCode getCanonicalCode(); /** diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java index 04003c56d9..a1768f35f1 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java @@ -137,6 +137,41 @@ public String getName() { return name; } + /** + * Returns the status of the {@code Span}. If not set defaults to {@link Status#OK}. + * + * @return the status of the {@code Span}. + */ + public Status getStatus() { + synchronized (this) { + return status; + } + } + + /** + * Returns the end nano time (see {@link System#nanoTime()}). If the current {@code Span} is + * not ended then returns {@link Clock#nowNanos()}. + * + * @return the end nano time. + */ + public long getEndNanoTime() { + synchronized (this) { + return hasBeenEnded ? endNanoTime : clock.nowNanos(); + } + } + + /** + * Returns the latency of the {@code Span} in nanos. If still active then returns now() - start + * time. + * + * @return the latency of the {@code Span} in nanos. + */ + public long getLatencyNs() { + synchronized (this) { + return hasBeenEnded ? endNanoTime - startNanoTime : clock.nowNanos() - startNanoTime; + } + } + /** * Returns the {@code TimestampConverter} used by this {@code Span}. * diff --git a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java index 89b797be5c..b0f7e07a56 100644 --- a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java @@ -17,7 +17,7 @@ import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.export.RunningSpanStoreImpl; -import io.opencensus.trace.export.SampledSpanStore; +import io.opencensus.trace.export.SampledSpanStoreImpl; import io.opencensus.trace.export.SpanData; import io.opencensus.trace.export.SpanExporterImpl; import javax.annotation.Nullable; @@ -31,7 +31,7 @@ public final class StartEndHandlerImpl implements StartEndHandler { private final SpanExporterImpl spanExporter; private final RunningSpanStoreImpl runningSpanStore; - private final SampledSpanStore sampledSpanStore; + private final SampledSpanStoreImpl sampledSpanStore; private final EventQueue eventQueue; // true if any of (runningSpanStore OR sampledSpanStore) are different than null, which // means the spans with RECORD_EVENTS should be enqueued in the queue. @@ -48,7 +48,7 @@ public final class StartEndHandlerImpl implements StartEndHandler { public StartEndHandlerImpl( SpanExporterImpl spanExporter, @Nullable RunningSpanStoreImpl runningSpanStore, - @Nullable SampledSpanStore sampledSpanStore, + @Nullable SampledSpanStoreImpl sampledSpanStore, EventQueue eventQueue) { this.spanExporter = spanExporter; this.runningSpanStore = runningSpanStore; @@ -96,15 +96,17 @@ private static final class SpanEndEvent implements EventQueue.Entry { private final SpanImpl span; private final RunningSpanStoreImpl runningSpanStore; private final SpanExporterImpl spanExporter; + private final SampledSpanStoreImpl sampledSpanStore; SpanEndEvent( SpanImpl span, SpanExporterImpl spanExporter, @Nullable RunningSpanStoreImpl runningSpanStore, - @Nullable SampledSpanStore sampledSpanStore) { + @Nullable SampledSpanStoreImpl sampledSpanStore) { this.span = span; this.runningSpanStore = runningSpanStore; this.spanExporter = spanExporter; + this.sampledSpanStore = sampledSpanStore; } @Override @@ -113,6 +115,9 @@ public void process() { if (runningSpanStore != null) { runningSpanStore.onEnd(span); } + if (sampledSpanStore != null) { + sampledSpanStore.considerForSampling(span); + } } } } diff --git a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java index 8ff40df0b4..a6b809860d 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java @@ -22,7 +22,8 @@ public final class ExportComponentImpl extends ExportComponent { private static final long EXPORTER_SCHEDULE_DELAY_MS = 2000; private final SpanExporterImpl spanExporter; - private final RunningSpanStoreImpl activeSpansExporter; + private final RunningSpanStoreImpl runningSpanStore; + private final SampledSpanStoreImpl sampledSpanStore; @Override public SpanExporterImpl getSpanExporter() { @@ -32,14 +33,13 @@ public SpanExporterImpl getSpanExporter() { @Nullable @Override public RunningSpanStoreImpl getRunningSpanStore() { - return activeSpansExporter; + return runningSpanStore; } @Nullable @Override - public SampledSpanStore getSampledSpanStore() { - // TODO(bdrutu): Implement this. - return null; + public SampledSpanStoreImpl getSampledSpanStore() { + return sampledSpanStore; } /** @@ -70,6 +70,7 @@ public static ExportComponentImpl createWithoutInProcessStores() { */ private ExportComponentImpl(boolean supportInProcessStores) { this.spanExporter = SpanExporterImpl.create(EXPORTER_BUFFER_SIZE, EXPORTER_SCHEDULE_DELAY_MS); - this.activeSpansExporter = supportInProcessStores ? new RunningSpanStoreImpl() : null; + this.runningSpanStore = supportInProcessStores ? new RunningSpanStoreImpl() : null; + this.sampledSpanStore = supportInProcessStores ? new SampledSpanStoreImpl() : null; } } diff --git a/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java new file mode 100644 index 0000000000..a2a986e5bb --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java @@ -0,0 +1,288 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.export; + +import com.google.common.collect.EvictingQueue; +import io.opencensus.trace.SpanImpl; +import io.opencensus.trace.base.Status; +import io.opencensus.trace.base.Status.CanonicalCode; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.annotation.concurrent.GuardedBy; +import javax.annotation.concurrent.ThreadSafe; + +/** Implementation of the {@link SampledSpanStore}. */ +@ThreadSafe +public final class SampledSpanStoreImpl extends SampledSpanStore { + private static final int NUM_SAMPLES_PER_LATENCY_BUCKET = 10; + private static final int NUM_SAMPLES_PER_ERROR_BUCKET = 5; + private static final long TIME_BETWEEN_SAMPLES = TimeUnit.SECONDS.toNanos(1); + private static final int NUM_LATENCY_BUCKETS = LatencyBucketBoundaries.values().length; + // The total number of canonical codes - 1 (the OK code). + private static final int NUM_ERROR_BUCKETS = CanonicalCode.values().length - 1; + private static final int MAX_PER_SPAN_NAME_SAMPLES = + NUM_SAMPLES_PER_LATENCY_BUCKET * NUM_LATENCY_BUCKETS + + NUM_SAMPLES_PER_ERROR_BUCKET * NUM_ERROR_BUCKETS; + @GuardedBy("samples") + private final Map samples; + + private static final class Bucket { + + private final EvictingQueue queue; + private long lastSampleNanoTime; + + private Bucket(int numSamples) { + queue = EvictingQueue.create(numSamples); + } + + private void considerForSampling(SpanImpl span) { + long spanEndNanoTime = span.getEndNanoTime(); + // Need to compare by doing the subtraction all the time because in case of an overflow, + // this may never sample again (at least for the next ~200 years). No real chance to + // overflow two times because that means the process runs for ~200 years. + if (spanEndNanoTime - lastSampleNanoTime > TIME_BETWEEN_SAMPLES) { + queue.add(span); + lastSampleNanoTime = spanEndNanoTime; + } + } + + private void getSamples(int maxSpansToReturn, List output) { + for (SpanImpl span : queue) { + if (output.size() >= maxSpansToReturn) { + break; + } + output.add(span); + } + } + + private void getSamplesFilteredByLatency( + long latencyLowerNs, long latencyUpperNs, int maxSpansToReturn, List output) { + for (SpanImpl span : queue) { + if (output.size() >= maxSpansToReturn) { + break; + } + long spanLatencyNs = span.getLatencyNs(); + if (spanLatencyNs >= latencyLowerNs && spanLatencyNs < latencyUpperNs) { + output.add(span); + } + } + } + + private int getNumSamples() { + return queue.size(); + } + } + + /** + * Keeps samples for a given span name. Samples for all the latency buckets and for all + * canonical codes other than OK. + */ + private static final class PerSpanNameSamples { + + private final Bucket[] latencyBuckets; + private final Bucket[] errorBuckets; + + private PerSpanNameSamples() { + latencyBuckets = new Bucket[NUM_LATENCY_BUCKETS]; + for (int i = 0; i < NUM_LATENCY_BUCKETS; i++) { + latencyBuckets[i] = new Bucket(NUM_SAMPLES_PER_LATENCY_BUCKET); + } + errorBuckets = new Bucket[NUM_ERROR_BUCKETS]; + for (int i = 0; i < NUM_ERROR_BUCKETS; i++) { + errorBuckets[i] = new Bucket(NUM_SAMPLES_PER_ERROR_BUCKET); + } + } + + private Bucket getLatencyBucket(long latencyNs) { + for (int i = 0; i < NUM_LATENCY_BUCKETS; i++) { + LatencyBucketBoundaries boundaries = LatencyBucketBoundaries.values()[i]; + if (latencyNs >= boundaries.getLatencyLowerNs() + && latencyNs < boundaries.getLatencyUpperNs()) { + return latencyBuckets[i]; + } + } + // latencyNs is negative or Long.MAX_VALUE, so this Span can be ignored. This cannot happen + // in real production because System#nanoTime is monotonic. + return null; + } + + private Bucket getErrorBucket(CanonicalCode code) { + return errorBuckets[code.value() - 1]; + } + + private void considerForSampling(SpanImpl span) { + Status status = span.getStatus(); + // Null status means running Span, this should not happen in production, but the library + // should not crash because of this. + if (status != null) { + Bucket bucket = + status.isOk() + ? getLatencyBucket(span.getLatencyNs()) + : getErrorBucket(status.getCanonicalCode()); + // If unable to find the bucket, ignore this Span. + if (bucket != null) { + bucket.considerForSampling(span); + } + } + } + + private Map getNumbersOfLatencySampledSpans() { + Map latencyBucketSummaries = + new EnumMap(LatencyBucketBoundaries.class); + for (int i = 0; i < NUM_LATENCY_BUCKETS; i++) { + latencyBucketSummaries.put( + LatencyBucketBoundaries.values()[i], latencyBuckets[i].getNumSamples()); + } + return latencyBucketSummaries; + } + + private Map getNumbersOfErrorSampledSpans() { + Map errorBucketSummaries = + new EnumMap(CanonicalCode.class); + for (int i = 0; i < NUM_ERROR_BUCKETS; i++) { + errorBucketSummaries.put(CanonicalCode.values()[i + 1], errorBuckets[i].getNumSamples()); + } + return errorBucketSummaries; + } + + private List getErrorSamples(CanonicalCode code, int maxSpansToReturn) { + ArrayList output = new ArrayList(maxSpansToReturn); + if (code != null) { + getErrorBucket(code).getSamples(maxSpansToReturn, output); + } else { + for (int i = 0; i < NUM_ERROR_BUCKETS; i++) { + errorBuckets[i].getSamples(maxSpansToReturn, output); + } + } + return output; + } + + private List getLatencySamples( + long latencyLowerNs, long latencyUpperNs, int maxSpansToReturn) { + ArrayList output = new ArrayList(maxSpansToReturn); + for (int i = 0; i < NUM_LATENCY_BUCKETS; i++) { + LatencyBucketBoundaries boundaries = LatencyBucketBoundaries.values()[i]; + if (latencyUpperNs >= boundaries.getLatencyLowerNs() + && latencyLowerNs < boundaries.getLatencyUpperNs()) { + latencyBuckets[i].getSamplesFilteredByLatency( + latencyLowerNs, latencyUpperNs, maxSpansToReturn, output); + } + } + return output; + } + } + + /** Constructs a new {@code SampledSpanStoreImpl}. */ + public SampledSpanStoreImpl() { + samples = new HashMap(); + } + + @Override + public Summary getSummary() { + Map ret = new HashMap(); + synchronized (samples) { + for (Map.Entry it : samples.entrySet()) { + ret.put( + it.getKey(), + PerSpanNameSummary.create( + it.getValue().getNumbersOfLatencySampledSpans(), + it.getValue().getNumbersOfErrorSampledSpans())); + } + } + return Summary.create(ret); + } + + /** + * Considers to save the given spans to the stored samples. This must be called at the end of + * each Span with the option RECORD_EVENTS. + * + * @param span the span to be consider for storing into the store buckets. + */ + public void considerForSampling(SpanImpl span) { + synchronized (samples) { + PerSpanNameSamples perSpanNameSamples = samples.get(span.getName()); + if (perSpanNameSamples != null) { + perSpanNameSamples.considerForSampling(span); + } + } + } + + @Override + public void registerSpanNamesForCollection(Collection spanNames) { + synchronized (samples) { + for (String spanName : spanNames) { + if (!samples.containsKey(spanName)) { + samples.put(spanName, new PerSpanNameSamples()); + } + } + } + } + + @Override + public void unregisterSpanNamesForCollection(Collection spanNames) { + synchronized (samples) { + samples.keySet().removeAll(spanNames); + } + } + + @Override + public Collection getErrorSampledSpans(ErrorFilter filter) { + int numSpansToReturn = + filter.getMaxSpansToReturn() == 0 + ? MAX_PER_SPAN_NAME_SAMPLES + : filter.getMaxSpansToReturn(); + List spans = Collections.emptyList(); + // Try to not keep the lock to much, do the SpanImpl -> SpanData conversion outside the lock. + synchronized (samples) { + PerSpanNameSamples perSpanNameSamples = samples.get(filter.getSpanName()); + if (perSpanNameSamples != null) { + spans = perSpanNameSamples.getErrorSamples(filter.getCanonicalCode(), numSpansToReturn); + } + } + List ret = new ArrayList(spans.size()); + for (SpanImpl span : spans) { + ret.add(span.toSpanData()); + } + return Collections.unmodifiableList(ret); + } + + @Override + public Collection getLatencySampledSpans(LatencyFilter filter) { + int numSpansToReturn = + filter.getMaxSpansToReturn() == 0 + ? MAX_PER_SPAN_NAME_SAMPLES + : filter.getMaxSpansToReturn(); + List spans = Collections.emptyList(); + // Try to not keep the lock to much, do the SpanImpl -> SpanData conversion outside the lock. + synchronized (samples) { + PerSpanNameSamples perSpanNameSamples = samples.get(filter.getSpanName()); + if (perSpanNameSamples != null) { + spans = + perSpanNameSamples.getLatencySamples( + filter.getLatencyLowerNs(), filter.getLatencyUpperNs(), numSpansToReturn); + } + } + List ret = new ArrayList(spans.size()); + for (SpanImpl span : spans) { + ret.add(span.toSpanData()); + } + return Collections.unmodifiableList(ret); + } +} diff --git a/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java index 73425ca36f..2cfa52eeb7 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java @@ -41,8 +41,8 @@ public void implementationOfActiveSpans() { @Test public void implementationOfSampledSpanStore() { - // TODO(bdrutu): Change this when implementation is available. - assertThat(exportComponentWithInProcess.getSampledSpanStore()).isNull(); + assertThat(exportComponentWithInProcess.getSampledSpanStore()) + .isInstanceOf(SampledSpanStoreImpl.class); assertThat(exportComponentWithoutInProcess.getSampledSpanStore()).isNull(); } } diff --git a/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java new file mode 100644 index 0000000000..829ca955b9 --- /dev/null +++ b/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java @@ -0,0 +1,330 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.export; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.common.Duration; +import io.opencensus.common.Timestamp; +import io.opencensus.testing.common.TestClock; +import io.opencensus.trace.Span; +import io.opencensus.trace.Span.Options; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanImpl; +import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.base.EndSpanOptions; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.Status; +import io.opencensus.trace.base.Status.CanonicalCode; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.export.SampledSpanStore.ErrorFilter; +import io.opencensus.trace.export.SampledSpanStore.LatencyBucketBoundaries; +import io.opencensus.trace.export.SampledSpanStore.LatencyFilter; +import io.opencensus.trace.export.SampledSpanStore.PerSpanNameSummary; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link SampledSpanStoreImpl}. */ +@RunWith(JUnit4.class) +public class SampledSpanStoreImplTest { + private static final String REGISTERED_SPAN_NAME = "MySpanName/1"; + private static final String NOT_REGISTERED_SPAN_NAME = "MySpanName/2"; + private static final long NUM_NANOS_PER_SECOND = TimeUnit.SECONDS.toNanos(1); + private final Random random = new Random(1234); + private final SpanContext sampledSpanContext = + SpanContext.create( + TraceId.generateRandomId(random), + SpanId.generateRandomId(random), + TraceOptions.builder().setIsSampled().build()); + private final SpanId parentSpanId = SpanId.generateRandomId(random); + private final EnumSet recordSpanOptions = EnumSet.of(Options.RECORD_EVENTS); + private final TestClock testClock = TestClock.create(Timestamp.create(12345, 54321)); + private final SampledSpanStoreImpl sampleStore = new SampledSpanStoreImpl(); + private final StartEndHandler startEndHandler = + new StartEndHandler() { + @Override + public void onStart(SpanImpl span) { + // Do nothing. + } + + @Override + public void onEnd(SpanImpl span) { + sampleStore.considerForSampling(span); + } + }; + + @Before + public void setUp() { + sampleStore.registerSpanNamesForCollection(Arrays.asList(REGISTERED_SPAN_NAME)); + } + + SpanImpl createSpan(String spanName) { + SpanImpl span = + SpanImpl.startSpan( + sampledSpanContext, + recordSpanOptions, + spanName, + parentSpanId, + false, + TraceParams.DEFAULT, + startEndHandler, + null, + testClock); + return span; + } + + private void addSpanNameToAllLatencyBuckets(String spanName) { + for (LatencyBucketBoundaries boundaries : LatencyBucketBoundaries.values()) { + Span span = createSpan(spanName); + if (boundaries.getLatencyLowerNs() < NUM_NANOS_PER_SECOND) { + testClock.advanceTime(Duration.create(0, (int) boundaries.getLatencyLowerNs())); + } else { + testClock.advanceTime( + Duration.create( + boundaries.getLatencyLowerNs() / NUM_NANOS_PER_SECOND, + (int) (boundaries.getLatencyLowerNs() % NUM_NANOS_PER_SECOND))); + } + span.end(); + } + } + + private void addSpanNameToAllErrorBuckets(String spanName) { + for (CanonicalCode code : CanonicalCode.values()) { + if (code != CanonicalCode.OK) { + Span span = createSpan(spanName); + testClock.advanceTime(Duration.create(0, 1000)); + span.end(EndSpanOptions.builder().setStatus(code.toStatus()).build()); + } + } + } + + @Test + public void addSpansWithRegisteredNamesInAllLatencyBuckets() { + addSpanNameToAllLatencyBuckets(REGISTERED_SPAN_NAME); + Map perSpanNameSummary = + sampleStore.getSummary().getPerSpanNameSummary(); + assertThat(perSpanNameSummary.size()).isEqualTo(1); + Map latencyBucketsSummaries = + perSpanNameSummary.get(REGISTERED_SPAN_NAME).getNumberOfLatencySampledSpans(); + assertThat(latencyBucketsSummaries.size()).isEqualTo(LatencyBucketBoundaries.values().length); + for (Map.Entry it : latencyBucketsSummaries.entrySet()) { + assertThat(it.getValue()).isEqualTo(1); + } + } + + @Test + public void addSpansWithoutRegisteredNamesInAllLatencyBuckets() { + addSpanNameToAllLatencyBuckets(NOT_REGISTERED_SPAN_NAME); + Map perSpanNameSummary = + sampleStore.getSummary().getPerSpanNameSummary(); + assertThat(perSpanNameSummary.size()).isEqualTo(1); + assertThat(perSpanNameSummary.containsKey(NOT_REGISTERED_SPAN_NAME)).isFalse(); + } + + @Test + public void registerAndUnregisterSpanNames() { + addSpanNameToAllLatencyBuckets(NOT_REGISTERED_SPAN_NAME); + assertThat( + sampleStore.getSummary().getPerSpanNameSummary().containsKey(NOT_REGISTERED_SPAN_NAME)) + .isFalse(); + sampleStore.registerSpanNamesForCollection(Arrays.asList(NOT_REGISTERED_SPAN_NAME)); + addSpanNameToAllLatencyBuckets(NOT_REGISTERED_SPAN_NAME); + assertThat( + sampleStore.getSummary().getPerSpanNameSummary().containsKey(NOT_REGISTERED_SPAN_NAME)) + .isTrue(); + sampleStore.unregisterSpanNamesForCollection(Arrays.asList(NOT_REGISTERED_SPAN_NAME)); + assertThat( + sampleStore.getSummary().getPerSpanNameSummary().containsKey(NOT_REGISTERED_SPAN_NAME)) + .isFalse(); + } + + @Test + public void addSpansWithRegisteredNamesInAllErrorBuckets() { + addSpanNameToAllErrorBuckets(REGISTERED_SPAN_NAME); + Map perSpanNameSummary = + sampleStore.getSummary().getPerSpanNameSummary(); + assertThat(perSpanNameSummary.size()).isEqualTo(1); + Map errorBucketsSummaries = + perSpanNameSummary.get(REGISTERED_SPAN_NAME).getNumberOfErrorSampledSpans(); + assertThat(errorBucketsSummaries.size()).isEqualTo(CanonicalCode.values().length - 1); + for (Map.Entry it : errorBucketsSummaries.entrySet()) { + assertThat(it.getValue()).isEqualTo(1); + } + } + + @Test + public void addSpansWithoutRegisteredNamesInAllErrorBuckets() { + addSpanNameToAllErrorBuckets(NOT_REGISTERED_SPAN_NAME); + Map perSpanNameSummary = + sampleStore.getSummary().getPerSpanNameSummary(); + assertThat(perSpanNameSummary.size()).isEqualTo(1); + assertThat(perSpanNameSummary.containsKey(NOT_REGISTERED_SPAN_NAME)).isFalse(); + } + + @Test + public void getErrorSampledSpans() { + SpanImpl span = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, 1000)); + span.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build()); + Collection samples = + sampleStore.getErrorSampledSpans( + ErrorFilter.create(REGISTERED_SPAN_NAME, CanonicalCode.CANCELLED, 0)); + assertThat(samples.size()).isEqualTo(1); + assertThat(samples.contains(span.toSpanData())).isTrue(); + } + + @Test + public void getErrorSampledSpans_MaxSpansToReturn() { + SpanImpl span1 = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, 1000)); + span1.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build()); + // Advance time to allow other spans to be sampled. + testClock.advanceTime(Duration.create(5, 0)); + SpanImpl span2 = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, 1000)); + span2.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build()); + Collection samples = + sampleStore.getErrorSampledSpans( + ErrorFilter.create(REGISTERED_SPAN_NAME, CanonicalCode.CANCELLED, 1)); + assertThat(samples.size()).isEqualTo(1); + // No order guaranteed so one of the spans should be in the list. + assertThat(samples).containsAnyOf(span1.toSpanData(), span2.toSpanData()); + } + + @Test + public void getErrorSampledSpans_NullCode() { + SpanImpl span1 = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, 1000)); + span1.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build()); + SpanImpl span2 = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, 1000)); + span2.end(EndSpanOptions.builder().setStatus(Status.UNKNOWN).build()); + Collection samples = + sampleStore.getErrorSampledSpans(ErrorFilter.create(REGISTERED_SPAN_NAME, null, 0)); + assertThat(samples.size()).isEqualTo(2); + assertThat(samples).containsExactly(span1.toSpanData(), span2.toSpanData()); + } + + @Test + public void getErrorSampledSpans_NullCode_MaxSpansToReturn() { + SpanImpl span1 = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, 1000)); + span1.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build()); + SpanImpl span2 = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, 1000)); + span2.end(EndSpanOptions.builder().setStatus(Status.UNKNOWN).build()); + Collection samples = + sampleStore.getErrorSampledSpans(ErrorFilter.create(REGISTERED_SPAN_NAME, null, 1)); + assertThat(samples.size()).isEqualTo(1); + assertThat(samples).containsAnyOf(span1.toSpanData(), span2.toSpanData()); + } + + @Test + public void getLatencySampledSpans() { + SpanImpl span = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(20))); + span.end(); + Collection samples = + sampleStore.getLatencySampledSpans( + LatencyFilter.create( + REGISTERED_SPAN_NAME, + TimeUnit.MICROSECONDS.toNanos(15), + TimeUnit.MICROSECONDS.toNanos(25), + 0)); + assertThat(samples.size()).isEqualTo(1); + assertThat(samples.contains(span.toSpanData())).isTrue(); + } + + @Test + public void getLatencySampledSpans_ExclusiveUpperBound() { + SpanImpl span = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(20))); + span.end(); + Collection samples = + sampleStore.getLatencySampledSpans( + LatencyFilter.create( + REGISTERED_SPAN_NAME, + TimeUnit.MICROSECONDS.toNanos(15), + TimeUnit.MICROSECONDS.toNanos(20), + 0)); + assertThat(samples.size()).isEqualTo(0); + } + + @Test + public void getLatencySampledSpans_InclusiveLowerBound() { + SpanImpl span = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(20))); + span.end(); + Collection samples = + sampleStore.getLatencySampledSpans( + LatencyFilter.create( + REGISTERED_SPAN_NAME, + TimeUnit.MICROSECONDS.toNanos(20), + TimeUnit.MICROSECONDS.toNanos(25), + 0)); + assertThat(samples.size()).isEqualTo(1); + assertThat(samples.contains(span.toSpanData())).isTrue(); + } + + @Test + public void getLatencySampledSpans_QueryBetweenMultipleBuckets() { + SpanImpl span1 = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(20))); + span1.end(); + // Advance time to allow other spans to be sampled. + testClock.advanceTime(Duration.create(5, 0)); + SpanImpl span2 = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(200))); + span2.end(); + Collection samples = + sampleStore.getLatencySampledSpans( + LatencyFilter.create( + REGISTERED_SPAN_NAME, + TimeUnit.MICROSECONDS.toNanos(15), + TimeUnit.MICROSECONDS.toNanos(250), + 0)); + assertThat(samples).containsExactly(span1.toSpanData(), span2.toSpanData()); + } + + @Test + public void getLatencySampledSpans_MaxSpansToReturn() { + SpanImpl span1 = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(20))); + span1.end(); + // Advance time to allow other spans to be sampled. + testClock.advanceTime(Duration.create(5, 0)); + SpanImpl span2 = createSpan(REGISTERED_SPAN_NAME); + testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(200))); + span2.end(); + Collection samples = + sampleStore.getLatencySampledSpans( + LatencyFilter.create( + REGISTERED_SPAN_NAME, + TimeUnit.MICROSECONDS.toNanos(15), + TimeUnit.MICROSECONDS.toNanos(250), + 1)); + assertThat(samples.size()).isEqualTo(1); + assertThat(samples.contains(span1.toSpanData())).isTrue(); + } +} From 57bec530f351009a796b579ea69898b890a2fc49 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 20 Jun 2017 19:18:06 -0700 Subject: [PATCH 0186/1581] Change getNumberOf -> getNumbersOf in SampledSpanStore. (#378) --- .../trace/export/SampledSpanStore.java | 24 +++++++++---------- .../export/SampledSpanStoreImplTest.java | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java b/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java index 00074a076b..0a47f4dd1c 100644 --- a/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java +++ b/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java @@ -138,22 +138,22 @@ public abstract static class PerSpanNameSummary { /** * Returns a new instance of {@code PerSpanNameSummary}. * - * @param numberOfLatencySampledSpans the summary for the latency buckets. - * @param numberOfErrorSampledSpans the summary for the error buckets. + * @param numbersOfLatencySampledSpans the summary for the latency buckets. + * @param numbersOfErrorSampledSpans the summary for the error buckets. * @return a new instance of {@code PerSpanNameSummary}. - * @throws NullPointerException if {@code numberOfLatencySampledSpans} or {@code - * numberOfErrorSampledSpans} are {@code null}. + * @throws NullPointerException if {@code numbersOfLatencySampledSpans} or {@code + * numbersOfErrorSampledSpans} are {@code null}. */ public static PerSpanNameSummary create( - Map numberOfLatencySampledSpans, - Map numberOfErrorSampledSpans) { + Map numbersOfLatencySampledSpans, + Map numbersOfErrorSampledSpans) { return new AutoValue_SampledSpanStore_PerSpanNameSummary( Collections.unmodifiableMap( new HashMap( - checkNotNull(numberOfLatencySampledSpans, "numberOfLatencySampledSpans"))), + checkNotNull(numbersOfLatencySampledSpans, "numbersOfLatencySampledSpans"))), Collections.unmodifiableMap( new HashMap( - checkNotNull(numberOfErrorSampledSpans, "numberOfErrorSampledSpans")))); + checkNotNull(numbersOfErrorSampledSpans, "numbersOfErrorSampledSpans")))); } /** @@ -164,7 +164,7 @@ public static PerSpanNameSummary create( * * @return the number of sampled spans in all the latency buckets. */ - public abstract Map getNumberOfLatencySampledSpans(); + public abstract Map getNumbersOfLatencySampledSpans(); /** * Returns the number of sampled spans in all the error buckets. @@ -174,7 +174,7 @@ public static PerSpanNameSummary create( * * @return the number of sampled spans in all the error buckets. */ - public abstract Map getNumberOfErrorSampledSpans(); + public abstract Map getNumbersOfErrorSampledSpans(); } /** @@ -315,8 +315,8 @@ public abstract static class ErrorFilter { * maximum of {@code maxSpansToReturn}. * * @param spanName the name of the span. - * @param canonicalCode the error code of the span. {@code null} can be used to query all - * error codes. + * @param canonicalCode the error code of the span. {@code null} can be used to query all error + * codes. * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. * @return a new instance of {@code ErrorFilter}. * @throws NullPointerException if {@code spanName} is {@code null}. diff --git a/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java index 829ca955b9..3679f56052 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java @@ -126,7 +126,7 @@ public void addSpansWithRegisteredNamesInAllLatencyBuckets() { sampleStore.getSummary().getPerSpanNameSummary(); assertThat(perSpanNameSummary.size()).isEqualTo(1); Map latencyBucketsSummaries = - perSpanNameSummary.get(REGISTERED_SPAN_NAME).getNumberOfLatencySampledSpans(); + perSpanNameSummary.get(REGISTERED_SPAN_NAME).getNumbersOfLatencySampledSpans(); assertThat(latencyBucketsSummaries.size()).isEqualTo(LatencyBucketBoundaries.values().length); for (Map.Entry it : latencyBucketsSummaries.entrySet()) { assertThat(it.getValue()).isEqualTo(1); @@ -166,7 +166,7 @@ public void addSpansWithRegisteredNamesInAllErrorBuckets() { sampleStore.getSummary().getPerSpanNameSummary(); assertThat(perSpanNameSummary.size()).isEqualTo(1); Map errorBucketsSummaries = - perSpanNameSummary.get(REGISTERED_SPAN_NAME).getNumberOfErrorSampledSpans(); + perSpanNameSummary.get(REGISTERED_SPAN_NAME).getNumbersOfErrorSampledSpans(); assertThat(errorBucketsSummaries.size()).isEqualTo(CanonicalCode.values().length - 1); for (Map.Entry it : errorBucketsSummaries.entrySet()) { assertThat(it.getValue()).isEqualTo(1); From 57433d7cbd984ba1fa94f6a8bb343a1882768d11 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 21 Jun 2017 17:06:52 -0700 Subject: [PATCH 0187/1581] Change grpc version to 1.4.0. (#381) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b410b3a141..867ded5cb5 100644 --- a/build.gradle +++ b/build.gradle @@ -100,7 +100,7 @@ subprojects { ext { autoValueVersion = '1.4' guavaVersion = '19.0' - grpcContextVersion = '1.3.0' + grpcContextVersion = '1.4.0' libraries = [ auto_value : "com.google.auto.value:auto-value:${autoValueVersion}", From 95c9b20f07622a140368a9dd8d61ff2d41d4534a Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 21 Jun 2017 23:56:49 -0700 Subject: [PATCH 0188/1581] Update repo release details and status badges. (#384) --- README.md | 2 +- build.gradle | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 965c98fe43..a49cd7d400 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ OpenCensus - A stats collection and distributed tracing framework ================================================================= -[![Build Status](https://travis-ci.org/census-instrumentation/instrumentation-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/instrumentation-java) [![Build status](https://ci.appveyor.com/api/projects/status/v5dbthkucuewsu33/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/instrumentation-java/branch/master) +[![Build Status](https://travis-ci.org/census-instrumentation/opencensus-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/opencensus-java) [![Build status](https://ci.appveyor.com/api/projects/status/hxthmpkxar4jq4be/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/opencensus-java/branch/master) OpenCensus provides a framework to define and collect stats against metrics and to break those stats down across user-defined dimensions. The library is in alpha diff --git a/build.gradle b/build.gradle index 867ded5cb5..319a3bf36f 100644 --- a/build.gradle +++ b/build.gradle @@ -209,12 +209,12 @@ subprojects { name "OpenCensus" packaging 'jar' description project.description - url 'https://github.com/census-instrumentation/instrumentation-java' + url 'https://github.com/census-instrumentation/opencensus-java' scm { - connection 'scm:svn:https://github.com/census-instrumentation/instrumentation-java' - developerConnection 'scm:git:git@github.com/census-instrumentation/instrumentation-java' - url 'https://github.com/census-instrumentation/instrumentation-java' + connection 'scm:svn:https://github.com/census-instrumentation/opencensus-java' + developerConnection 'scm:git:git@github.com/census-instrumentation/opencensus-java' + url 'https://github.com/census-instrumentation/opencensus-java' } licenses { From 831b9ce3122268c4f689700b851f1b6d73bcacfe Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 22 Jun 2017 00:24:00 -0700 Subject: [PATCH 0189/1581] Fix Tracing method name to get ExportComponent (#382) --- api/src/main/java/io/opencensus/trace/Tracing.java | 2 +- api/src/test/java/io/opencensus/trace/TracingTest.java | 2 +- .../io/opencensus/examples/trace/MultiSpansContextTracing.java | 2 +- .../io/opencensus/examples/trace/MultiSpansScopedTracing.java | 2 +- .../java/io/opencensus/examples/trace/MultiSpansTracing.java | 2 +- impl/src/test/java/io/opencensus/trace/TracingTest.java | 2 +- .../java/io/opencensus/trace/TraceComponentImplLiteTest.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/Tracing.java b/api/src/main/java/io/opencensus/trace/Tracing.java index 5255450a87..869fae4848 100644 --- a/api/src/main/java/io/opencensus/trace/Tracing.java +++ b/api/src/main/java/io/opencensus/trace/Tracing.java @@ -60,7 +60,7 @@ public static Clock getClock() { * * @return the global {@code ExportComponent}. */ - public static ExportComponent getTraceExporter() { + public static ExportComponent getExportComponent() { return traceComponent.getExportComponent(); } diff --git a/api/src/test/java/io/opencensus/trace/TracingTest.java b/api/src/test/java/io/opencensus/trace/TracingTest.java index be11ff5fa3..10891f2f2b 100644 --- a/api/src/test/java/io/opencensus/trace/TracingTest.java +++ b/api/src/test/java/io/opencensus/trace/TracingTest.java @@ -69,7 +69,7 @@ public void defaultBinaryPropagationHandler() { @Test public void defaultTraceExporter() { - assertThat(Tracing.getTraceExporter()).isSameAs(ExportComponent.getNoopExportComponent()); + assertThat(Tracing.getExportComponent()).isSameAs(ExportComponent.getNoopExportComponent()); } @Test diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java index c98f3fa7ce..aa23f3f70d 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java @@ -48,7 +48,7 @@ private static void doWork() { /** Main method. */ public static void main(String[] args) { - LoggingHandler.register(Tracing.getTraceExporter().getSpanExporter()); + LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); Span span = tracer.spanBuilder("MyRootSpan").becomeRoot().startSpan(); try (NonThrowingCloseable ws = tracer.withSpan(span)) { doWork(); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java index ef57bf57da..10f2d2ca4e 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java @@ -46,7 +46,7 @@ private static void doWork() { /** Main method. */ public static void main(String[] args) { - LoggingHandler.register(Tracing.getTraceExporter().getSpanExporter()); + LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); try (NonThrowingCloseable ss = tracer.spanBuilder("MyRootSpan").becomeRoot().startScopedSpan()) { doWork(); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java index 785a213570..6b8f3ed60b 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java @@ -35,7 +35,7 @@ private static void doWork() { /** Main method. */ public static void main(String[] args) { - LoggingHandler.register(Tracing.getTraceExporter().getSpanExporter()); + LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); doWork(); } } diff --git a/impl/src/test/java/io/opencensus/trace/TracingTest.java b/impl/src/test/java/io/opencensus/trace/TracingTest.java index 5f5fbeee26..205fd68cb3 100644 --- a/impl/src/test/java/io/opencensus/trace/TracingTest.java +++ b/impl/src/test/java/io/opencensus/trace/TracingTest.java @@ -43,6 +43,6 @@ public void implementationOfClock() { @Test public void implementationOfTraceExporter() { - assertThat(Tracing.getTraceExporter()).isInstanceOf(ExportComponentImpl.class); + assertThat(Tracing.getExportComponent()).isInstanceOf(ExportComponentImpl.class); } } diff --git a/impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplLiteTest.java b/impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplLiteTest.java index 65afe66bd2..f06c3d4088 100644 --- a/impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplLiteTest.java +++ b/impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplLiteTest.java @@ -43,6 +43,6 @@ public void implementationOfClock() { @Test public void implementationOfTraceExporter() { - assertThat(Tracing.getTraceExporter()).isInstanceOf(ExportComponentImpl.class); + assertThat(Tracing.getExportComponent()).isInstanceOf(ExportComponentImpl.class); } } From 52f8ecc1ee6f5e755fe0eed5648a5e570eefb681 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 22 Jun 2017 00:35:58 -0700 Subject: [PATCH 0190/1581] Change examples to use runtime dependency on implementations. (#383) --- examples/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/build.gradle b/examples/build.gradle index f471b11c4c..0ff5102b71 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -7,9 +7,9 @@ tasks.withType(JavaCompile) { dependencies { compile project(':core'), - project(':core_impl'), - project(':core_impl_java'), - project(':opencensus-api'), + project(':opencensus-api') + + runtime project(':core_impl_java'), project(':opencensus-impl') } From 924338a8bb42adfb42b25613587d1402aaeb29b8 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 23 Jun 2017 17:35:16 +0200 Subject: [PATCH 0191/1581] Relocate third party packages to avoid any conflicts of the agent's classes with the app's classes, which are loaded by the same classloader (the system classloader). --- contrib/agent/build.gradle | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 4bc6065b6e..b267ef133b 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -9,6 +9,7 @@ targetCompatibility = 1.7 def agentPackage = 'io.opencensus.contrib.agent' def agentMainClass = "${agentPackage}.AgentMain" +def agentRepackaged = "${agentPackage}.deps" dependencies { compile group: 'net.bytebuddy', name: 'byte-buddy', version: '1.7.1' @@ -31,10 +32,31 @@ shadowJar { baseName = 'opencensus-agent' classifier = null - // TODO(stschmidt): Relocate third party packages to avoid any conflicts of the agent's classes - // with the app's classes, which are loaded by the same classloader (the system classloader). + // Include only the following dependencies (excluding transitive dependencies). + dependencies { + include(dependency('net.bytebuddy:byte-buddy')) + } - // TODO(stschmidt): Assert that there's nothing unexpected left outside of ${agentPackage}. + // Exclude cruft which still snuck in. + exclude 'META-INF/maven/**' + + // Relocate third party packages to avoid any conflicts of the agent's classes with the app's + // classes, which are loaded by the same classloader (the system classloader). + relocate 'net.bytebuddy', agentRepackaged + '.bytebuddy' + + doLast { + // Assert that there's nothing unexpected left outside of ${agentPackage}. + def agentPackageDir = agentPackage.replace('.', '/') + '/' + + new java.util.zip.ZipFile(shadowJar.archivePath).withCloseable { + it.entries().each { + assert it.name.startsWith(agentPackageDir) || + (it.isDirectory() && agentPackageDir.startsWith(it.name)) || + it.name == 'META-INF/' || + it.name == 'META-INF/MANIFEST.MF' + } + } + } } jar.finalizedBy shadowJar From 613a885de54c8bccf0e2b16f1fe06a9940ce7562 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 23 Jun 2017 17:44:27 +0200 Subject: [PATCH 0192/1581] Fix the Source/Target-Compatibility manifest entry. --- contrib/agent/build.gradle | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 4bc6065b6e..52007c7f72 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -17,11 +17,15 @@ dependencies { } jar { - // Set required manifest attributes, cf. - // https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html. manifest { + // Set the required manifest attributes for the Java agent, cf. + // https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html. attributes 'Premain-Class': agentMainClass attributes 'Can-Retransform-Classes': true + + // Let the java plugin use the overridden values instead of the root project's values. + attributes 'Source-Compatibility': sourceCompatibility + attributes 'Target-Compatibility': targetCompatibility } } From d305a32421e24bee18358bc8bb5ad503706e33a2 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 23 Jun 2017 10:22:53 -0700 Subject: [PATCH 0193/1581] Replace StatsManager with StatsComponent class. (Fixes #376) StatsComponent is the class that is instantiated with reflection, to determine which stats library implementation to use. It contains a ViewManager, StatsRecorder, and StatsContextFactory. (The StatsContextFactory will be removed when we replace StatsContext with TagContext.) Breaking up the stats library functionality into multiple classes allows client code to pass around only the parts that it needs. Then when users mock the stats library, they only need to mock the parts that their code uses. For example, a user can write unit tests for code that should record specific stats by mocking StatsRecorder and asserting that StatsRecorder.record was called with the correct arguments. This change also makes the stats package more consistent with the trace package, which has a TraceComponent that holds all other objects that provide tracing functionality. --- .../main/java/io/opencensus/stats/Stats.java | 38 +++--- .../io/opencensus/stats/StatsComponent.java | 31 +++++ .../io/opencensus/stats/StatsRecorder.java | 25 ++++ .../{StatsManager.java => ViewManager.java} | 9 +- .../java/io/opencensus/stats/StatsTest.java | 7 +- .../stats/StatsComponentImplBase.java | 47 +++++++ .../stats/StatsContextFactoryImpl.java | 10 +- .../io/opencensus/stats/StatsContextImpl.java | 18 +-- .../{ViewManager.java => StatsManager.java} | 8 +- .../stats/StatsManagerImplBase.java | 71 ---------- .../opencensus/stats/StatsRecorderImpl.java | 29 +++++ .../io/opencensus/stats/StatsSerializer.java | 4 +- .../io/opencensus/stats/ViewManagerImpl.java | 39 ++++++ .../stats/StatsContextFactoryTest.java | 11 +- .../io/opencensus/stats/StatsContextTest.java | 19 ++- ...ImplTest.java => ViewManagerImplTest.java} | 122 +++++++++--------- ...lLite.java => StatsComponentImplLite.java} | 6 +- .../java/io/opencensus/stats/StatsTest.java | 13 +- ...nagerImpl.java => StatsComponentImpl.java} | 6 +- .../java/io/opencensus/stats/StatsTest.java | 12 +- 20 files changed, 321 insertions(+), 204 deletions(-) create mode 100644 core/src/main/java/io/opencensus/stats/StatsComponent.java create mode 100644 core/src/main/java/io/opencensus/stats/StatsRecorder.java rename core/src/main/java/io/opencensus/stats/{StatsManager.java => ViewManager.java} (80%) create mode 100644 core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java rename core_impl/src/main/java/io/opencensus/stats/{ViewManager.java => StatsManager.java} (92%) delete mode 100644 core_impl/src/main/java/io/opencensus/stats/StatsManagerImplBase.java create mode 100644 core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java create mode 100644 core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java rename core_impl/src/test/java/io/opencensus/stats/{StatsManagerImplTest.java => ViewManagerImplTest.java} (84%) rename core_impl_android/src/main/java/io/opencensus/stats/{StatsManagerImplLite.java => StatsComponentImplLite.java} (82%) rename core_impl_java/src/main/java/io/opencensus/stats/{StatsManagerImpl.java => StatsComponentImpl.java} (83%) diff --git a/core/src/main/java/io/opencensus/stats/Stats.java b/core/src/main/java/io/opencensus/stats/Stats.java index 05e44d9a15..0b52bdf0e0 100644 --- a/core/src/main/java/io/opencensus/stats/Stats.java +++ b/core/src/main/java/io/opencensus/stats/Stats.java @@ -19,51 +19,57 @@ import java.util.logging.Logger; import javax.annotation.Nullable; -/** {@link Stats}. */ +/** Class for accessing the default {@link StatsComponent}. */ public final class Stats { private static final Logger logger = Logger.getLogger(Stats.class.getName()); - private static final StatsManager statsManager = - loadStatsManager(Provider.getCorrectClassLoader(StatsManager.class)); + private static final StatsComponent statsComponent = + loadStatsComponent(Provider.getCorrectClassLoader(StatsComponent.class)); /** Returns the default {@link StatsContextFactory}. */ @Nullable public static StatsContextFactory getStatsContextFactory() { - return statsManager == null ? null : statsManager.getStatsContextFactory(); + return statsComponent == null ? null : statsComponent.getStatsContextFactory(); } - /** Returns the default {@link StatsManager}. */ + /** Returns the default {@link StatsRecorder}. */ @Nullable - public static StatsManager getStatsManager() { - return statsManager; + public static StatsRecorder getStatsRecorder() { + return statsComponent == null ? null : statsComponent.getStatsRecorder(); } - // Any provider that may be used for StatsManager can be added here. + /** Returns the default {@link ViewManager}. */ + @Nullable + public static ViewManager getViewManager() { + return statsComponent == null ? null : statsComponent.getViewManager(); + } + + // Any provider that may be used for StatsComponent can be added here. @VisibleForTesting @Nullable - static StatsManager loadStatsManager(ClassLoader classLoader) { + static StatsComponent loadStatsComponent(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. return Provider.createInstance( - Class.forName("io.opencensus.stats.StatsManagerImpl", true, classLoader), - StatsManager.class); + Class.forName("io.opencensus.stats.StatsComponentImpl", true, classLoader), + StatsComponent.class); } catch (ClassNotFoundException e) { logger.log( Level.FINE, - "Couldn't load full implementation for StatsManager, now trying to load lite " + "Couldn't load full implementation for StatsComponent, now trying to load lite " + "implementation.", e); } try { // Call Class.forName with literal string name of the class to help shading tools. return Provider.createInstance( - Class.forName("io.opencensus.stats.StatsManagerImplLite", true, classLoader), - StatsManager.class); + Class.forName("io.opencensus.stats.StatsComponentImplLite", true, classLoader), + StatsComponent.class); } catch (ClassNotFoundException e) { logger.log( Level.FINE, - "Couldn't load lite implementation for StatsManager, now using " - + "default implementation for StatsManager.", + "Couldn't load lite implementation for StatsComponent, now using " + + "default implementation for StatsComponent.", e); } // TODO: Add a no-op implementation. diff --git a/core/src/main/java/io/opencensus/stats/StatsComponent.java b/core/src/main/java/io/opencensus/stats/StatsComponent.java new file mode 100644 index 0000000000..08cbd44f65 --- /dev/null +++ b/core/src/main/java/io/opencensus/stats/StatsComponent.java @@ -0,0 +1,31 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +/** + * Class that holds the implementations for {@link ViewManager}, {@link StatsRecorder}, and {@link + * StatsContextFactory}. + * + *

            All objects returned by methods on {@code StatsComponent} are cacheable. + */ +public abstract class StatsComponent { + /** Returns the default {@link ViewManager}. */ + public abstract ViewManager getViewManager(); + + /** Returns the default {@link StatsRecorder}. */ + public abstract StatsRecorder getStatsRecorder(); + + /** Returns the default {@link StatsContextFactory}. */ + abstract StatsContextFactory getStatsContextFactory(); +} diff --git a/core/src/main/java/io/opencensus/stats/StatsRecorder.java b/core/src/main/java/io/opencensus/stats/StatsRecorder.java new file mode 100644 index 0000000000..aad28f02f1 --- /dev/null +++ b/core/src/main/java/io/opencensus/stats/StatsRecorder.java @@ -0,0 +1,25 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +/** Provides methods to record stats against tags. */ +public abstract class StatsRecorder { + /** + * Records a set of measurements with a set of tags. + * + * @param tags the tags associated with the measurements. + * @param measurementValues the measurements to record. + */ + abstract void record(StatsContext tags, MeasurementMap measurementValues); +} diff --git a/core/src/main/java/io/opencensus/stats/StatsManager.java b/core/src/main/java/io/opencensus/stats/ViewManager.java similarity index 80% rename from core/src/main/java/io/opencensus/stats/StatsManager.java rename to core/src/main/java/io/opencensus/stats/ViewManager.java index bfdbee644b..78400ee5f8 100644 --- a/core/src/main/java/io/opencensus/stats/StatsManager.java +++ b/core/src/main/java/io/opencensus/stats/ViewManager.java @@ -14,10 +14,10 @@ package io.opencensus.stats; /** - * Provides facillities to register {@link ViewDescriptor}s for collecting stats and retrieving + * Provides facilities to register {@link ViewDescriptor}s for collecting stats and retrieving * stats data as a {@link View}. */ -public abstract class StatsManager { +public abstract class ViewManager { /** * Pull model for stats. Registers a {@link ViewDescriptor} that will collect data to be accessed * via {@link #getView(ViewDescriptor)}. @@ -28,9 +28,4 @@ public abstract class StatsManager { * Returns the current stats data, {@link View}, associated with the given {@link ViewDescriptor}. */ public abstract View getView(ViewDescriptor viewDescriptor); - - /** - * Returns the default {@link StatsContextFactory}. - */ - abstract StatsContextFactory getStatsContextFactory(); } diff --git a/core/src/test/java/io/opencensus/stats/StatsTest.java b/core/src/test/java/io/opencensus/stats/StatsTest.java index 2dcd680edf..278f0ce35a 100644 --- a/core/src/test/java/io/opencensus/stats/StatsTest.java +++ b/core/src/test/java/io/opencensus/stats/StatsTest.java @@ -31,7 +31,7 @@ public void loadStatsManager_UsesProvidedClassLoader() { final RuntimeException toThrow = new RuntimeException("UseClassLoader"); thrown.expect(RuntimeException.class); thrown.expectMessage("UseClassLoader"); - Stats.loadStatsManager( + Stats.loadStatsComponent( new ClassLoader() { @Override public Class loadClass(String name) { @@ -43,7 +43,7 @@ public Class loadClass(String name) { @Test public void loadStatsManager_IgnoresMissingClasses() { assertThat( - Stats.loadStatsManager( + Stats.loadStatsComponent( new ClassLoader() { @Override public Class loadClass(String name) throws ClassNotFoundException { @@ -56,6 +56,7 @@ public Class loadClass(String name) throws ClassNotFoundException { @Test public void defaultValues() { assertThat(Stats.getStatsContextFactory()).isNull(); - assertThat(Stats.getStatsManager()).isNull(); + assertThat(Stats.getStatsRecorder()).isNull(); + assertThat(Stats.getViewManager()).isNull(); } } diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java b/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java new file mode 100644 index 0000000000..ddde102a46 --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java @@ -0,0 +1,47 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import io.opencensus.common.Clock; +import io.opencensus.internal.EventQueue; + +/** Base implementation of {@link StatsComponent}. */ +class StatsComponentImplBase extends StatsComponent { + + private final ViewManagerImpl viewManager; + private final StatsRecorderImpl statsRecorder; + private final StatsContextFactoryImpl statsContextFactory; + + StatsComponentImplBase(EventQueue queue, Clock clock) { + StatsManager statsManager = new StatsManager(queue, clock); + this.viewManager = new ViewManagerImpl(statsManager); + this.statsRecorder = new StatsRecorderImpl(statsManager); + this.statsContextFactory = new StatsContextFactoryImpl(statsRecorder); + } + + @Override + public ViewManagerImpl getViewManager() { + return viewManager; + } + + @Override + public StatsRecorderImpl getStatsRecorder() { + return statsRecorder; + } + + @Override + StatsContextFactoryImpl getStatsContextFactory() { + return statsContextFactory; + } +} diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsContextFactoryImpl.java b/core_impl/src/main/java/io/opencensus/stats/StatsContextFactoryImpl.java index ca23cbb9f5..ef2a7cc0b0 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsContextFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsContextFactoryImpl.java @@ -22,13 +22,13 @@ * Native Implementation of {@link StatsContextFactory}. */ final class StatsContextFactoryImpl extends StatsContextFactory { - private final StatsManagerImplBase statsManager; + private final StatsRecorderImpl statsRecorder; private final StatsContextImpl defaultStatsContext; - StatsContextFactoryImpl(StatsManagerImplBase statsManager) { - this.statsManager = Preconditions.checkNotNull(statsManager); + StatsContextFactoryImpl(StatsRecorderImpl statsRecorder) { + this.statsRecorder = Preconditions.checkNotNull(statsRecorder); this.defaultStatsContext = - new StatsContextImpl(statsManager, Collections.emptyMap()); + new StatsContextImpl(statsRecorder, Collections.emptyMap()); } /** @@ -38,7 +38,7 @@ final class StatsContextFactoryImpl extends StatsContextFactory { */ @Override public StatsContextImpl deserialize(InputStream input) throws IOException { - return StatsSerializer.deserialize(statsManager, input); + return StatsSerializer.deserialize(statsRecorder, input); } @Override diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java b/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java index 2faf0b0315..59f4473b1a 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java @@ -24,22 +24,22 @@ * Native Implementation of {@link StatsContext}. */ final class StatsContextImpl extends StatsContext { - private final StatsManagerImplBase statsManager; + private final StatsRecorderImpl statsRecorder; final Map tags; - StatsContextImpl(StatsManagerImplBase statsManager, Map tags) { - this.statsManager = Preconditions.checkNotNull(statsManager); + StatsContextImpl(StatsRecorderImpl statsRecorder, Map tags) { + this.statsRecorder = Preconditions.checkNotNull(statsRecorder); this.tags = Preconditions.checkNotNull(tags); } @Override public Builder builder() { - return new Builder(statsManager, tags); + return new Builder(statsRecorder, tags); } @Override public StatsContextImpl record(MeasurementMap stats) { - statsManager.record(this, stats); + statsRecorder.record(this, stats); return this; } @@ -69,11 +69,11 @@ public String toString() { } static final class Builder extends StatsContext.Builder { - private final StatsManagerImplBase statsManager; + private final StatsRecorderImpl statsRecorder; private final HashMap tags; - private Builder(StatsManagerImplBase statsManager, Map tags) { - this.statsManager = statsManager; + private Builder(StatsRecorderImpl statsRecorder, Map tags) { + this.statsRecorder = statsRecorder; this.tags = new HashMap(tags); } @@ -86,7 +86,7 @@ public Builder set(TagKey key, TagValue value) { @Override public StatsContextImpl build() { return new StatsContextImpl( - statsManager, Collections.unmodifiableMap(new HashMap(tags))); + statsRecorder, Collections.unmodifiableMap(new HashMap(tags))); } } } diff --git a/core_impl/src/main/java/io/opencensus/stats/ViewManager.java b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java similarity index 92% rename from core_impl/src/main/java/io/opencensus/stats/ViewManager.java rename to core_impl/src/main/java/io/opencensus/stats/StatsManager.java index cade127eaa..97b1c30dfa 100644 --- a/core_impl/src/main/java/io/opencensus/stats/ViewManager.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java @@ -18,7 +18,7 @@ import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; /** Object that stores all views and stats. */ -final class ViewManager { +final class StatsManager { private final EventQueue queue; @@ -28,7 +28,7 @@ final class ViewManager { private final MeasurementDescriptorToViewMap measurementDescriptorToViewMap = new MeasurementDescriptorToViewMap(); - ViewManager(EventQueue queue, Clock clock) { + StatsManager(EventQueue queue, Clock clock) { this.queue = queue; this.clock = clock; } @@ -61,9 +61,9 @@ void record(StatsContextImpl tags, MeasurementMap measurementValues) { private static final class StatsEvent implements EventQueue.Entry { private final StatsContextImpl tags; private final MeasurementMap stats; - private final ViewManager viewManager; + private final StatsManager viewManager; - StatsEvent(ViewManager viewManager, StatsContextImpl tags, MeasurementMap stats) { + StatsEvent(StatsManager viewManager, StatsContextImpl tags, MeasurementMap stats) { this.viewManager = viewManager; this.tags = tags; this.stats = stats; diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsManagerImplBase.java b/core_impl/src/main/java/io/opencensus/stats/StatsManagerImplBase.java deleted file mode 100644 index a523fcf7cb..0000000000 --- a/core_impl/src/main/java/io/opencensus/stats/StatsManagerImplBase.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import io.opencensus.common.Clock; -import io.opencensus.internal.EventQueue; - -/** - * Base implementation of {@link StatsManager}. - */ -class StatsManagerImplBase extends StatsManager { - - // StatsManagerImplBase delegates all operations related to stats to ViewManager in order to keep - // StatsManagerImplBase simple. - private final ViewManager viewManager; - - // The StatsContextFactoryImpl is lazily initialized because it references "this" and cannot be - // created in the constructor. Multiple initializations are okay. - private volatile StatsContextFactoryImpl statsContextFactory; - - StatsManagerImplBase(EventQueue queue, Clock clock) { - this.viewManager = new ViewManager(queue, clock); - } - - @Override - public void registerView(ViewDescriptor viewDescriptor) { - viewManager.registerView(viewDescriptor); - } - - // TODO(sebright): Replace this method with the ViewDescriptor.Name version. - @Override - public View getView(ViewDescriptor viewDescriptor) { - return getView(viewDescriptor.getViewDescriptorName()); - } - - // TODO(sebright): Expose this method. - View getView(ViewDescriptor.Name viewName) { - return viewManager.getView(viewName); - } - - @Override - StatsContextFactoryImpl getStatsContextFactory() { - StatsContextFactoryImpl factory = statsContextFactory; - if (factory == null) { - statsContextFactory = factory = new StatsContextFactoryImpl(this); - } - return factory; - } - - /** - * Records a set of measurements with a set of tags. - * - * @param tags the tags associated with the measurements - * @param measurementValues the measurements to record - */ - // TODO(sebright): Add this method to StatsManager. - void record(StatsContextImpl tags, MeasurementMap measurementValues) { - viewManager.record(tags, measurementValues); - } -} diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java b/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java new file mode 100644 index 0000000000..796f0b2367 --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java @@ -0,0 +1,29 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +/** Implementation of {@link StatsRecorder}. */ +final class StatsRecorderImpl extends StatsRecorder { + private final StatsManager statsManager; + + StatsRecorderImpl(StatsManager statsManager) { + this.statsManager = statsManager; + } + + @Override + void record(StatsContext tags, MeasurementMap measurementValues) { + // TODO(sebright): Replace StatsContext with TagContext, and then this cast won't be necessary. + statsManager.record((StatsContextImpl) tags, measurementValues); + } +} diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsSerializer.java b/core_impl/src/main/java/io/opencensus/stats/StatsSerializer.java index 945ead384b..449be11b47 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsSerializer.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsSerializer.java @@ -89,7 +89,7 @@ static void serialize(StatsContextImpl context, OutputStream output) throws IOEx // Deserializes input to StatsContext based on the binary format standard. // The encoded tags are of the form: - static StatsContextImpl deserialize(StatsManagerImplBase statsManager, InputStream input) + static StatsContextImpl deserialize(StatsRecorderImpl statsRecorder, InputStream input) throws IOException { try { byte[] bytes = ByteStreams.toByteArray(input); @@ -123,7 +123,7 @@ static StatsContextImpl deserialize(StatsManagerImplBase statsManager, InputStre throw new IOException("Unsupported tag value type."); } } - return new StatsContextImpl(statsManager, tags); + return new StatsContextImpl(statsRecorder, tags); } catch (BufferUnderflowException exn) { throw new IOException(exn.toString()); // byte array format error. } diff --git a/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java b/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java new file mode 100644 index 0000000000..4bc17e297b --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java @@ -0,0 +1,39 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +/** Implementation of {@link ViewManager}. */ +final class ViewManagerImpl extends ViewManager { + private final StatsManager statsManager; + + ViewManagerImpl(StatsManager statsManager) { + this.statsManager = statsManager; + } + + @Override + public void registerView(ViewDescriptor viewDescriptor) { + statsManager.registerView(viewDescriptor); + } + + // TODO(sebright): Expose this method. + View getView(ViewDescriptor.Name viewName) { + return statsManager.getView(viewName); + } + + // TODO(sebright): Replace this method with the ViewDescriptor.Name version. + @Override + public View getView(ViewDescriptor viewDescr) { + return statsManager.getView(viewDescr.getViewDescriptorName()); + } +} diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java index f38c1d6e2e..8a4e43f5b8 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java @@ -39,9 +39,10 @@ public class StatsContextFactoryTest { private static final String VALUE_STRING = "String"; private static final int VALUE_INT = 10; - private final StatsManagerImplBase statsManager = - new StatsManagerImplBase(new SimpleEventQueue(), TestClock.create()); - private final StatsContextFactory factory = new StatsContextFactoryImpl(statsManager); + private final StatsComponentImplBase statsComponent = + new StatsComponentImplBase(new SimpleEventQueue(), TestClock.create()); + private final StatsContextFactory factory = statsComponent.getStatsContextFactory(); + private final StatsRecorderImpl statsRecorder = statsComponent.getStatsRecorder(); private final HashMap sampleTags = new HashMap(); private final StatsContext defaultCtx = factory.getDefault(); private final StatsContext statsContext = factory.getDefault() @@ -78,7 +79,7 @@ public void testDeserializeEmptyByteArrayThrowException() throws Exception { @Test public void testDeserializeValueTypeString() throws Exception { - StatsContext expected = new StatsContextImpl(statsManager, sampleTags); + StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); StatsContext actual = testDeserialize( constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_STRING)); assertThat(actual).isEqualTo(expected); @@ -87,7 +88,7 @@ public void testDeserializeValueTypeString() throws Exception { @Test public void testDeserializeMultipleString() throws Exception { sampleTags.put(TagKey.create("Key2"), TagValue.create("String2")); - StatsContext expected = new StatsContextImpl(statsManager, sampleTags); + StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byteArrayOutputStream.write(StatsSerializer.VERSION_ID); diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index 9c77f5f418..96b9ed3667 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -20,10 +20,10 @@ import com.google.common.testing.EqualsTester; import io.opencensus.common.Function; import io.opencensus.internal.SimpleEventQueue; -import io.opencensus.testing.common.TestClock; import io.opencensus.internal.VarInt; import io.opencensus.stats.View.DistributionView; import io.opencensus.stats.View.IntervalView; +import io.opencensus.testing.common.TestClock; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -41,9 +41,10 @@ public class StatsContextTest { private static final double TOLERANCE = 1e-6; - private final StatsManagerImplBase statsManager = - new StatsManagerImplBase(new SimpleEventQueue(), TestClock.create()); - private final StatsContextFactory factory = statsManager.getStatsContextFactory(); + private final StatsComponentImplBase statsComponent = + new StatsComponentImplBase(new SimpleEventQueue(), TestClock.create()); + private final ViewManager viewManager = statsComponent.getViewManager(); + private final StatsContextFactory factory = statsComponent.getStatsContextFactory(); private final StatsContext defaultStatsContext = factory.getDefault(); private static final int VERSION_ID = 0; @@ -109,8 +110,10 @@ public void testWithComposed() { // The main tests for stats recording are in StatsManagerImplTest. @Test public void testRecord() { - statsManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - View beforeView = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + viewManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + View beforeView = + viewManager.getView( + RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); beforeView.match( new Function() { @Override @@ -132,7 +135,9 @@ public Void apply(IntervalView view) { MeasurementMap measurements = MeasurementMap.of(RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1); context.record(measurements); - View afterView = statsManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + View afterView = + viewManager.getView( + RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); afterView.match( new Function() { @Override diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java similarity index 84% rename from core_impl/src/test/java/io/opencensus/stats/StatsManagerImplTest.java rename to core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index a964db102d..c4d3f98d29 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -34,9 +34,9 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link StatsManagerImplBase}. */ +/** Tests for {@link ViewManagerImpl}. */ @RunWith(JUnit4.class) -public class StatsManagerImplTest { +public class ViewManagerImplTest { @Rule public final ExpectedException thrown = ExpectedException.none(); @@ -74,10 +74,12 @@ public class StatsManagerImplTest { private final TestClock clock = TestClock.create(); - private final StatsManagerImplBase statsManager = - new StatsManagerImplBase(new SimpleEventQueue(), clock); + private final StatsComponentImplBase statsComponent = + new StatsComponentImplBase(new SimpleEventQueue(), clock); - private final StatsContextFactoryImpl factory = new StatsContextFactoryImpl(statsManager); + private final StatsContextFactoryImpl factory = statsComponent.getStatsContextFactory(); + private final ViewManagerImpl viewManager = statsComponent.getViewManager(); + private final StatsRecorder statsRecorder = statsComponent.getStatsRecorder(); private static DistributionViewDescriptor createDistributionViewDescriptor() { return createDistributionViewDescriptor( @@ -95,8 +97,8 @@ private static DistributionViewDescriptor createDistributionViewDescriptor( @Test public void testRegisterAndGetView() { DistributionViewDescriptor viewDescr = createDistributionViewDescriptor(); - statsManager.registerView(viewDescr); - assertThat(statsManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(viewDescr); + viewManager.registerView(viewDescr); + assertThat(viewManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(viewDescr); } @Test @@ -109,15 +111,15 @@ public void preventRegisteringIntervalView() { IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(1000))), Arrays.asList(KEY)); thrown.expect(UnsupportedOperationException.class); - statsManager.registerView(intervalView); + viewManager.registerView(intervalView); } @Test public void allowRegisteringSameViewDescriptorTwice() { DistributionViewDescriptor viewDescr = createDistributionViewDescriptor(); - statsManager.registerView(viewDescr); - statsManager.registerView(viewDescr); - assertThat(statsManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(viewDescr); + viewManager.registerView(viewDescr); + viewManager.registerView(viewDescr); + assertThat(viewManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(viewDescr); } @Test @@ -129,7 +131,7 @@ public void preventRegisteringDifferentViewDescriptorWithSameName() { MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); - statsManager.registerView(view1); + viewManager.registerView(view1); ViewDescriptor view2 = DistributionViewDescriptor.create( VIEW_NAME, @@ -140,16 +142,16 @@ public void preventRegisteringDifferentViewDescriptorWithSameName() { try { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("A different view with the same name is already registered"); - statsManager.registerView(view2); + viewManager.registerView(view2); } finally { - assertThat(statsManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(view1); + assertThat(viewManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(view1); } } @Test public void disallowGettingNonexistentView() { thrown.expect(IllegalArgumentException.class); - statsManager.getView(VIEW_NAME); + viewManager.getView(VIEW_NAME); } @Test @@ -161,13 +163,13 @@ public void testRecord() { DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 2)); - statsManager.registerView(viewDescr); + viewManager.registerView(viewDescr); StatsContextImpl tags = createContext(factory, KEY, VALUE); for (double val : Arrays.asList(10.0, 20.0, 30.0, 40.0)) { - statsManager.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, val)); + statsRecorder.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, val)); } clock.setTime(Timestamp.create(3, 4)); - DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertThat(view.getViewDescriptor()).isEqualTo(viewDescr); assertThat(view.getStart()).isEqualTo(Timestamp.create(1, 2)); assertThat(view.getEnd()).isEqualTo(Timestamp.create(3, 4)); @@ -189,11 +191,11 @@ public void getViewDoesNotClearStats() { DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(10, 0)); - statsManager.registerView(viewDescr); + viewManager.registerView(viewDescr); StatsContextImpl tags = createContext(factory, KEY, VALUE); - statsManager.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.1)); + statsRecorder.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.1)); clock.setTime(Timestamp.create(11, 0)); - DistributionView view1 = (DistributionView) statsManager.getView(VIEW_NAME); + DistributionView view1 = (DistributionView) viewManager.getView(VIEW_NAME); assertThat(view1.getStart()).isEqualTo(Timestamp.create(10, 0)); assertThat(view1.getEnd()).isEqualTo(Timestamp.create(11, 0)); assertDistributionAggregationsEquivalent( @@ -201,9 +203,9 @@ public void getViewDoesNotClearStats() { Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(0.1)))); - statsManager.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.2)); + statsRecorder.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.2)); clock.setTime(Timestamp.create(12, 0)); - DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME); + DistributionView view2 = (DistributionView) viewManager.getView(VIEW_NAME); // The second view should have the same start time as the first view, and it should include both // recorded values: @@ -220,19 +222,19 @@ public void getViewDoesNotClearStats() { @Test public void testRecordMultipleTagValues() { - statsManager.registerView( + viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); - statsManager.record( + statsRecorder.record( createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); - statsManager.record( + statsRecorder.record( createContext(factory, KEY, VALUE_2), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 30.0)); - statsManager.record( + statsRecorder.record( createContext(factory, KEY, VALUE_2), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 50.0)); - DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( view.getDistributionAggregations(), Arrays.asList( @@ -244,27 +246,25 @@ public void testRecordMultipleTagValues() { Arrays.asList(30.0, 50.0)))); } - // This test checks that StatsManager.record(...) does not throw an exception when no views are + // This test checks that StatsRecorder.record(...) does not throw an exception when no views are // registered. @Test public void allowRecordingWithoutRegisteringMatchingView() { - statsManager.record( + statsRecorder.record( createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10)); } @Test public void testRecordWithEmptyStatsContext() { - statsManager.registerView( + viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); // DEFAULT doesn't have tags, but the view has tag key "KEY". - statsManager.record( - statsManager.getStatsContextFactory().getDefault(), - MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); - DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + statsRecorder.record(factory.getDefault(), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); + DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( view.getDistributionAggregations(), Arrays.asList( @@ -279,7 +279,7 @@ public void testRecordWithEmptyStatsContext() { @Test public void testRecordWithNonExistentMeasurementDescriptor() { - statsManager.registerView( + viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, MeasurementDescriptor.create(MEASUREMENT_NAME, "measurement", MEASUREMENT_UNIT), @@ -287,26 +287,26 @@ public void testRecordWithNonExistentMeasurementDescriptor() { Arrays.asList(KEY))); MeasurementDescriptor measure2 = MeasurementDescriptor.create(MEASUREMENT_NAME_2, "measurement", MEASUREMENT_UNIT); - statsManager.record(createContext(factory, KEY, VALUE), MeasurementMap.of(measure2, 10.0)); - DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + statsRecorder.record(createContext(factory, KEY, VALUE), MeasurementMap.of(measure2, 10.0)); + DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertThat(view.getDistributionAggregations()).isEmpty(); } @Test public void testRecordWithTagsThatDoNotMatchView() { - statsManager.registerView( + viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); - statsManager.record( + statsRecorder.record( createContext(factory, TagKey.create("wrong key"), VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); - statsManager.record( + statsRecorder.record( createContext(factory, TagKey.create("another wrong key"), VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 50.0)); - DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( view.getDistributionAggregations(), Arrays.asList( @@ -323,25 +323,25 @@ public void testRecordWithTagsThatDoNotMatchView() { public void testViewWithMultipleTagKeys() { TagKey key1 = TagKey.create("Key-1"); TagKey key2 = TagKey.create("Key-2"); - statsManager.registerView( + viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(key1, key2))); - statsManager.record( + statsRecorder.record( createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 1.1)); - statsManager.record( + statsRecorder.record( createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v20")), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 2.2)); - statsManager.record( + statsRecorder.record( createContext(factory, key1, TagValue.create("v2"), key2, TagValue.create("v10")), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 3.3)); - statsManager.record( + statsRecorder.record( createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 4.4)); - DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( view.getDistributionAggregations(), Arrays.asList( @@ -380,19 +380,19 @@ public void testMultipleViewsSameMeasure() { DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 1)); - statsManager.registerView(viewDescr1); + viewManager.registerView(viewDescr1); clock.setTime(Timestamp.create(2, 2)); - statsManager.registerView(viewDescr2); - statsManager.record( + viewManager.registerView(viewDescr2); + statsRecorder.record( createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 5.0)); List expectedAggs = Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(5.0))); clock.setTime(Timestamp.create(3, 3)); - DistributionView view1 = (DistributionView) statsManager.getView(VIEW_NAME); + DistributionView view1 = (DistributionView) viewManager.getView(VIEW_NAME); clock.setTime(Timestamp.create(4, 4)); - DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME_2); + DistributionView view2 = (DistributionView) viewManager.getView(VIEW_NAME_2); assertThat(view1.getStart()).isEqualTo(Timestamp.create(1, 1)); assertThat(view1.getEnd()).isEqualTo(Timestamp.create(3, 3)); assertDistributionAggregationsEquivalent(view1.getDistributionAggregations(), expectedAggs); @@ -414,16 +414,16 @@ public void testMultipleViewsDifferentMeasures() { createDistributionViewDescriptor( VIEW_NAME_2, measureDescr2, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); - statsManager.registerView(viewDescr1); + viewManager.registerView(viewDescr1); clock.setTime(Timestamp.create(2, 0)); - statsManager.registerView(viewDescr2); - statsManager.record( + viewManager.registerView(viewDescr2); + statsRecorder.record( createContext(factory, KEY, VALUE), MeasurementMap.of(measureDescr1, 1.1, measureDescr2, 2.2)); clock.setTime(Timestamp.create(3, 0)); - DistributionView view1 = (DistributionView) statsManager.getView(VIEW_NAME); + DistributionView view1 = (DistributionView) viewManager.getView(VIEW_NAME); clock.setTime(Timestamp.create(4, 0)); - DistributionView view2 = (DistributionView) statsManager.getView(VIEW_NAME_2); + DistributionView view2 = (DistributionView) viewManager.getView(VIEW_NAME_2); assertThat(view1.getStart()).isEqualTo(Timestamp.create(1, 0)); assertThat(view1.getEnd()).isEqualTo(Timestamp.create(3, 0)); assertDistributionAggregationsEquivalent( @@ -447,11 +447,11 @@ public void testGetDistributionViewWithoutBucketBoundaries() { VIEW_NAME, MEASUREMENT_DESCRIPTOR, DistributionAggregationDescriptor.create(), Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); - statsManager.registerView(viewDescr); - statsManager.record( + viewManager.registerView(viewDescr); + statsRecorder.record( createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 1.1)); clock.setTime(Timestamp.create(3, 0)); - DistributionView view = (DistributionView) statsManager.getView(VIEW_NAME); + DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertThat(view.getStart()).isEqualTo(Timestamp.create(1, 0)); assertThat(view.getEnd()).isEqualTo(Timestamp.create(3, 0)); assertDistributionAggregationsEquivalent( diff --git a/core_impl_android/src/main/java/io/opencensus/stats/StatsManagerImplLite.java b/core_impl_android/src/main/java/io/opencensus/stats/StatsComponentImplLite.java similarity index 82% rename from core_impl_android/src/main/java/io/opencensus/stats/StatsManagerImplLite.java rename to core_impl_android/src/main/java/io/opencensus/stats/StatsComponentImplLite.java index 612de6f20e..58cbd8cb31 100644 --- a/core_impl_android/src/main/java/io/opencensus/stats/StatsManagerImplLite.java +++ b/core_impl_android/src/main/java/io/opencensus/stats/StatsComponentImplLite.java @@ -17,11 +17,11 @@ import io.opencensus.internal.SimpleEventQueue; /** - * Android-compatible implementation of {@link StatsManager}. + * Android-compatible implementation of {@link StatsComponent}. */ -public final class StatsManagerImplLite extends StatsManagerImplBase { +public final class StatsComponentImplLite extends StatsComponentImplBase { - public StatsManagerImplLite() { + public StatsComponentImplLite() { // TODO(sebright): Use a more efficient queue implementation. super(new SimpleEventQueue(), MillisClock.getInstance()); } diff --git a/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java b/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java index 346c1e2e55..8c423d80c6 100644 --- a/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java +++ b/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java @@ -20,17 +20,22 @@ import org.junit.runners.JUnit4; /** - * Test for accessing the {@link StatsManager} through the {@link Stats} class. + * Test for accessing the {@link StatsComponent} through the {@link Stats} class. */ @RunWith(JUnit4.class) public final class StatsTest { @Test - public void getStatsManager() { - assertThat(Stats.getStatsManager()).isInstanceOf(StatsManagerImplLite.class); + public void getStatsRecorder() { + assertThat(Stats.getStatsRecorder()).isInstanceOf(StatsRecorderImpl.class); + } + + @Test + public void getViewManager() { + assertThat(Stats.getViewManager()).isInstanceOf(ViewManagerImpl.class); } @Test public void getStatsContextFactory() { - assertThat(Stats.getStatsContextFactory()).isNotNull(); + assertThat(Stats.getStatsContextFactory()).isInstanceOf(StatsContextFactoryImpl.class); } } diff --git a/core_impl_java/src/main/java/io/opencensus/stats/StatsManagerImpl.java b/core_impl_java/src/main/java/io/opencensus/stats/StatsComponentImpl.java similarity index 83% rename from core_impl_java/src/main/java/io/opencensus/stats/StatsManagerImpl.java rename to core_impl_java/src/main/java/io/opencensus/stats/StatsComponentImpl.java index 67370631ab..d4790e253a 100644 --- a/core_impl_java/src/main/java/io/opencensus/stats/StatsManagerImpl.java +++ b/core_impl_java/src/main/java/io/opencensus/stats/StatsComponentImpl.java @@ -16,11 +16,11 @@ import io.opencensus.common.MillisClock; import io.opencensus.internal.DisruptorEventQueue; -/** Java 7 and 8 implementation of {@link StatsManager}. */ -public final class StatsManagerImpl extends StatsManagerImplBase { +/** Java 7 and 8 implementation of {@link StatsComponent}. */ +public final class StatsComponentImpl extends StatsComponentImplBase { /** Public constructor to be used with reflection loading. */ - public StatsManagerImpl() { + public StatsComponentImpl() { super(DisruptorEventQueue.getInstance(), MillisClock.getInstance()); } } diff --git a/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java b/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java index 57b0291012..8002c2f755 100644 --- a/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java +++ b/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java @@ -19,17 +19,21 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Test for accessing the {@link StatsManager} through the {@link Stats} class. */ +/** Test for accessing the {@link StatsComponent} through the {@link Stats} class. */ @RunWith(JUnit4.class) public final class StatsTest { @Test - public void getStatsManager() { - assertThat(Stats.getStatsManager()).isInstanceOf(StatsManagerImpl.class); + public void getStatsRecorder() { + assertThat(Stats.getStatsRecorder()).isInstanceOf(StatsRecorderImpl.class); } + @Test + public void getViewManager() { + assertThat(Stats.getViewManager()).isInstanceOf(ViewManagerImpl.class); + } @Test public void getStatsContextFactory() { - assertThat(Stats.getStatsContextFactory()).isNotNull(); + assertThat(Stats.getStatsContextFactory()).isInstanceOf(StatsContextFactoryImpl.class); } } From b83db2d9da514dbcd8619a2eb3baab8ef5f12c8a Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 23 Jun 2017 13:23:25 -0700 Subject: [PATCH 0194/1581] Remove deprecated RpcConstants class. This class is no longer needed for backwards compatibility, since we have already changed its package name. --- .../io/opencensus/stats/RpcConstants.java | 485 ------------------ .../io/opencensus/stats/RpcConstantsTest.java | 110 ---- 2 files changed, 595 deletions(-) delete mode 100644 core/src/main/java/io/opencensus/stats/RpcConstants.java delete mode 100644 core/src/test/java/io/opencensus/stats/RpcConstantsTest.java diff --git a/core/src/main/java/io/opencensus/stats/RpcConstants.java b/core/src/main/java/io/opencensus/stats/RpcConstants.java deleted file mode 100644 index 095cdfea61..0000000000 --- a/core/src/main/java/io/opencensus/stats/RpcConstants.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import io.opencensus.common.Duration; -import io.opencensus.stats.MeasurementDescriptor.BasicUnit; -import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; -import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; -import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * Constants for collecting rpc stats. - */ -// Deprecated, please use RpcMeasurementConstants for MeasurementDescriptor constants, and -// RpcViewConstants for ViewDescriptor constants. -@Deprecated -public final class RpcConstants { - // Rpc tag keys. - public static final TagKey RPC_STATUS = TagKey.create("OpStatus"); - public static final TagKey RPC_CLIENT_METHOD = TagKey.create("method"); - public static final TagKey RPC_SERVER_METHOD = TagKey.create("method"); - - // Constants used to define the following MeasurementDescriptors. - private static final List bytes = Arrays.asList(BasicUnit.BYTES); - private static final List scalar = Arrays.asList(BasicUnit.SCALAR); - private static final List seconds = Arrays.asList(BasicUnit.SECONDS); - - // RPC client {@link MeasurementDescriptor}s. - public static final MeasurementDescriptor RPC_CLIENT_ERROR_COUNT = - MeasurementDescriptor.create( - "grpc.io/client/error_count", - "RPC Errors", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_CLIENT_REQUEST_BYTES = - MeasurementDescriptor.create( - "grpc.io/client/request_bytes", - "Request bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_CLIENT_RESPONSE_BYTES = - MeasurementDescriptor.create( - "grpc.io/client/response_bytes", - "Response bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_CLIENT_ROUNDTRIP_LATENCY = - MeasurementDescriptor.create( - "grpc.io/client/roundtrip_latency", - "RPC roundtrip latency msec", - MeasurementUnit.create(-3, seconds)); - public static final MeasurementDescriptor RPC_CLIENT_SERVER_ELAPSED_TIME = - MeasurementDescriptor.create( - "grpc.io/client/server_elapsed_time", - "Server elapsed time in msecs", - MeasurementUnit.create(-3, seconds)); - public static final MeasurementDescriptor RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES = - MeasurementDescriptor.create( - "grpc.io/client/uncompressed_request_bytes", - "Uncompressed Request bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES = - MeasurementDescriptor.create( - "grpc.io/client/uncompressed_response_bytes", - "Uncompressed Response bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_CLIENT_STARTED_COUNT = - MeasurementDescriptor.create( - "grpc.io/client/started_count", - "Number of client RPCs (streams) started", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_CLIENT_FINISHED_COUNT = - MeasurementDescriptor.create( - "grpc.io/client/finished_count", - "Number of client RPCs (streams) finished", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_CLIENT_REQUEST_COUNT = - MeasurementDescriptor.create( - "grpc.io/client/request_count", - "Number of client RPC request messages", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_CLIENT_RESPONSE_COUNT = - MeasurementDescriptor.create( - "grpc.io/client/response_count", - "Number of client RPC response messages", - MeasurementUnit.create(0, scalar)); - - - // RPC server {@link MeasurementDescriptor}s. - public static final MeasurementDescriptor RPC_SERVER_ERROR_COUNT = - MeasurementDescriptor.create( - "grpc.io/server/error_count", - "RPC Errors", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_SERVER_REQUEST_BYTES = - MeasurementDescriptor.create( - "grpc.io/server/request_bytes", - "Request bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_SERVER_RESPONSE_BYTES = - MeasurementDescriptor.create( - "grpc.io/server/response_bytes", - "Response bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_SERVER_SERVER_ELAPSED_TIME = - MeasurementDescriptor.create( - "grpc.io/server/server_elapsed_time", - "Server elapsed time in msecs", - MeasurementUnit.create(-3, seconds)); - public static final MeasurementDescriptor RPC_SERVER_SERVER_LATENCY = - MeasurementDescriptor.create( - "grpc.io/server/server_latency", - "Latency in msecs", - MeasurementUnit.create(-3, seconds)); - public static final MeasurementDescriptor RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES = - MeasurementDescriptor.create( - "grpc.io/server/uncompressed_request_bytes", - "Uncompressed Request bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES = - MeasurementDescriptor.create( - "grpc.io/server/uncompressed_response_bytes", - "Uncompressed Response bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_SERVER_STARTED_COUNT = - MeasurementDescriptor.create( - "grpc.io/server/started_count", - "Number of server RPCs (streams) started", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_SERVER_FINISHED_COUNT = - MeasurementDescriptor.create( - "grpc.io/server/finished_count", - "Number of server RPCs (streams) finished", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_SERVER_REQUEST_COUNT = - MeasurementDescriptor.create( - "grpc.io/server/request_count", - "Number of server RPC request messages", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_SERVER_RESPONSE_COUNT = - MeasurementDescriptor.create( - "grpc.io/server/response_count", - "Number of server RPC response messages", - MeasurementUnit.create(0, scalar)); - - // Common histogram bucket boundaries for bytes received/sets DistributionViewDescriptors. - static final List RPC_BYTES_BUCKET_BOUNDARIES = Collections.unmodifiableList( - Arrays.asList(0.0, 1024.0, 2048.0, 4096.0, 16384.0, 65536.0, 262144.0, 1048576.0, 4194304.0, - 16777216.0, 67108864.0, 268435456.0, 1073741824.0, 4294967296.0)); - - // Common histogram bucket boundaries for latency and elapsed-time DistributionViewDescriptors. - static final List RPC_MILLIS_BUCKET_BOUNDARIES = Collections.unmodifiableList( - Arrays.asList(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 13.0, 16.0, 20.0, 25.0, 30.0, - 40.0, 50.0, 65.0, 80.0, 100.0, 130.0, 160.0, 200.0, 250.0, 300.0, 400.0, 500.0, 650.0, - 800.0, 1000.0, 2000.0, 5000.0, 10000.0, 20000.0, 50000.0, 100000.0)); - - // Rpc client {@link ViewDescriptor}s. - public static final DistributionViewDescriptor RPC_CLIENT_ERROR_COUNT_VIEW = - DistributionViewDescriptor.create( - "grpc.io/client/error_count/distribution_cumulative", - "RPC Errors", - RPC_CLIENT_ERROR_COUNT, - DistributionAggregationDescriptor.create(), - Arrays.asList(RPC_STATUS, RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW = - DistributionViewDescriptor.create( - "grpc.io/client/roundtrip_latency/distribution_cumulative", - "Latency in msecs", - RPC_CLIENT_ROUNDTRIP_LATENCY, - DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_SERVER_ELAPSED_TIME_VIEW = - DistributionViewDescriptor.create( - "grpc.io/client/server_elapsed_time/distribution_cumulative", - "Server elapsed time in msecs", - RPC_CLIENT_SERVER_ELAPSED_TIME, - DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_REQUEST_BYTES_VIEW = - DistributionViewDescriptor.create( - "grpc.io/client/request_bytes/distribution_cumulative", - "Request bytes", - RPC_CLIENT_REQUEST_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_RESPONSE_BYTES_VIEW = - DistributionViewDescriptor.create( - "grpc.io/client/response_bytes/distribution_cumulative", - "Response bytes", - RPC_CLIENT_RESPONSE_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_VIEW = - DistributionViewDescriptor.create( - "grpc.io/client/uncompressed_request_bytes/distribution_cumulative", - "Uncompressed Request bytes", - RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_VIEW = - DistributionViewDescriptor.create( - "grpc.io/client/uncompressed_response_bytes/distribution_cumulative", - "Uncompressed Response bytes", - RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_REQUEST_COUNT_VIEW = - DistributionViewDescriptor.create( - "grpc.io/client/request_count/distribution_cumulative", - "Count of request messages per client RPC", - RPC_CLIENT_REQUEST_COUNT, - DistributionAggregationDescriptor.create(), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_RESPONSE_COUNT_VIEW = - DistributionViewDescriptor.create( - "grpc.io/client/response_count/distribution_cumulative", - "Count of response messages per client RPC", - RPC_CLIENT_RESPONSE_COUNT, - DistributionAggregationDescriptor.create(), - Arrays.asList(RPC_CLIENT_METHOD)); - - - // Rpc server {@link ViewDescriptor}s. - public static final DistributionViewDescriptor RPC_SERVER_ERROR_COUNT_VIEW = - DistributionViewDescriptor.create( - "grpc.io/server/error_count/distribution_cumulative", - "RPC Errors", - RPC_SERVER_ERROR_COUNT, - DistributionAggregationDescriptor.create(), - Arrays.asList(RPC_STATUS, RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_SERVER_LATENCY_VIEW = - DistributionViewDescriptor.create( - "grpc.io/server/server_latency/distribution_cumulative", - "Latency in msecs", - RPC_SERVER_SERVER_LATENCY, - DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_SERVER_ELAPSED_TIME_VIEW = - DistributionViewDescriptor.create( - "grpc.io/server/elapsed_time/distribution_cumulative", - "Server elapsed time in msecs", - RPC_SERVER_SERVER_ELAPSED_TIME, - DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_REQUEST_BYTES_VIEW = - DistributionViewDescriptor.create( - "grpc.io/server/request_bytes/distribution_cumulative", - "Request bytes", - RPC_SERVER_REQUEST_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_RESPONSE_BYTES_VIEW = - DistributionViewDescriptor.create( - "grpc.io/server/response_bytes/distribution_cumulative", - "Response bytes", - RPC_SERVER_RESPONSE_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_VIEW = - DistributionViewDescriptor.create( - "grpc.io/server/uncompressed_request_bytes/distribution_cumulative", - "Uncompressed Request bytes", - RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_VIEW = - DistributionViewDescriptor.create( - "grpc.io/server/uncompressed_response_bytes/distribution_cumulative", - "Uncompressed Response bytes", - RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_REQUEST_COUNT_VIEW = - DistributionViewDescriptor.create( - "grpc.io/server/request_count/distribution_cumulative", - "Count of request messages per server RPC", - RPC_SERVER_REQUEST_COUNT, - DistributionAggregationDescriptor.create(), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_RESPONSE_COUNT_VIEW = - DistributionViewDescriptor.create( - "grpc.io/server/response_count/distribution_cumulative", - "Count of response messages per server RPC", - RPC_SERVER_RESPONSE_COUNT, - DistributionAggregationDescriptor.create(), - Arrays.asList(RPC_SERVER_METHOD)); - - // Interval Stats - static final Duration MINUTE = Duration.create(60, 0); - static final Duration HOUR = Duration.create(60 * 60, 0); - - // RPC client {@link IntervalViewDescriptor}s. - public static final IntervalViewDescriptor RPC_CLIENT_ROUNDTRIP_LATENCY_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/client/roundtrip_latency/interval", - "Minute and Hour stats for latency in msecs", - RPC_CLIENT_ROUNDTRIP_LATENCY, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); - - public static final IntervalViewDescriptor RPC_CLIENT_REQUEST_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/client/request_bytes/interval", - "Minute and Hour stats for request size in bytes", - RPC_CLIENT_REQUEST_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); - - public static final IntervalViewDescriptor RPC_CLIENT_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/client/response_bytes/interval", - "Minute and Hour stats for response size in bytes", - RPC_CLIENT_RESPONSE_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); - - public static final IntervalViewDescriptor RPC_CLIENT_ERROR_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/client/error_count/interval", - "Minute and Hour stats for rpc errors", - RPC_CLIENT_ERROR_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); - - public static final IntervalViewDescriptor RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/client/uncompressed_request_bytes/interval", - "Minute and Hour stats for uncompressed request size in bytes", - RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); - - public static final IntervalViewDescriptor RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/client/uncompressed_response_bytes/interval", - "Minute and Hour stats for uncompressed response size in bytes", - RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); - - public static final IntervalViewDescriptor RPC_CLIENT_SERVER_ELAPSED_TIME_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/client/server_elapsed_time/interval", - "Minute and Hour stats for server elapsed time in msecs", - RPC_CLIENT_SERVER_ELAPSED_TIME, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); - - public static final IntervalViewDescriptor RPC_CLIENT_STARTED_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/client/started_count/interval", - "Minute and Hour stats on the number of client RPCs started", - RPC_CLIENT_STARTED_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); - - public static final IntervalViewDescriptor RPC_CLIENT_FINISHED_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/client/finished_count/interval", - "Minute and Hour stats on the number of client RPCs finished", - RPC_CLIENT_FINISHED_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); - - public static final IntervalViewDescriptor RPC_CLIENT_REQUEST_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/client/request_count/interval", - "Minute and Hour stats on the count of request messages per client RPC", - RPC_CLIENT_REQUEST_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); - - public static final IntervalViewDescriptor RPC_CLIENT_RESPONSE_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/client/response_count/interval", - "Minute and Hour stats on the count of response messages per client RPC", - RPC_CLIENT_RESPONSE_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); - - // RPC server {@link IntervalViewDescriptor}s. - public static final IntervalViewDescriptor RPC_SERVER_SERVER_LATENCY_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/server/server_latency/interval", - "Minute and Hour stats for server latency in msecs", - RPC_SERVER_SERVER_LATENCY, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); - - public static final IntervalViewDescriptor RPC_SERVER_REQUEST_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/server/request_bytes/interval", - "Minute and Hour stats for request size in bytes", - RPC_SERVER_REQUEST_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); - - public static final IntervalViewDescriptor RPC_SERVER_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/server/response_bytes/interval", - "Minute and Hour stats for response size in bytes", - RPC_SERVER_RESPONSE_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); - - public static final IntervalViewDescriptor RPC_SERVER_ERROR_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/server/error_count/interval", - "Minute and Hour stats for rpc errors", - RPC_SERVER_ERROR_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); - - public static final IntervalViewDescriptor RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/server/uncompressed_request_bytes/interval", - "Minute and Hour stats for uncompressed request size in bytes", - RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); - - public static final IntervalViewDescriptor RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/server/uncompressed_response_bytes/interval", - "Minute and Hour stats for uncompressed response size in bytes", - RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); - - public static final IntervalViewDescriptor RPC_SERVER_SERVER_ELAPSED_TIME_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/server/server_elapsed_time/interval", - "Minute and Hour stats for server elapsed time in msecs", - RPC_SERVER_SERVER_ELAPSED_TIME, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); - - public static final IntervalViewDescriptor RPC_SERVER_STARTED_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/server/started_count/interval", - "Minute and Hour stats on the number of server RPCs started", - RPC_SERVER_STARTED_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); - - public static final IntervalViewDescriptor RPC_SERVER_FINISHED_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/server/finished_count/interval", - "Minute and Hour stats on the number of server RPCs finished", - RPC_SERVER_FINISHED_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); - - public static final IntervalViewDescriptor RPC_SERVER_REQUEST_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/server/request_count/interval", - "Minute and Hour stats on the count of request messages per server RPC", - RPC_SERVER_REQUEST_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); - - public static final IntervalViewDescriptor RPC_SERVER_RESPONSE_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( - "grpc.io/server/response_count/interval", - "Minute and Hour stats on the count of response messages per server RPC", - RPC_SERVER_RESPONSE_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); - - // Visible for testing - RpcConstants() { - throw new AssertionError(); - } -} diff --git a/core/src/test/java/io/opencensus/stats/RpcConstantsTest.java b/core/src/test/java/io/opencensus/stats/RpcConstantsTest.java deleted file mode 100644 index 01e220652b..0000000000 --- a/core/src/test/java/io/opencensus/stats/RpcConstantsTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests for {@link RpcConstants} - */ -@Deprecated -@RunWith(JUnit4.class) -public final class RpcConstantsTest { - @Test - public void testConstants() { - assertThat(RpcConstants.RPC_STATUS).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_METHOD).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_METHOD).isNotNull(); - - // Test client measurement descriptors. - assertThat(RpcConstants.RPC_CLIENT_ERROR_COUNT).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_REQUEST_BYTES).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_RESPONSE_BYTES).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_REQUEST_COUNT).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_RESPONSE_COUNT).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_STARTED_COUNT).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_FINISHED_COUNT).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_SERVER_ELAPSED_TIME).isNotNull(); - - // Test server measurement descriptors. - assertThat(RpcConstants.RPC_SERVER_ERROR_COUNT).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_REQUEST_BYTES).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_RESPONSE_BYTES).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_SERVER_LATENCY).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_REQUEST_COUNT).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_RESPONSE_COUNT).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_STARTED_COUNT).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_FINISHED_COUNT).isNotNull(); - - // Test client distribution view descriptors. - assertThat(RpcConstants.RPC_CLIENT_ERROR_COUNT_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_REQUEST_BYTES_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_RESPONSE_BYTES_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_REQUEST_COUNT_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_RESPONSE_COUNT_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_SERVER_ELAPSED_TIME_VIEW).isNotNull(); - - // Test server distribution view descriptors. - assertThat(RpcConstants.RPC_SERVER_ERROR_COUNT_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_SERVER_LATENCY_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_REQUEST_BYTES_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_RESPONSE_BYTES_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_REQUEST_COUNT_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_RESPONSE_COUNT_VIEW).isNotNull(); - - // Test client interval view descriptors. - assertThat(RpcConstants.RPC_CLIENT_ERROR_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_STARTED_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_FINISHED_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_SERVER_ELAPSED_TIME_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_REQUEST_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_CLIENT_RESPONSE_COUNT_INTERVAL_VIEW).isNotNull(); - - // Test server interval view descriptors. - assertThat(RpcConstants.RPC_SERVER_ERROR_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_SERVER_LATENCY_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_STARTED_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_FINISHED_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_REQUEST_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcConstants.RPC_SERVER_RESPONSE_COUNT_INTERVAL_VIEW).isNotNull(); - } - - @Test(expected = AssertionError.class) - public void testConstructor() { - new RpcConstants(); - } -} From 66294a6299744ffbc32f8ca61fdb5109753b1adf Mon Sep 17 00:00:00 2001 From: easy Date: Mon, 26 Jun 2017 17:49:34 +1000 Subject: [PATCH 0195/1581] Fill out Javadoc for SpanImpl#startSpan(). (#391) --- .../java/io/opencensus/trace/SpanImpl.java | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java index a1768f35f1..53a8053ef6 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java @@ -48,7 +48,7 @@ public final class SpanImpl extends Span implements Element { private static final Logger logger = Logger.getLogger(Tracer.class.getName()); - // The parent SpanId of this span. Null if this is a root. + // The parent SpanId of this span. Null if this is a root span. private final SpanId parentSpanId; // True if the parent is on a different process. private final boolean hasRemoteParent; @@ -60,13 +60,13 @@ public final class SpanImpl extends Span implements Element { private final String name; // The clock used to get the time. private final Clock clock; - // The time converter used to convert nano time to Timestamp. This is needed because java has - // milliseconds granularity for Timestamp and tracing events are recorded more often. + // The time converter used to convert nano time to Timestamp. This is needed because Java has + // millisecond granularity for Timestamp and tracing events are recorded more often. private final TimestampConverter timestampConverter; // The start time of the span. Set when the span is created iff the RECORD_EVENTS options is // set, otherwise 0. private final long startNanoTime; - // Set of recorded attributes. DO NOT CALL any other method that change the ordering of events. + // Set of recorded attributes. DO NOT CALL any other method that changes the ordering of events. @GuardedBy("this") private AttributesWithCapacity attributes; // List of recorded annotations. @@ -75,7 +75,7 @@ public final class SpanImpl extends Span implements Element { // List of recorded network events. @GuardedBy("this") private TraceEvents> networkEvents; - // List of recorded links. + // List of recorded links to parent and child spans. @GuardedBy("this") private TraceEvents links; // The status of the span. Set when the span is ended iff the RECORD_EVENTS options is set. @@ -94,9 +94,20 @@ public final class SpanImpl extends Span implements Element { private SpanImpl prev = null; /** - * Creates and starts a span with the given configuration. TimestampConverter is null if the - * {@code Span} is a root span or the parent is not sampled. If the parent is sampled we should - * use the same converter to ensure ordering between tracing events. + * Creates and starts a span with the given configuration. + * + * @param context supplies the trace_id and span_id for the newly started span. + * @param options the options for the new span, importantly Options.RECORD_EVENTS. + * @param name the displayed name for the new span. + * @param parentSpanId the span_id of the parent span, or null if the new span is a root span. + * @param hasRemoteParent true if the parent span is in another process. + * @param traceParams trace parameters like sampler and probability. + * @param startEndHandler handler called when the span starts and ends. + * @param timestampConverter null if the span is a root span or the parent is not sampled. If the + * parent is sampled, we should use the same converter to ensure ordering between tracing + * events. + * @param clock the clock used to get the time. + * @return a new and started span. */ @VisibleForTesting public static SpanImpl startSpan( @@ -149,8 +160,8 @@ public Status getStatus() { } /** - * Returns the end nano time (see {@link System#nanoTime()}). If the current {@code Span} is - * not ended then returns {@link Clock#nowNanos()}. + * Returns the end nano time (see {@link System#nanoTime()}). If the current {@code Span} is not + * ended then returns {@link Clock#nowNanos()}. * * @return the end nano time. */ From 67683b6c8c3a6b675de8a96dbb3f00ca420c1758 Mon Sep 17 00:00:00 2001 From: easy Date: Mon, 26 Jun 2017 19:00:36 +1000 Subject: [PATCH 0196/1581] Make :jmh work by removing duplicate package-info class. (#390) The implementation should be internal by default. --- .../io/opencensus/internal/package-info.java | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 impl_core/src/main/java/io/opencensus/internal/package-info.java diff --git a/impl_core/src/main/java/io/opencensus/internal/package-info.java b/impl_core/src/main/java/io/opencensus/internal/package-info.java deleted file mode 100644 index a9f9486497..0000000000 --- a/impl_core/src/main/java/io/opencensus/internal/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Interfaces and implementations that are internal to OpenCensus. - * - *

            All the content under this package and its subpackages are considered annotated with {@link - * io.opencensus.common.Internal}. - */ -@io.opencensus.common.Internal -package io.opencensus.internal; From 7e0539486bd98828cd852feb877360f2a8424e73 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 26 Jun 2017 21:41:47 +0200 Subject: [PATCH 0197/1581] Added package-info.java to the package containing the relocated deps. --- .../contrib/agent/deps/package-info.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 contrib/agent/src/main/java/io/opencensus/contrib/agent/deps/package-info.java diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/deps/package-info.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/deps/package-info.java new file mode 100644 index 0000000000..214492f4c7 --- /dev/null +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/deps/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent.deps; + +/** + * Contains third party packages, such as Byte Buddy, Guava, etc., relocated here by the build + * process to avoid any conflicts of the agent's classes with the app's classes, which are loaded + * by the same classloader (the system classloader). + */ From f5fc855d68a5cfb376224f825670918d5f072163 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 26 Jun 2017 22:06:17 +0200 Subject: [PATCH 0198/1581] Reserve a package for classes that need to be loaded by the boostrap classloader. --- .../contrib/agent/bootstrap/package-info.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/package-info.java diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/package-info.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/package-info.java new file mode 100644 index 0000000000..748c7f78fc --- /dev/null +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent.bootstrap; + +/** + * Contains classes that need to be loaded by the bootstrap classloader because they are used from + * classes loaded by the bootstrap classloader. + */ From d27b708a36420ad9a16f55c088f1f5bcbefc3267 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 26 Jun 2017 15:42:21 -0700 Subject: [PATCH 0199/1581] Add TODOs. --- core/src/main/java/io/opencensus/stats/StatsComponent.java | 2 ++ core/src/main/java/io/opencensus/stats/StatsRecorder.java | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/core/src/main/java/io/opencensus/stats/StatsComponent.java b/core/src/main/java/io/opencensus/stats/StatsComponent.java index 08cbd44f65..fbf609e17d 100644 --- a/core/src/main/java/io/opencensus/stats/StatsComponent.java +++ b/core/src/main/java/io/opencensus/stats/StatsComponent.java @@ -19,6 +19,7 @@ * *

            All objects returned by methods on {@code StatsComponent} are cacheable. */ +// TODO(sebright): Add a no-op StatsComponent. public abstract class StatsComponent { /** Returns the default {@link ViewManager}. */ public abstract ViewManager getViewManager(); @@ -27,5 +28,6 @@ public abstract class StatsComponent { public abstract StatsRecorder getStatsRecorder(); /** Returns the default {@link StatsContextFactory}. */ + // TODO(sebright): Remove this method once StatsContext is replaced by TagContext. abstract StatsContextFactory getStatsContextFactory(); } diff --git a/core/src/main/java/io/opencensus/stats/StatsRecorder.java b/core/src/main/java/io/opencensus/stats/StatsRecorder.java index aad28f02f1..fc183754bb 100644 --- a/core/src/main/java/io/opencensus/stats/StatsRecorder.java +++ b/core/src/main/java/io/opencensus/stats/StatsRecorder.java @@ -15,6 +15,12 @@ /** Provides methods to record stats against tags. */ public abstract class StatsRecorder { + // // TODO(sebright): Add a "record" method for implicit propagation: + // + // public void record(MeasurementMap measurementValues) { + // record(getCurrentTagContext(), measurementValues); + // } + /** * Records a set of measurements with a set of tags. * From 91304d75e249e3599db80cdac8d6a864e466fb0a Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 27 Jun 2017 17:04:55 -0700 Subject: [PATCH 0200/1581] Change RpcMeasurementConstants.RPC_STATUS to "canonical_status". --- .../main/java/io/opencensus/stats/RpcMeasurementConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java b/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java index 42ac4e448f..c015e17cb1 100644 --- a/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java @@ -24,7 +24,7 @@ public final class RpcMeasurementConstants { // Rpc tag keys. - public static final TagKey RPC_STATUS = TagKey.create("OpStatus"); + public static final TagKey RPC_STATUS = TagKey.create("canonical_status"); public static final TagKey RPC_CLIENT_METHOD = TagKey.create("method"); public static final TagKey RPC_SERVER_METHOD = TagKey.create("method"); From 286ab5aedb270eb516a2ce761eb6ed956bba1ff8 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 28 Jun 2017 13:33:44 +0200 Subject: [PATCH 0201/1581] Add compareTo to Timestamp. (#392) * Add compareTo to Timestamp. * Update Timestamp.java Javadoc edits. * Update Timestamp.java Fix the long line that broke the appveyor build. * Fix comments --- .../java/io/opencensus/common/Timestamp.java | 23 ++++++++++++++++++- .../io/opencensus/common/TimestampTest.java | 17 +++++++++++++- findbugs-exclude.xml | 7 ++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/io/opencensus/common/Timestamp.java b/api/src/main/java/io/opencensus/common/Timestamp.java index 68b5efc788..5cdfeea0c5 100644 --- a/api/src/main/java/io/opencensus/common/Timestamp.java +++ b/api/src/main/java/io/opencensus/common/Timestamp.java @@ -33,7 +33,7 @@ */ @Immutable @AutoValue -public abstract class Timestamp { +public abstract class Timestamp implements Comparable { private static final Timestamp EPOCH = new AutoValue_Timestamp(0, 0); Timestamp() {} @@ -130,6 +130,27 @@ public Duration subtractTimestamp(Timestamp timestamp) { return Duration.create(durationSeconds, durationNanos); } + /** + * Compares this {@code Timestamp} to the specified {@code Timestamp}. + * + * @param otherTimestamp the other {@code Timestamp} to compare to, not {@code null}. + * @return the comparator value: zero if equal, negative if this timestamp happens + * before otherTimestamp, positive if after. + * @throws NullPointerException if otherTimestamp is {@code null}. + */ + @Override + public int compareTo(Timestamp otherTimestamp) { + int cmp = compareLong(getSeconds(), otherTimestamp.getSeconds()); + if (cmp != 0) { + return cmp; + } + return compareLong(getNanos(), otherTimestamp.getNanos()); + } + + private static int compareLong(long x, long y) { + return (x < y) ? -1 : ((x == y) ? 0 : 1); + } + // Returns a Timestamp with the specified duration added. private Timestamp plus(long secondsToAdd, long nanosToAdd) { if ((secondsToAdd | nanosToAdd) == 0) { diff --git a/api/src/test/java/io/opencensus/common/TimestampTest.java b/api/src/test/java/io/opencensus/common/TimestampTest.java index e384b5ca70..6936247e5e 100644 --- a/api/src/test/java/io/opencensus/common/TimestampTest.java +++ b/api/src/test/java/io/opencensus/common/TimestampTest.java @@ -135,7 +135,22 @@ public void timestampSubtractTimestamp_NegativeResult() { } @Test - public void testTimestampEqual() { + public void timestamp_CompareTo() { + assertThat(Timestamp.create(0, 0).compareTo(Timestamp.create(0, 0))).isEqualTo(0); + assertThat(Timestamp.create(24, 42).compareTo(Timestamp.create(24, 42))).isEqualTo(0); + assertThat(Timestamp.create(-24, 42).compareTo(Timestamp.create(-24, 42))).isEqualTo(0); + assertThat(Timestamp.create(25, 42).compareTo(Timestamp.create(24, 42))).isEqualTo(1); + assertThat(Timestamp.create(24, 45).compareTo(Timestamp.create(24, 42))).isEqualTo(1); + assertThat(Timestamp.create(24, 42).compareTo(Timestamp.create(25, 42))).isEqualTo(-1); + assertThat(Timestamp.create(24, 42).compareTo(Timestamp.create(24, 45))).isEqualTo(-1); + assertThat(Timestamp.create(-25, 42).compareTo(Timestamp.create(-24, 42))).isEqualTo(-1); + assertThat(Timestamp.create(-24, 45).compareTo(Timestamp.create(-24, 42))).isEqualTo(1); + assertThat(Timestamp.create(-24, 42).compareTo(Timestamp.create(-25, 42))).isEqualTo(1); + assertThat(Timestamp.create(-24, 42).compareTo(Timestamp.create(-24, 45))).isEqualTo(-1); + } + + @Test + public void timestamp_Equal() { // Positive tests. assertThat(Timestamp.create(0, 0)).isEqualTo(Timestamp.create(0, 0)); assertThat(Timestamp.create(24, 42)).isEqualTo(Timestamp.create(24, 42)); diff --git a/findbugs-exclude.xml b/findbugs-exclude.xml index 8444032a0d..119f823e0d 100644 --- a/findbugs-exclude.xml +++ b/findbugs-exclude.xml @@ -5,4 +5,11 @@ + + + + + + + From f69cfce7c40980dc5d915650d40d826892ac9761 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 29 Jun 2017 22:52:56 +0200 Subject: [PATCH 0202/1581] Package the classes that need to be loaded by the bootstrap classes in a separate JAR file, bootstrap.jar, and bundle that with the agent's JAR file. --- contrib/agent/build.gradle | 41 +++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index f420c89fc2..72478a07e2 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -9,6 +9,16 @@ targetCompatibility = 1.7 def agentPackage = 'io.opencensus.contrib.agent' def agentMainClass = "${agentPackage}.AgentMain" + +// The package containing the classes that need to be loaded by the bootstrap classloader because +// they are used from classes loaded by the bootstrap classloader. +def agentBootstrapPackage = "${agentPackage}.bootstrap" +def agentBootstrapPackageDir = agentBootstrapPackage.replace('.', '/') + '/' +def agentBootstrapClasses = agentBootstrapPackageDir + '**' + +// The package to which which we relocate all third party packages. This avoids any conflicts of +// the agent's classes with the app's classes, which are loaded by the same classloader (the system +// classloader). def agentRepackaged = "${agentPackage}.deps" dependencies { @@ -30,6 +40,19 @@ jar { } } +// Create bootstrap.jar containing the classes that need to be loaded by the bootstrap +// classloader. +task bootstrapJar(type: Jar) { + // Output to 'bootstrap.jar'. + baseName = 'bootstrap' + version = null + + from sourceSets.main.output + include agentBootstrapClasses +} + +shadowJar.dependsOn bootstrapJar + // Bundle the agent's classes and dependencies into a single, self-contained JAR file. shadowJar { // Output to opencensus-agent-VERSION.jar. @@ -43,21 +66,37 @@ shadowJar { // Exclude cruft which still snuck in. exclude 'META-INF/maven/**' + exclude agentBootstrapClasses // Relocate third party packages to avoid any conflicts of the agent's classes with the app's // classes, which are loaded by the same classloader (the system classloader). relocate 'net.bytebuddy', agentRepackaged + '.bytebuddy' doLast { - // Assert that there's nothing unexpected left outside of ${agentPackage}. def agentPackageDir = agentPackage.replace('.', '/') + '/' + def agentBootstrapJar = agentPackageDir + 'bootstrap.jar' + // Bundle bootstrap.jar. + ant.jar(update: 'true', destfile: shadowJar.archivePath) { + mappedresources { + fileset(file: bootstrapJar.archivePath) + globmapper(from: '*', to: agentBootstrapJar) + } + } + + // Assert that there's nothing obviously wrong with the JAR's contents. new java.util.zip.ZipFile(shadowJar.archivePath).withCloseable { + // Must have bundled the bootstrap.jar. + assert it.entries().any { it.name = agentBootstrapJar } + it.entries().each { + // Must not contain anything outside of ${agentPackage}, except for the manifest. assert it.name.startsWith(agentPackageDir) || (it.isDirectory() && agentPackageDir.startsWith(it.name)) || it.name == 'META-INF/' || it.name == 'META-INF/MANIFEST.MF' + // Also, should not have the bootstrap classes. + assert !it.name.startsWith(agentBootstrapPackageDir) } } } From 91f5b2a51bfc7820354d718b5893b1053333c2c5 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 01:14:29 +0200 Subject: [PATCH 0203/1581] Updated build status indicators from top-level readme. --- contrib/agent/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/agent/README.md b/contrib/agent/README.md index 59125cadaf..787a2c250d 100644 --- a/contrib/agent/README.md +++ b/contrib/agent/README.md @@ -1,6 +1,6 @@ # OpenCensus Agent for Java -[![Build Status](https://travis-ci.org/census-instrumentation/instrumentation-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/instrumentation-java) [![Build status](https://ci.appveyor.com/api/projects/status/v5dbthkucuewsu33/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/instrumentation-java/branch/master) +[![Build Status](https://travis-ci.org/census-instrumentation/opencensus-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/opencensus-java) [![Build status](https://ci.appveyor.com/api/projects/status/hxthmpkxar4jq4be/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/opencensus-java/branch/master) The *OpenCensus Agent for Java* collects and sends latency data about your Java process to OpenCensus backends such as Zipkin, Stackdriver Trace, etc. for analysis and visualization. From 552da72391d8b628a3ff1212d9bda34a0274a51e Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 12:29:01 +0200 Subject: [PATCH 0204/1581] Added experimental support for legacy Java 1.6 JVMs through Retrolambda. --- contrib/agent/build.gradle | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 72478a07e2..449d889006 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -1,11 +1,17 @@ plugins { id 'com.github.johnrengelman.shadow' version '2.0.0' + id 'me.tatarka.retrolambda' version '3.6.0' } description = 'OpenCensus Agent' -sourceCompatibility = 1.7 -targetCompatibility = 1.7 +sourceCompatibility = JavaVersion.VERSION_1_7 +targetCompatibility = JavaVersion.VERSION_1_7 + +// Experimental support for legacy Java 1.6 JVMs. +retrolambda { + javaVersion JavaVersion.VERSION_1_6 +} def agentPackage = 'io.opencensus.contrib.agent' def agentMainClass = "${agentPackage}.AgentMain" @@ -24,7 +30,7 @@ def agentRepackaged = "${agentPackage}.deps" dependencies { compile group: 'net.bytebuddy', name: 'byte-buddy', version: '1.7.1' - signature 'org.codehaus.mojo.signature:java17:+@signature' + signature 'org.codehaus.mojo.signature:java16:+@signature' } jar { @@ -35,8 +41,8 @@ jar { attributes 'Can-Retransform-Classes': true // Let the java plugin use the overridden values instead of the root project's values. - attributes 'Source-Compatibility': sourceCompatibility - attributes 'Target-Compatibility': targetCompatibility + attributes 'Source-Compatibility': JavaVersion.VERSION_1_6 + attributes 'Target-Compatibility': JavaVersion.VERSION_1_6 } } From a9689033f4536e6bad8e398a1c6605fb1b38cbe7 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 13:58:27 +0200 Subject: [PATCH 0205/1581] Mention that Animalsniffer is used. --- contrib/agent/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 449d889006..79adfadb9c 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -8,7 +8,8 @@ description = 'OpenCensus Agent' sourceCompatibility = JavaVersion.VERSION_1_7 targetCompatibility = JavaVersion.VERSION_1_7 -// Experimental support for legacy Java 1.6 JVMs. +// Experimental support for legacy Java 1.6 JVMs. Animalsniffer (applied by the root project) is +// used to check for unexpected references to later APIs. Also see dependencies/signature. retrolambda { javaVersion JavaVersion.VERSION_1_6 } From c433da68f1fba73c896903a9b9d445a95fedb6b5 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 14:01:35 +0200 Subject: [PATCH 0206/1581] Retrolambda itself wants JDK 8. --- contrib/agent/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 79adfadb9c..f4147ca434 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -12,6 +12,7 @@ targetCompatibility = JavaVersion.VERSION_1_7 // used to check for unexpected references to later APIs. Also see dependencies/signature. retrolambda { javaVersion JavaVersion.VERSION_1_6 + jdk '/usr/lib/jvm/java-8-oracle' } def agentPackage = 'io.opencensus.contrib.agent' From 459aaa7020867929807429440ca1358cb603752a Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 14:17:27 +0200 Subject: [PATCH 0207/1581] Get the Java 8 home from jdk_switcher instead of hardcoding the path. --- .travis.yml | 1 + contrib/agent/build.gradle | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d7ae79caae..fcab102a03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,6 +37,7 @@ script: "CHECK_GIT_HISTORY") python check-git-history.py ;; "BUILD") + export JAVA8_HOME=`jdk_switcher home oraclejdk8` ; ./gradlew clean assemble --stacktrace ; case "$TRAVIS_JDK_VERSION" in "oraclejdk8") diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index f4147ca434..79adfadb9c 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -12,7 +12,6 @@ targetCompatibility = JavaVersion.VERSION_1_7 // used to check for unexpected references to later APIs. Also see dependencies/signature. retrolambda { javaVersion JavaVersion.VERSION_1_6 - jdk '/usr/lib/jvm/java-8-oracle' } def agentPackage = 'io.opencensus.contrib.agent' From 7ac5f413d93580f5c667f3893649059ab6680d6f Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 14:25:01 +0200 Subject: [PATCH 0208/1581] Mention JAVA8_HOME, too. --- contrib/agent/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 79adfadb9c..d2d5fd69a6 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -10,6 +10,7 @@ targetCompatibility = JavaVersion.VERSION_1_7 // Experimental support for legacy Java 1.6 JVMs. Animalsniffer (applied by the root project) is // used to check for unexpected references to later APIs. Also see dependencies/signature. +// Retrolambda itself requires JDK 8, which it finds at $JAVA8_HOME. retrolambda { javaVersion JavaVersion.VERSION_1_6 } From 27df8d6c6690789c025ece971a11a4b867395782 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 14:55:17 +0200 Subject: [PATCH 0209/1581] Add a dependency on Guava and relocate and bundle it properly. --- contrib/agent/build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 72478a07e2..41b4b0b137 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -22,6 +22,7 @@ def agentBootstrapClasses = agentBootstrapPackageDir + '**' def agentRepackaged = "${agentPackage}.deps" dependencies { + compile libraries.guava compile group: 'net.bytebuddy', name: 'byte-buddy', version: '1.7.1' signature 'org.codehaus.mojo.signature:java17:+@signature' @@ -62,6 +63,7 @@ shadowJar { // Include only the following dependencies (excluding transitive dependencies). dependencies { include(dependency('net.bytebuddy:byte-buddy')) + include(dependency(libraries.guava)) } // Exclude cruft which still snuck in. @@ -70,7 +72,11 @@ shadowJar { // Relocate third party packages to avoid any conflicts of the agent's classes with the app's // classes, which are loaded by the same classloader (the system classloader). + // Byte Buddy: relocate 'net.bytebuddy', agentRepackaged + '.bytebuddy' + // Guava: + relocate 'com.google.common', agentRepackaged + '.guava' + relocate 'com.google.thirdparty.publicsuffix', agentRepackaged + '.publicsuffix' doLast { def agentPackageDir = agentPackage.replace('.', '/') + '/' @@ -103,3 +109,5 @@ shadowJar { } jar.finalizedBy shadowJar + +// TODO(stschmidt): Proguard-shrink the agent JAR. From d07f8d2d912089086d6f1962f4ff1f28298a74be Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 17:08:03 +0200 Subject: [PATCH 0210/1581] Append bootstrap.jar to the bootstrap classloader search path. --- .../opencensus/contrib/agent/AgentMain.java | 6 ++ .../opencensus/contrib/agent/Resources.java | 74 +++++++++++++++++++ .../contrib/agent/ResourcesTest.java | 58 +++++++++++++++ .../contrib/agent/some_resource.txt | 1 + 4 files changed, 139 insertions(+) create mode 100644 contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java create mode 100644 contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java create mode 100644 contrib/agent/src/test/resources/io/opencensus/contrib/agent/some_resource.txt diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index 4e62697f0f..a64f9a8c19 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -16,6 +16,7 @@ import static net.bytebuddy.matcher.ElementMatchers.none; import java.lang.instrument.Instrumentation; +import java.util.jar.JarFile; import java.util.logging.Logger; import net.bytebuddy.agent.builder.AgentBuilder; @@ -53,6 +54,11 @@ private AgentMain() { public static void premain(String agentArgs, Instrumentation inst) throws Exception { logger.info("Initializing."); + // The classes in bootstrap.jar will be referenced from classes loaded by the bootstrap + // classloader. Thus, these classes have to be loaded by the bootstrap classloader, too. + inst.appendToBootstrapClassLoaderSearch( + new JarFile(Resources.getResourceAsTempFile("bootstrap.jar"))); + AgentBuilder agentBuilder = new AgentBuilder.Default() .disableClassFormatChanges() .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java new file mode 100644 index 0000000000..21668ea0bc --- /dev/null +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java @@ -0,0 +1,74 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Strings; +import com.google.common.io.ByteStreams; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Helper methods for working with resources. + */ +final class Resources { + + /** + * Returns a resource of the given name as a temporary file. + * + * @param resourceName name of the resource + * @return a temporary {@link File} containing a copy of the resource + * @throws FileNotFoundException if no resource of the given name is found + */ + static File getResourceAsTempFile(String resourceName) throws IOException { + checkArgument(!Strings.isNullOrEmpty(resourceName)); + + File file = File.createTempFile(resourceName, ".tmp"); + try (OutputStream os = new FileOutputStream(file)) { + getResourceAsTempFile(resourceName, file, os); + return file; + } + } + + @VisibleForTesting + static void getResourceAsTempFile(String resourceName, File file, OutputStream os) + throws IOException { + checkArgument(!Strings.isNullOrEmpty(resourceName)); + checkNotNull(file); + checkNotNull(os); + + try (InputStream is = getResourceAsStream(resourceName)) { + file.deleteOnExit(); + ByteStreams.copy(is, os); + } + } + + private static InputStream getResourceAsStream(String resourceName) throws FileNotFoundException { + checkArgument(!Strings.isNullOrEmpty(resourceName)); + + InputStream is = Resources.class.getResourceAsStream(resourceName); + if (is == null) { + throw new FileNotFoundException( + "Cannot find resource '" + resourceName + "' on the class path."); + } + return is; + } +} diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java new file mode 100644 index 0000000000..99dbb00395 --- /dev/null +++ b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import com.google.common.base.Charsets; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Unit tests for {@link Resources}. + */ +@RunWith(JUnit4.class) +public class ResourcesTest { + + @Rule + public final ExpectedException exception = ExpectedException.none(); + + @Test + public void getResourceAsTempFile() throws IOException { + File mockFile = mock(File.class); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + + Resources.getResourceAsTempFile("some_resource.txt", mockFile, bytes); + + verify(mockFile).deleteOnExit(); + assertThat(bytes.toString(Charsets.UTF_8.name())).isEqualTo("A resource!"); + } + + @Test + public void getResourceAsTempFile_Missing() throws IOException { + exception.expect(FileNotFoundException.class); + + Resources.getResourceAsTempFile("missing_resource.txt", + mock(File.class), new ByteArrayOutputStream()); + } +} diff --git a/contrib/agent/src/test/resources/io/opencensus/contrib/agent/some_resource.txt b/contrib/agent/src/test/resources/io/opencensus/contrib/agent/some_resource.txt new file mode 100644 index 0000000000..07319bbd85 --- /dev/null +++ b/contrib/agent/src/test/resources/io/opencensus/contrib/agent/some_resource.txt @@ -0,0 +1 @@ +A resource! \ No newline at end of file From 6dedf0bf9c7603343ad1cacb7b2dad6de9dc8585 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 17:13:47 +0200 Subject: [PATCH 0211/1581] checkNotNull required param. --- .../src/main/java/io/opencensus/contrib/agent/AgentMain.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index a64f9a8c19..03d617dde7 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -13,6 +13,7 @@ package io.opencensus.contrib.agent; +import static com.google.common.base.Preconditions.checkNotNull; import static net.bytebuddy.matcher.ElementMatchers.none; import java.lang.instrument.Instrumentation; @@ -52,6 +53,8 @@ private AgentMain() { * @see java.lang.instrument */ public static void premain(String agentArgs, Instrumentation inst) throws Exception { + checkNotNull(inst); + logger.info("Initializing."); // The classes in bootstrap.jar will be referenced from classes loaded by the bootstrap From 66c7cde319e6887a4e5d51bb33c6303ba0938c3b Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 17:24:37 +0200 Subject: [PATCH 0212/1581] Doc @throws IOException. --- .../src/main/java/io/opencensus/contrib/agent/Resources.java | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java index 21668ea0bc..0ab5bced50 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java @@ -37,6 +37,7 @@ final class Resources { * @param resourceName name of the resource * @return a temporary {@link File} containing a copy of the resource * @throws FileNotFoundException if no resource of the given name is found + * @throws IOException if an I/O error occurs */ static File getResourceAsTempFile(String resourceName) throws IOException { checkArgument(!Strings.isNullOrEmpty(resourceName)); From e1b8f060cb29d7deec0b4a536e7e438dc9f323b1 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 17:51:51 +0200 Subject: [PATCH 0213/1581] Test write failure. --- .../contrib/agent/ResourcesTest.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java index 99dbb00395..7915da9932 100644 --- a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java +++ b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java @@ -14,6 +14,7 @@ package io.opencensus.contrib.agent; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -22,11 +23,14 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.OutputStream; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.Matchers; +import org.mockito.stubbing.Stubber; /** * Unit tests for {@link Resources}. @@ -55,4 +59,22 @@ public void getResourceAsTempFile_Missing() throws IOException { Resources.getResourceAsTempFile("missing_resource.txt", mock(File.class), new ByteArrayOutputStream()); } + + @Test + public void getResourceAsTempFile_WriteFailure() throws IOException { + exception.expect(IOException.class); + exception.expectMessage("denied"); + + File mockFile = mock(File.class); + OutputStream outputStream = new OutputStream() { + @Override + public void write(int b) throws IOException { + throw new IOException("denied"); + } + }; + + Resources.getResourceAsTempFile("some_resource.txt", mockFile, outputStream); + + verify(mockFile).deleteOnExit(); + } } From a6d1bc874da9e64550b9f69686652fe5c871c213 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 17:59:03 +0200 Subject: [PATCH 0214/1581] Cleanup imports. --- .../test/java/io/opencensus/contrib/agent/ResourcesTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java index 7915da9932..39f393479b 100644 --- a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java +++ b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java @@ -14,7 +14,6 @@ package io.opencensus.contrib.agent; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -29,8 +28,6 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import org.mockito.Matchers; -import org.mockito.stubbing.Stubber; /** * Unit tests for {@link Resources}. From bc90465a81721e6e4f4b9e4f7ac1342ff2fa024f Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 18:25:51 +0200 Subject: [PATCH 0215/1581] Fix broken test. --- .../java/io/opencensus/contrib/agent/ResourcesTest.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java index 39f393479b..478c7e5a80 100644 --- a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java +++ b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java @@ -59,9 +59,6 @@ public void getResourceAsTempFile_Missing() throws IOException { @Test public void getResourceAsTempFile_WriteFailure() throws IOException { - exception.expect(IOException.class); - exception.expectMessage("denied"); - File mockFile = mock(File.class); OutputStream outputStream = new OutputStream() { @Override @@ -70,8 +67,9 @@ public void write(int b) throws IOException { } }; - Resources.getResourceAsTempFile("some_resource.txt", mockFile, outputStream); + exception.expect(IOException.class); + exception.expectMessage("denied"); - verify(mockFile).deleteOnExit(); + Resources.getResourceAsTempFile("some_resource.txt", mockFile, outputStream); } } From c893f7169368769c1d10071a3f1f2e790772cc1b Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 30 Jun 2017 18:34:08 +0200 Subject: [PATCH 0216/1581] Cosmetics. --- .../test/java/io/opencensus/contrib/agent/ResourcesTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java index 478c7e5a80..9eb33da5be 100644 --- a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java +++ b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java @@ -59,8 +59,7 @@ public void getResourceAsTempFile_Missing() throws IOException { @Test public void getResourceAsTempFile_WriteFailure() throws IOException { - File mockFile = mock(File.class); - OutputStream outputStream = new OutputStream() { + OutputStream badOutputStream = new OutputStream() { @Override public void write(int b) throws IOException { throw new IOException("denied"); @@ -70,6 +69,6 @@ public void write(int b) throws IOException { exception.expect(IOException.class); exception.expectMessage("denied"); - Resources.getResourceAsTempFile("some_resource.txt", mockFile, outputStream); + Resources.getResourceAsTempFile("some_resource.txt", mock(File.class), badOutputStream); } } From 07d69996286f6800be2d3977571cac0a80bb4e7c Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 30 Jun 2017 11:12:56 -0700 Subject: [PATCH 0217/1581] Change API to remove the "Option" logic and keep only Builder. (#380) --- .../java/io/opencensus/trace/SpanBuilder.java | 111 ++++------ .../main/java/io/opencensus/trace/Tracer.java | 67 +++--- .../trace/base/StartSpanOptions.java | 122 ----------- .../trace/internal/SpanFactory.java | 47 ----- .../io/opencensus/trace/SpanBuilderTest.java | 179 ---------------- .../java/io/opencensus/trace/TracerTest.java | 137 ++++--------- .../trace/base/StartSpanOptionsTest.java | 114 ----------- ...ordTraceEventsNonSampledSpanBenchmark.java | 4 +- ...RecordTraceEventsSampledSpanBenchmark.java | 4 +- .../trace/StartEndSpanBenchmark.java | 9 +- .../trace/MultiSpansContextTracing.java | 2 +- .../trace/MultiSpansScopedTracing.java | 2 +- .../io/opencensus/trace/SpanBuilderImpl.java | 192 ++++++++++++++++++ .../io/opencensus/trace/SpanFactoryImpl.java | 137 ------------- .../opencensus/trace/StartEndHandlerImpl.java | 3 +- .../java/io/opencensus/trace/TracerImpl.java | 18 +- .../trace/export/ExportComponentImpl.java | 8 +- .../trace/export/SampledSpanStoreImpl.java | 9 +- .../trace/internal/RandomHandler.java | 8 +- ...ImplTest.java => SpanBuilderImplTest.java} | 70 +++---- .../io/opencensus/trace/TracerImplTest.java | 55 +++++ 21 files changed, 421 insertions(+), 877 deletions(-) delete mode 100644 api/src/main/java/io/opencensus/trace/base/StartSpanOptions.java delete mode 100644 api/src/main/java/io/opencensus/trace/internal/SpanFactory.java delete mode 100644 api/src/test/java/io/opencensus/trace/SpanBuilderTest.java delete mode 100644 api/src/test/java/io/opencensus/trace/base/StartSpanOptionsTest.java create mode 100644 impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java delete mode 100644 impl_core/src/main/java/io/opencensus/trace/SpanFactoryImpl.java rename impl_core/src/test/java/io/opencensus/trace/{SpanFactoryImplTest.java => SpanBuilderImplTest.java} (68%) create mode 100644 impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java diff --git a/api/src/main/java/io/opencensus/trace/SpanBuilder.java b/api/src/main/java/io/opencensus/trace/SpanBuilder.java index 782248baac..f573d9a65c 100644 --- a/api/src/main/java/io/opencensus/trace/SpanBuilder.java +++ b/api/src/main/java/io/opencensus/trace/SpanBuilder.java @@ -13,11 +13,11 @@ package io.opencensus.trace; +import static com.google.common.base.Preconditions.checkNotNull; + import io.opencensus.common.NonThrowingCloseable; import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.Sampler; -import io.opencensus.trace.base.StartSpanOptions; -import io.opencensus.trace.internal.SpanFactory; import java.util.List; import javax.annotation.Nullable; @@ -102,34 +102,15 @@ *

            If your Java version is less than Java SE 7, see {@link SpanBuilder#startSpan} and {@link * SpanBuilder#startScopedSpan} for usage examples. */ -public final class SpanBuilder { - private final SpanFactory spanFactory; - private final String name; - private final StartSpanOptions.Builder startSpanOptionsBuilder = StartSpanOptions.builder(); - private Span parentSpan; - private SpanContext parentSpanContext; - private boolean remoteParent; - - static SpanBuilder builder(SpanFactory spanFactory, Span parentSpan, String name) { - return new SpanBuilder(spanFactory, parentSpan, null, false, name); - } - - static SpanBuilder builderWithRemoteParent( - SpanFactory spanFactory, SpanContext parentSpanContext, String name) { - return new SpanBuilder(spanFactory, null, parentSpanContext, true, name); - } +public abstract class SpanBuilder { /** - * Sets the {@link Sampler} to use. If a {@code null} value is passed, the implementation will - * provide a default. + * Sets the {@link Sampler} to use. If not set, the implementation will provide a default. * * @param sampler The {@code Sampler} to use when determining sampling for a {@code Span}. * @return this. */ - public SpanBuilder setSampler(@Nullable Sampler sampler) { - startSpanOptionsBuilder.setSampler(sampler); - return this; - } + public abstract SpanBuilder setSampler(Sampler sampler); /** * Sets the {@code List} of parent links. Links are used to link {@link Span}s in different @@ -138,11 +119,9 @@ public SpanBuilder setSampler(@Nullable Sampler sampler) { * * @param parentLinks New links to be added. * @return this. + * @throws NullPointerException if {@code parentLinks} is {@code null}. */ - public SpanBuilder setParentLinks(@Nullable List parentLinks) { - startSpanOptionsBuilder.setParentLinks(parentLinks); - return this; - } + public abstract SpanBuilder setParentLinks(List parentLinks); /** * Sets the option {@link Span.Options#RECORD_EVENTS} for the newly created {@code Span}. If not @@ -151,27 +130,7 @@ public SpanBuilder setParentLinks(@Nullable List parentLinks) { * @param recordEvents New value determining if this {@code Span} should have events recorded. * @return this. */ - public SpanBuilder setRecordEvents(boolean recordEvents) { - startSpanOptionsBuilder.setRecordEvents(recordEvents); - return this; - } - - /** - * If called this will force the newly created {@code Span} to be a root span. As a consequence, - * any parent specified (or inherited from the Context) will be ignored (N.B. does not apply to - * linked parents set through {@link #setParentLinks}). - * - *

            This is useful when {@link Tracer#spanBuilder(String)} is used and the newly created {@code - * Span} needs to be decoupled from the parent {@code Span}. - * - * @return this. - */ - public SpanBuilder becomeRoot() { - parentSpan = null; - parentSpanContext = null; - remoteParent = false; - return this; - } + public abstract SpanBuilder setRecordEvents(boolean recordEvents); /** * Starts a new {@link Span}. @@ -201,9 +160,7 @@ public SpanBuilder becomeRoot() { * * @return the newly created {@code Span}. */ - public Span startSpan() { - return start(); - } + public abstract Span startSpan(); // TODO(bdrutu): Add error_prone annotation @MustBeClosed when the 2.0.16 jar is fixed. /** @@ -260,28 +217,38 @@ public Span startSpan() { * @return an object that defines a scope where the newly created {@code Span} will be set to the * current Context. */ - public NonThrowingCloseable startScopedSpan() { - return new ScopedSpanHandle(start()); + public final NonThrowingCloseable startScopedSpan() { + return new ScopedSpanHandle(startSpan()); } - private SpanBuilder( - SpanFactory spanFactory, - @Nullable Span parentSpan, - @Nullable SpanContext parentSpanContext, - boolean remoteParent, - String name) { - this.parentSpan = parentSpan; - this.parentSpanContext = parentSpanContext; - this.remoteParent = remoteParent; - this.name = name; - this.spanFactory = spanFactory; - } + static final class NoopSpanBuilder extends SpanBuilder { + NoopSpanBuilder(@Nullable Span parentSpan, String name) { + checkNotNull(name, "name"); + } + + NoopSpanBuilder(SpanContext remoteParentSpanContext, String name) { + checkNotNull(remoteParentSpanContext, "remoteParentSpanContext"); + checkNotNull(name, "name"); + } + + @Override + public Span startSpan() { + return BlankSpan.INSTANCE; + } + + @Override + public SpanBuilder setSampler(@Nullable Sampler sampler) { + return this; + } + + @Override + public SpanBuilder setParentLinks(List parentLinks) { + return this; + } - // Utility method to start a Span. - private Span start() { - return remoteParent - ? spanFactory.startSpanWithRemoteParent( - parentSpanContext, name, startSpanOptionsBuilder.build()) - : spanFactory.startSpan(parentSpan, name, startSpanOptionsBuilder.build()); + @Override + public SpanBuilder setRecordEvents(boolean recordEvents) { + return this; + } } } diff --git a/api/src/main/java/io/opencensus/trace/Tracer.java b/api/src/main/java/io/opencensus/trace/Tracer.java index e6172bed85..ef5616a9fd 100644 --- a/api/src/main/java/io/opencensus/trace/Tracer.java +++ b/api/src/main/java/io/opencensus/trace/Tracer.java @@ -16,8 +16,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.trace.base.StartSpanOptions; -import io.opencensus.trace.internal.SpanFactory; import javax.annotation.Nullable; /** @@ -67,7 +65,6 @@ */ public abstract class Tracer { private static final NoopTracer noopTracer = new NoopTracer(); - private final SpanFactory spanFactory; /** * Returns the no-op implementation of the {@code Tracer}. @@ -142,7 +139,7 @@ public final Span getCurrentSpan() { * @param span The {@link Span} to be set to the current Context. * @return an object that defines a scope where the given {@link Span} will be set to the current * Context. - * @throws NullPointerException if span is null. + * @throws NullPointerException if {@code span} is null. */ public final NonThrowingCloseable withSpan(Span span) { return ContextUtils.withSpan(checkNotNull(span, "span")); @@ -150,7 +147,7 @@ public final NonThrowingCloseable withSpan(Span span) { /** * Returns a {@link SpanBuilder} to create and start a new child {@link Span} as a child of to the - * current {@code Span} if any, otherwise create a root Span with the default options. + * current {@code Span} if any, otherwise creates a root {@code Span}. * *

            See {@link SpanBuilder} for usage examples. * @@ -159,7 +156,7 @@ public final NonThrowingCloseable withSpan(Span span) { * * @param name The name of the returned Span. * @return a {@code SpanBuilder} to create and start a new {@code Span}. - * @throws NullPointerException if name is null. + * @throws NullPointerException if {@code name} is null. */ public final SpanBuilder spanBuilder(String name) { return spanBuilder(ContextUtils.getCurrentSpan(), name); @@ -167,64 +164,60 @@ public final SpanBuilder spanBuilder(String name) { /** * Returns a {@link SpanBuilder} to create and start a new child {@link Span} (or root if parent - * is null), with parent being the designated {@code Span}. + * is {@code null} or has an invalid {@link SpanContext}), with parent being the designated {@code + * Span}. * *

            See {@link SpanBuilder} for usage examples. * - *

            This must be used to create a {@code Span} when manual Context propagation is used. + *

            This must be used to create a {@code Span} when manual Context propagation is used + * OR when creating a root {@code Span} with a {@code null} parent. * * @param parent The parent of the returned Span. If null the {@code SpanBuilder} will build a * root {@code Span}. * @param name The name of the returned Span. * @return a {@code SpanBuilder} to create and start a new {@code Span}. - * @throws NullPointerException if name is null. + * @throws NullPointerException if {@code name} is null. */ - public final SpanBuilder spanBuilder(@Nullable Span parent, String name) { - return SpanBuilder.builder(spanFactory, parent, checkNotNull(name, "name")); - } + public abstract SpanBuilder spanBuilder(@Nullable Span parent, String name); /** * Returns a {@link SpanBuilder} to create and start a new child {@link Span} (or root if parent - * is null), with parent being the {@link Span} designated by the {@link SpanContext}. + * is an invalid {@link SpanContext}), with parent being the {@link Span} designated by the {@link + * SpanContext}. * *

            See {@link SpanBuilder} for usage examples. * *

            This must be used to create a {@code Span} when the parent is in a different process. * This is only intended for use by RPC systems or similar. * - * @param remoteParent The remote parent of the returned Span. + *

            If no {@link SpanContext} OR fail to parse the {@link SpanContext} on the server side, + * users must call this method with an {@link SpanContext#INVALID} remote parent {@code + * SpanContext}. + * + * @param remoteParentSpanContext The remote parent of the returned Span. * @param name The name of the returned Span. * @return a {@code SpanBuilder} to create and start a new {@code Span}. - * @throws NullPointerException if name is null. + * @throws NullPointerException if {@code name} or {@code remoteParentSpanContext} are null. */ - public final SpanBuilder spanBuilderWithRemoteParent( - @Nullable SpanContext remoteParent, String name) { - return SpanBuilder.builderWithRemoteParent( - spanFactory, remoteParent, checkNotNull(name, "name")); - } + public abstract SpanBuilder spanBuilderWithRemoteParent( + SpanContext remoteParentSpanContext, String name); // No-Op implementation of the Tracer. private static final class NoopTracer extends Tracer { - private NoopTracer() { - super(new NoopSpanFactory()); - } - // No-op implementation of the SpanFactory - private static final class NoopSpanFactory extends SpanFactory { - @Override - public Span startSpan(@Nullable Span parent, String name, StartSpanOptions options) { - return BlankSpan.INSTANCE; - } + @Override + public SpanBuilder spanBuilder(@Nullable Span parent, String name) { + return new SpanBuilder.NoopSpanBuilder(parent, name); + } - @Override - public Span startSpanWithRemoteParent( - @Nullable SpanContext remoteParent, String name, StartSpanOptions options) { - return BlankSpan.INSTANCE; - } + @Override + public SpanBuilder spanBuilderWithRemoteParent( + SpanContext remoteParentSpanContext, String name) { + return new SpanBuilder.NoopSpanBuilder(remoteParentSpanContext, name); } - } - protected Tracer(SpanFactory spanFactory) { - this.spanFactory = checkNotNull(spanFactory, "spanFactory"); + private NoopTracer() {} } + + protected Tracer() {} } diff --git a/api/src/main/java/io/opencensus/trace/base/StartSpanOptions.java b/api/src/main/java/io/opencensus/trace/base/StartSpanOptions.java deleted file mode 100644 index 518f1e60ec..0000000000 --- a/api/src/main/java/io/opencensus/trace/base/StartSpanOptions.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.trace.base; - -import com.google.auto.value.AutoValue; -import com.google.common.annotations.VisibleForTesting; -import io.opencensus.trace.Span; -import io.opencensus.trace.config.TraceConfig; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * A class that enables overriding the default values used when starting a {@link Span}. Allows - * overriding the {@link Sampler sampler}, the parent links, and option to record all the events - * even if the {@code Span} is not sampled. - */ -@AutoValue -@Immutable -public abstract class StartSpanOptions { - private static final List EMPTY_PARENT_LINKS_LIST = Collections.emptyList(); - - /** The default {@code StartSpanOptions}. */ - @VisibleForTesting public static final StartSpanOptions DEFAULT = builder().build(); - - /** - * Returns the {@link Sampler} to be used, or {@code null} if default. - * - * @return the {@code Sampler} to be used, or {@code null} if default. - */ - @Nullable - public abstract Sampler getSampler(); - - /** - * Returns the parent links to be set for the {@link Span}. - * - * @return the parent links to be set for the {@code Span}. - */ - public abstract List getParentLinks(); - - /** - * Returns the record events option, or {@code null} if default. - * - *

            See {@link Span.Options#RECORD_EVENTS} for more details. - * - * @return the record events option, or {@code null} if default. - */ - @Nullable - public abstract Boolean getRecordEvents(); - - /** - * Returns a new {@link Builder} with default options. - * - * @return a new {@code Builder} with default options. - */ - public static Builder builder() { - return new AutoValue_StartSpanOptions.Builder().setParentLinks(EMPTY_PARENT_LINKS_LIST); - } - - /** Builder class for {@link StartSpanOptions}. */ - @AutoValue.Builder - public abstract static class Builder { - - /** - * Sets the {@link Sampler} to be used. If {@code null} the default {@code Sampler} from the - * {@link TraceConfig#getActiveTraceParams()} will be used. - * - * @param sampler the {@link Sampler} to be used. - * @return this. - */ - public abstract Builder setSampler(@Nullable Sampler sampler); - - /** - * Sets the parent links to be set for the {@link Span}. - * - * @param parentLinks the parent links to be set for the {@link Span}. - * @return this. - * @throws NullPointerException if {@code parentLinks} is {@code null}. - */ - public abstract Builder setParentLinks(List parentLinks); - - /** - * Sets the record events option. If {@code null} the default value from the {@link - * TraceConfig#getActiveTraceParams()} will be used. - * - *

            See {@link Span.Options#RECORD_EVENTS} for more details. - * - * @param recordEvents the record events option. - * @return this. - */ - public abstract Builder setRecordEvents(@Nullable Boolean recordEvents); - - abstract List getParentLinks(); // not public - - abstract StartSpanOptions autoBuild(); // not public - - /** - * Builds and returns a {@code StartSpanOptions} with the desired settings. - * - * @return a {@code StartSpanOptions} with the desired settings. - */ - public StartSpanOptions build() { - setParentLinks(Collections.unmodifiableList(new ArrayList(getParentLinks()))); - return autoBuild(); - } - } - - StartSpanOptions() {} -} diff --git a/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java b/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java deleted file mode 100644 index a030615227..0000000000 --- a/api/src/main/java/io/opencensus/trace/internal/SpanFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.trace.internal; - -import io.opencensus.trace.Span; -import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.StartSpanOptions; -import javax.annotation.Nullable; - -/** Factory class to create and start a {@link Span}. */ -public abstract class SpanFactory { - /** - * Creates and starts a new child {@link Span} (or root if parent is {@code null}), with parent - * being the designated {@code Span} and the given options. - * - * @param parent The parent of the returned {@code Span}. - * @param name The name of the returned {@code Span}. - * @param options The options for the start of the {@code Span}. - * @return A child {@code Span} that will have the name provided. - */ - public abstract Span startSpan(@Nullable Span parent, String name, StartSpanOptions options); - - /** - * Creates and starts a new child {@link Span} (or root if parent is {@code null}), with parent - * being the {@code Span} designated by the {@link SpanContext} and the given options. - * - *

            This must be used to create a {@code Span} when the parent is on a different process. - * - * @param remoteParent The remote parent of the returned {@code Span}. - * @param name The name of the returned {@code Span}. - * @param options The options for the start of the {@code Span}. - * @return A child {@code Span} that will have the name provided. - */ - public abstract Span startSpanWithRemoteParent( - @Nullable SpanContext remoteParent, String name, StartSpanOptions options); -} diff --git a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java deleted file mode 100644 index 10eccbe6fe..0000000000 --- a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.trace; - -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isNull; -import static org.mockito.Matchers.same; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.trace.base.EndSpanOptions; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.StartSpanOptions; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; -import io.opencensus.trace.internal.SpanFactory; -import io.opencensus.trace.samplers.Samplers; -import java.util.Arrays; -import java.util.List; -import java.util.Random; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -/** Unit tests for {@link Tracer}. */ -@RunWith(JUnit4.class) -public class SpanBuilderTest { - private static final String SPAN_NAME = "MySpanName"; - private static final Tracer tracer = Tracing.getTracer(); - private final Random random = new Random(1234); - private final SpanContext spanContext = - SpanContext.create( - TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); - @Mock private Span span; - @Mock private SpanFactory spanFactory; - private SpanBuilder spanBuilder; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - spanBuilder = SpanBuilder.builder(spanFactory, BlankSpan.INSTANCE, SPAN_NAME); - } - - @Test - public void startScopedSpanRoot() { - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - NonThrowingCloseable ss = spanBuilder.becomeRoot().startScopedSpan(); - try { - assertThat(tracer.getCurrentSpan()).isSameAs(span); - } finally { - ss.close(); - } - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startScopedSpanRootWithOptions() { - StartSpanOptions startSpanOptions = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(startSpanOptions))) - .thenReturn(span); - NonThrowingCloseable ss = - spanBuilder.becomeRoot().setSampler(Samplers.neverSample()).startScopedSpan(); - try { - assertThat(tracer.getCurrentSpan()).isSameAs(span); - } finally { - ss.close(); - } - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startRootSpan() { - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span rootSpan = spanBuilder.becomeRoot().startSpan(); - assertThat(rootSpan).isEqualTo(span); - rootSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startSpan_WithNullParent() { - spanBuilder = SpanBuilder.builder(spanFactory, null, SPAN_NAME); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span rootSpan = spanBuilder.startSpan(); - assertThat(rootSpan).isEqualTo(span); - rootSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startRootSpanWithOptions() { - List parentList = Arrays.asList(BlankSpan.INSTANCE); - StartSpanOptions startSpanOptions = - StartSpanOptions.builder() - .setSampler(Samplers.neverSample()) - .setParentLinks(parentList) - .build(); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(startSpanOptions))) - .thenReturn(span); - Span rootSpan = - spanBuilder - .becomeRoot() - .setSampler(Samplers.neverSample()) - .setParentLinks(parentList) - .startSpan(); - assertThat(rootSpan).isEqualTo(span); - rootSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startChildSpan() { - when(spanFactory.startSpan( - same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span childSpan = spanBuilder.startSpan(); - assertThat(childSpan).isEqualTo(span); - childSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startChildSpanWithOptions() { - StartSpanOptions startSpanOptions = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).setRecordEvents(true).build(); - ; - when(spanFactory.startSpan(same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(startSpanOptions))) - .thenReturn(span); - Span childSpan = - spanBuilder.setSampler(Samplers.neverSample()).setRecordEvents(true).startSpan(); - assertThat(childSpan).isEqualTo(span); - childSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startSpanWitRemoteParent() { - spanBuilder = SpanBuilder.builderWithRemoteParent(spanFactory, spanContext, SPAN_NAME); - when(spanFactory.startSpanWithRemoteParent( - same(spanContext), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span remoteChildSpan = spanBuilder.startSpan(); - assertThat(remoteChildSpan).isEqualTo(span); - remoteChildSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startSpanWitRemoteParent_WithNullParent() { - spanBuilder = SpanBuilder.builderWithRemoteParent(spanFactory, null, SPAN_NAME); - when(spanFactory.startSpanWithRemoteParent( - isNull(SpanContext.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span remoteChildSpan = spanBuilder.startSpan(); - assertThat(remoteChildSpan).isEqualTo(span); - remoteChildSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } -} diff --git a/api/src/test/java/io/opencensus/trace/TracerTest.java b/api/src/test/java/io/opencensus/trace/TracerTest.java index 7339eae266..3c69068ba2 100644 --- a/api/src/test/java/io/opencensus/trace/TracerTest.java +++ b/api/src/test/java/io/opencensus/trace/TracerTest.java @@ -14,21 +14,11 @@ package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isNull; import static org.mockito.Matchers.same; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.grpc.Context; import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.trace.base.EndSpanOptions; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.StartSpanOptions; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; -import io.opencensus.trace.internal.SpanFactory; -import java.util.Random; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -41,10 +31,11 @@ /** Unit tests for {@link Tracer}. */ @RunWith(JUnit4.class) public class TracerTest { - private static final Tracer tracer = Tracing.getTracer(); + private static final Tracer noopTracer = Tracer.getNoopTracer(); private static final String SPAN_NAME = "MySpanName"; @Rule public ExpectedException thrown = ExpectedException.none(); - @Mock private SpanFactory spanFactory; + @Mock private Tracer tracer; + @Mock private SpanBuilder spanBuilder; @Mock private Span span; @Before @@ -54,163 +45,107 @@ public void setUp() { @Test public void defaultGetCurrentSpan() { - assertThat(tracer.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE); + assertThat(noopTracer.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE); } @Test(expected = NullPointerException.class) public void withSpan_NullSpan() { - tracer.withSpan(null); + noopTracer.withSpan(null); } @Test public void getCurrentSpan_WithSpan() { - assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); - NonThrowingCloseable ws = tracer.withSpan(span); + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + NonThrowingCloseable ws = noopTracer.withSpan(span); try { - assertThat(tracer.getCurrentSpan()).isSameAs(span); + assertThat(noopTracer.getCurrentSpan()).isSameAs(span); } finally { ws.close(); } - assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); } @Test public void propagationViaRunnable() { - Runnable runnable = null; - NonThrowingCloseable ws = tracer.withSpan(span); + Runnable runnable; + NonThrowingCloseable ws = noopTracer.withSpan(span); try { - assertThat(tracer.getCurrentSpan()).isSameAs(span); + assertThat(noopTracer.getCurrentSpan()).isSameAs(span); runnable = Context.current() .wrap( new Runnable() { @Override public void run() { - assertThat(tracer.getCurrentSpan()).isSameAs(span); + assertThat(noopTracer.getCurrentSpan()).isSameAs(span); } }); } finally { ws.close(); } - assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); // When we run the runnable we will have the span in the current Context. runnable.run(); - assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); } @Test(expected = NullPointerException.class) public void spanBuilderWithName_NullName() { - assertThat(tracer.spanBuilder(null).startSpan()).isSameAs(BlankSpan.INSTANCE); + noopTracer.spanBuilder(null); } @Test public void defaultSpanBuilderWithName() { - assertThat(tracer.spanBuilder(SPAN_NAME).startSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat(noopTracer.spanBuilder(SPAN_NAME).startSpan()).isSameAs(BlankSpan.INSTANCE); } @Test(expected = NullPointerException.class) public void spanBuilderWithParentAndName_NullName() { - assertThat(tracer.spanBuilder(null, null).startSpan()).isSameAs(BlankSpan.INSTANCE); + noopTracer.spanBuilder(null, null); } @Test public void defaultSpanBuilderWithParentAndName() { - assertThat(tracer.spanBuilder(null, SPAN_NAME).startSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat(noopTracer.spanBuilder(null, SPAN_NAME).startSpan()).isSameAs(BlankSpan.INSTANCE); } @Test(expected = NullPointerException.class) public void spanBuilderWithRemoteParent_NullName() { - assertThat(tracer.spanBuilderWithRemoteParent(null, null).startSpan()) - .isSameAs(BlankSpan.INSTANCE); + noopTracer.spanBuilderWithRemoteParent(null, null); + } + + @Test(expected = NullPointerException.class) + public void defaultSpanBuilderWitRemoteParent_NullParent() { + noopTracer.spanBuilderWithRemoteParent(null, SPAN_NAME); } @Test - public void defaultSpanBuilderWitRemoteParent() { - assertThat(tracer.spanBuilderWithRemoteParent(null, SPAN_NAME).startSpan()) + public void defaultSpanBuilderWithRemoteParent() { + assertThat(noopTracer.spanBuilderWithRemoteParent(SpanContext.INVALID, SPAN_NAME).startSpan()) .isSameAs(BlankSpan.INSTANCE); } @Test - public void startScopedSpanRoot() { - Tracer mockTracer = new MockTracer(spanFactory); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - NonThrowingCloseable ss = mockTracer.spanBuilder(SPAN_NAME).becomeRoot().startScopedSpan(); + public void startSpanWithParentFromContext() { + NonThrowingCloseable ws = tracer.withSpan(span); try { assertThat(tracer.getCurrentSpan()).isSameAs(span); + when(tracer.spanBuilder(same(span), same(SPAN_NAME))).thenReturn(spanBuilder); + assertThat(tracer.spanBuilder(SPAN_NAME)).isSameAs(spanBuilder); } finally { - ss.close(); + ws.close(); } - verify(span).end(same(EndSpanOptions.DEFAULT)); } @Test - public void startScopedSpanChild() { - Tracer mockTracer = new MockTracer(spanFactory); - NonThrowingCloseable ws = mockTracer.withSpan(BlankSpan.INSTANCE); + public void startSpanWithInvalidParentFromContext() { + NonThrowingCloseable ws = tracer.withSpan(BlankSpan.INSTANCE); try { assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); - when(spanFactory.startSpan( - same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - NonThrowingCloseable ss = mockTracer.spanBuilder(SPAN_NAME).startScopedSpan(); - try { - assertThat(tracer.getCurrentSpan()).isSameAs(span); - } finally { - ss.close(); - } - assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + when(tracer.spanBuilder(same(BlankSpan.INSTANCE), same(SPAN_NAME))).thenReturn(spanBuilder); + assertThat(tracer.spanBuilder(SPAN_NAME)).isSameAs(spanBuilder); } finally { ws.close(); } - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startRootSpan() { - Tracer mockTracer = new MockTracer(spanFactory); - when(spanFactory.startSpan(isNull(Span.class), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span rootSpan = mockTracer.spanBuilder(BlankSpan.INSTANCE, SPAN_NAME).becomeRoot().startSpan(); - assertThat(rootSpan).isEqualTo(span); - rootSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startChildSpan() { - Tracer mockTracer = new MockTracer(spanFactory); - when(spanFactory.startSpan( - same(BlankSpan.INSTANCE), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span childSpan = mockTracer.spanBuilder(BlankSpan.INSTANCE, SPAN_NAME).startSpan(); - assertThat(childSpan).isEqualTo(span); - childSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - @Test - public void startSpanWitRemoteParent() { - Random random = new Random(1234); - Tracer mockTracer = new MockTracer(spanFactory); - SpanContext spanContext = - SpanContext.create( - TraceId.generateRandomId(random), - SpanId.generateRandomId(random), - TraceOptions.DEFAULT); - when(spanFactory.startSpanWithRemoteParent( - same(spanContext), same(SPAN_NAME), eq(StartSpanOptions.DEFAULT))) - .thenReturn(span); - Span remoteChildSpan = - mockTracer.spanBuilderWithRemoteParent(spanContext, SPAN_NAME).startSpan(); - assertThat(remoteChildSpan).isEqualTo(span); - remoteChildSpan.end(); - verify(span).end(same(EndSpanOptions.DEFAULT)); - } - - private static final class MockTracer extends Tracer { - private MockTracer(SpanFactory spanFactory) { - super(spanFactory); - } } } diff --git a/api/src/test/java/io/opencensus/trace/base/StartSpanOptionsTest.java b/api/src/test/java/io/opencensus/trace/base/StartSpanOptionsTest.java deleted file mode 100644 index 1a983b73df..0000000000 --- a/api/src/test/java/io/opencensus/trace/base/StartSpanOptionsTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.trace.base; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.testing.EqualsTester; -import io.opencensus.trace.BlankSpan; -import io.opencensus.trace.Span; -import io.opencensus.trace.samplers.Samplers; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link StartSpanOptions}. */ -@RunWith(JUnit4.class) -public class StartSpanOptionsTest { - private final List singleParentList = Arrays.asList(BlankSpan.INSTANCE); - - @Test - public void defaultOptions() { - StartSpanOptions defaultOptions = StartSpanOptions.builder().build(); - assertThat(defaultOptions.getSampler()).isNull(); - assertThat(defaultOptions.getParentLinks().isEmpty()).isTrue(); - assertThat(defaultOptions.getRecordEvents()).isNull(); - } - - @Test - public void setSampler() { - StartSpanOptions options = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); - assertThat(options.getSampler()).isEqualTo(Samplers.neverSample()); - assertThat(options.getParentLinks().isEmpty()).isTrue(); - assertThat(options.getRecordEvents()).isNull(); - } - - @Test - public void setParentLinks() { - StartSpanOptions options = StartSpanOptions.builder().setParentLinks(singleParentList).build(); - assertThat(options.getSampler()).isNull(); - assertThat(options.getParentLinks()).isEqualTo(singleParentList); - assertThat(options.getRecordEvents()).isNull(); - } - - @Test - public void setParentLinks_EmptyList() { - StartSpanOptions options = - StartSpanOptions.builder().setParentLinks(new LinkedList()).build(); - assertThat(options.getSampler()).isNull(); - assertThat(options.getParentLinks().size()).isEqualTo(0); - assertThat(options.getRecordEvents()).isNull(); - } - - @Test - public void setParentLinks_MultipleParents() { - StartSpanOptions options = - StartSpanOptions.builder() - .setParentLinks(Arrays.asList(BlankSpan.INSTANCE, BlankSpan.INSTANCE)) - .build(); - assertThat(options.getSampler()).isNull(); - assertThat(options.getParentLinks().size()).isEqualTo(2); - assertThat(options.getRecordEvents()).isNull(); - } - - @Test - public void setRecordEvents() { - StartSpanOptions options = StartSpanOptions.builder().setRecordEvents(true).build(); - assertThat(options.getSampler()).isNull(); - assertThat(options.getParentLinks().isEmpty()).isTrue(); - assertThat(options.getRecordEvents()).isTrue(); - } - - @Test - public void setAllProperties() { - StartSpanOptions options = - StartSpanOptions.builder() - .setSampler(Samplers.alwaysSample()) - .setRecordEvents(true) - .setParentLinks(singleParentList) - .build(); - assertThat(options.getSampler()).isEqualTo(Samplers.alwaysSample()); - assertThat(options.getParentLinks()).isEqualTo(singleParentList); - assertThat(options.getRecordEvents()).isTrue(); - } - - @Test - public void startSpanOptions_EqualsAndHashCode() { - EqualsTester tester = new EqualsTester(); - StartSpanOptions optionsWithAlwaysSampler1 = - StartSpanOptions.builder().setSampler(Samplers.alwaysSample()).build(); - StartSpanOptions optionsWithAlwaysSampler2 = - StartSpanOptions.builder().setSampler(Samplers.alwaysSample()).build(); - tester.addEqualityGroup(optionsWithAlwaysSampler1, optionsWithAlwaysSampler2); - StartSpanOptions optionsWithNeverSampler = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); - tester.addEqualityGroup(optionsWithNeverSampler); - tester.addEqualityGroup(StartSpanOptions.DEFAULT); - tester.testEquals(); - } -} diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java index 3013e764ca..06a1412ffd 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java @@ -36,9 +36,9 @@ public class RecordTraceEventsNonSampledSpanBenchmark { private static final String ATTRIBUTE_KEY = "MyAttributeKey"; private static final String ATTRIBUTE_VALUE = "MyAttributeValue"; private Span linkedSpan = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); private Span span = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); /** TearDown method. */ @TearDown diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java index ccfbc7753a..5773923ff4 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java @@ -36,9 +36,9 @@ public class RecordTraceEventsSampledSpanBenchmark { private static final String ATTRIBUTE_KEY = "MyAttributeKey"; private static final String ATTRIBUTE_VALUE = "MyAttributeValue"; private Span linkedSpan = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.alwaysSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.alwaysSample()).startSpan(); private Span span = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.alwaysSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.alwaysSample()).startSpan(); /** TearDown method. */ @TearDown diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java index 0a86b6f8ae..8418184ff2 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java @@ -23,13 +23,13 @@ import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; -/** Benchmarks for {@link SpanFactoryImpl} and {@link SpanImpl}. */ +/** Benchmarks for {@link SpanBuilderImpl} and {@link SpanImpl}. */ @State(Scope.Benchmark) public class StartEndSpanBenchmark { private static final Tracer tracer = Tracing.getTracer(); private static final String SPAN_NAME = "MySpanName"; private Span rootSpan = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); @TearDown public void doTearDown() { @@ -45,7 +45,7 @@ public void doTearDown() { @OutputTimeUnit(TimeUnit.NANOSECONDS) public Span startEndNonSampledRootSpan() { Span span = - tracer.spanBuilder(SPAN_NAME).becomeRoot().setSampler(Samplers.neverSample()).startSpan(); + tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); span.end(); return span; } @@ -60,8 +60,7 @@ public Span startEndNonSampledRootSpan() { public Span startEndRecordEventsRootSpan() { Span span = tracer - .spanBuilder(SPAN_NAME) - .becomeRoot() + .spanBuilder(null, SPAN_NAME) .setSampler(Samplers.neverSample()) .setRecordEvents(true) .startSpan(); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java index aa23f3f70d..c6fa0317a7 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java @@ -49,7 +49,7 @@ private static void doWork() { /** Main method. */ public static void main(String[] args) { LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); - Span span = tracer.spanBuilder("MyRootSpan").becomeRoot().startSpan(); + Span span = tracer.spanBuilder(null,"MyRootSpan").startSpan(); try (NonThrowingCloseable ws = tracer.withSpan(span)) { doWork(); } diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java index 10f2d2ca4e..547403bb7d 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java @@ -48,7 +48,7 @@ private static void doWork() { public static void main(String[] args) { LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); try (NonThrowingCloseable ss = - tracer.spanBuilder("MyRootSpan").becomeRoot().startScopedSpan()) { + tracer.spanBuilder(null,"MyRootSpan").startScopedSpan()) { doWork(); } } diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java new file mode 100644 index 0000000000..74a4ae34f5 --- /dev/null +++ b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java @@ -0,0 +1,192 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.opencensus.common.Clock; +import io.opencensus.internal.TimestampConverter; +import io.opencensus.trace.base.Link; +import io.opencensus.trace.base.Link.Type; +import io.opencensus.trace.base.Sampler; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.internal.RandomHandler; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.Random; +import javax.annotation.Nullable; + +/** Implementation of the {@link SpanBuilder}. */ +final class SpanBuilderImpl extends SpanBuilder { + private final Options options; + + private final String name; + private final Span parentSpan; + private final SpanContext remoteParentSpanContext; + private Sampler sampler; + private List parentLinks = Collections.emptyList(); + private Boolean recordEvents; + + private Span startSpanInternal( + @Nullable SpanContext parent, + boolean hasRemoteParent, + String name, + Sampler sampler, + List parentLinks, + Boolean recordEvents, + @Nullable TimestampConverter timestampConverter) { + TraceParams activeTraceParams = options.traceConfig.getActiveTraceParams(); + Random random = options.randomHandler.current(); + TraceId traceId; + SpanId spanId = SpanId.generateRandomId(random); + SpanId parentSpanId = null; + TraceOptions.Builder traceOptionsBuilder; + if (parent == null || !parent.isValid()) { + // New root span. + traceId = TraceId.generateRandomId(random); + traceOptionsBuilder = TraceOptions.builder(); + // This is a root span so no remote or local parent. + hasRemoteParent = false; + } else { + // New child span. + traceId = parent.getTraceId(); + parentSpanId = parent.getSpanId(); + traceOptionsBuilder = TraceOptions.builder(parent.getTraceOptions()); + } + if (sampler == null) { + sampler = activeTraceParams.getSampler(); + } + if (sampler.shouldSample(parent, hasRemoteParent, traceId, spanId, name, parentLinks)) { + traceOptionsBuilder.setIsSampled(); + } + TraceOptions traceOptions = traceOptionsBuilder.build(); + EnumSet spanOptions = EnumSet.noneOf(Span.Options.class); + if (traceOptions.isSampled() || Boolean.TRUE.equals(recordEvents)) { + spanOptions.add(Span.Options.RECORD_EVENTS); + } + Span span = + SpanImpl.startSpan( + SpanContext.create(traceId, spanId, traceOptions), + spanOptions, + name, + parentSpanId, + hasRemoteParent, + activeTraceParams, + options.startEndHandler, + timestampConverter, + options.clock); + linkSpans(span, parentLinks); + return span; + } + + private static void linkSpans(Span span, List parentLinks) { + if (!parentLinks.isEmpty()) { + Link childLink = Link.fromSpanContext(span.getContext(), Type.CHILD); + for (Span linkedSpan : parentLinks) { + linkedSpan.addLink(childLink); + span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Type.PARENT)); + } + } + } + + static SpanBuilder createBuilder(@Nullable Span parentSpan, String name, Options options) { + return new SpanBuilderImpl(parentSpan, null, name, options); + } + + static SpanBuilder createBuilderWithRemoteParent( + SpanContext remoteParentSpanContext, String name, Options options) { + return new SpanBuilderImpl(null, checkNotNull(remoteParentSpanContext, + "remoteParentSpanContext"), name, options); + } + + private SpanBuilderImpl( + @Nullable Span parentSpan, + @Nullable SpanContext remoteParentSpanContext, + String name, + Options options) { + this.name = checkNotNull(name, "name"); + this.parentSpan = parentSpan; + this.remoteParentSpanContext = remoteParentSpanContext; + this.options = options; + } + + @Override + public Span startSpan() { + SpanContext parentContext = remoteParentSpanContext; + boolean hasRemoteParent = parentContext != null; + TimestampConverter timestampConverter = null; + if (!hasRemoteParent) { + // This is not a child of a remote Span. Get the parent SpanContext from the parent Span if + // any. + Span parent = parentSpan; + if (parent != null) { + parentContext = parent.getContext(); + // Pass the timestamp converter from the parent to ensure that the recorded events are in + // the right order. Implementation uses System.nanoTime() which is monotonically increasing. + if (parent instanceof SpanImpl) { + timestampConverter = ((SpanImpl) parent).getTimestampConverter(); + } + } + } + return startSpanInternal( + parentContext, + hasRemoteParent, + name, + sampler, + parentLinks, + recordEvents, + timestampConverter); + } + + static final class Options { + private final RandomHandler randomHandler; + private final SpanImpl.StartEndHandler startEndHandler; + private final Clock clock; + private final TraceConfig traceConfig; + + Options( + RandomHandler randomHandler, + SpanImpl.StartEndHandler startEndHandler, + Clock clock, + TraceConfig traceConfig) { + this.randomHandler = checkNotNull(randomHandler, "randomHandler"); + this.startEndHandler = checkNotNull(startEndHandler, "startEndHandler"); + this.clock = checkNotNull(clock, "clock"); + this.traceConfig = checkNotNull(traceConfig, "traceConfig"); + } + } + + @Override + public SpanBuilder setSampler(Sampler sampler) { + this.sampler = checkNotNull(sampler, "sampler"); + return this; + } + + @Override + public SpanBuilder setParentLinks(List parentLinks) { + this.parentLinks = checkNotNull(parentLinks, "parentLinks"); + return this; + } + + @Override + public SpanBuilder setRecordEvents(boolean recordEvents) { + this.recordEvents = recordEvents; + return this; + } +} diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanFactoryImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanFactoryImpl.java deleted file mode 100644 index 4e816d975f..0000000000 --- a/impl_core/src/main/java/io/opencensus/trace/SpanFactoryImpl.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.trace; - -import static com.google.common.base.Preconditions.checkNotNull; - -import io.opencensus.common.Clock; -import io.opencensus.internal.TimestampConverter; -import io.opencensus.trace.Span.Options; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.Link.Type; -import io.opencensus.trace.base.Sampler; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.StartSpanOptions; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; -import io.opencensus.trace.config.TraceConfig; -import io.opencensus.trace.config.TraceParams; -import io.opencensus.trace.internal.RandomHandler; -import io.opencensus.trace.internal.SpanFactory; -import java.util.EnumSet; -import java.util.List; -import java.util.Random; -import javax.annotation.Nullable; - -/** Implementation of the {@link SpanFactory}. */ -final class SpanFactoryImpl extends SpanFactory { - private final RandomHandler randomHandler; - private final SpanImpl.StartEndHandler startEndHandler; - private final Clock clock; - private final TraceConfig traceConfig; - - @Override - public Span startSpan(@Nullable Span parent, String name, StartSpanOptions options) { - SpanContext parentContext = null; - TimestampConverter timestampConverter = null; - if (parent != null) { - parentContext = parent.getContext(); - // Pass the timestamp converter from the parent to ensure that the recorded events are in - // the right order. Implementation uses System.nanoTime() which is monotonically increasing. - if (parent instanceof SpanImpl) { - timestampConverter = ((SpanImpl) parent).getTimestampConverter(); - } - } - return startSpanInternal(parentContext, false, name, options, timestampConverter); - } - - @Override - public Span startSpanWithRemoteParent( - @Nullable SpanContext remoteParent, String name, StartSpanOptions options) { - return startSpanInternal(remoteParent, true, name, options, null); - } - - Span startSpanInternal( - @Nullable SpanContext parent, - boolean hasRemoteParent, - String name, - StartSpanOptions startSpanOptions, - @Nullable TimestampConverter timestampConverter) { - TraceParams activeTraceParams = traceConfig.getActiveTraceParams(); - Random random = randomHandler.current(); - TraceId traceId; - SpanId spanId = SpanId.generateRandomId(random); - SpanId parentSpanId = null; - TraceOptions.Builder traceOptionsBuilder; - if (parent == null || !parent.isValid()) { - // New root span. - traceId = TraceId.generateRandomId(random); - traceOptionsBuilder = TraceOptions.builder(); - // This is a root span so no remote or local parent. - hasRemoteParent = false; - } else { - // New child span. - traceId = parent.getTraceId(); - parentSpanId = parent.getSpanId(); - traceOptionsBuilder = TraceOptions.builder(parent.getTraceOptions()); - } - Sampler sampler = - startSpanOptions.getSampler() != null - ? startSpanOptions.getSampler() - : activeTraceParams.getSampler(); - if (sampler.shouldSample( - parent, hasRemoteParent, traceId, spanId, name, startSpanOptions.getParentLinks())) { - traceOptionsBuilder.setIsSampled(); - } - TraceOptions traceOptions = traceOptionsBuilder.build(); - EnumSet spanOptions = EnumSet.noneOf(Options.class); - if (traceOptions.isSampled() || Boolean.TRUE.equals(startSpanOptions.getRecordEvents())) { - spanOptions.add(Options.RECORD_EVENTS); - } - Span span = - SpanImpl.startSpan( - SpanContext.create(traceId, spanId, traceOptions), - spanOptions, - name, - parentSpanId, - hasRemoteParent, - activeTraceParams, - startEndHandler, - timestampConverter, - clock); - linkSpans(span, startSpanOptions.getParentLinks()); - return span; - } - - private static void linkSpans(Span span, List parentLinks) { - if (!parentLinks.isEmpty()) { - Link childLink = Link.fromSpanContext(span.getContext(), Type.CHILD); - for (Span linkedSpan : parentLinks) { - linkedSpan.addLink(childLink); - span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Type.PARENT)); - } - } - } - - SpanFactoryImpl( - RandomHandler randomHandler, - SpanImpl.StartEndHandler startEndHandler, - Clock clock, - TraceConfig traceConfig) { - this.randomHandler = checkNotNull(randomHandler, "randomHandler"); - this.startEndHandler = checkNotNull(startEndHandler, "startEndHandler"); - this.clock = checkNotNull(clock, "clock"); - this.traceConfig = checkNotNull(traceConfig, "traceConfig"); - } -} diff --git a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java index b0f7e07a56..9159eeade7 100644 --- a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java @@ -68,8 +68,7 @@ public void onStart(SpanImpl span) { public void onEnd(SpanImpl span) { if ((span.getOptions().contains(Options.RECORD_EVENTS) && enqueueEventForNonSampledSpans) || span.getContext().getTraceOptions().isSampled()) { - eventQueue.enqueue( - new SpanEndEvent(span, spanExporter, runningSpanStore, sampledSpanStore)); + eventQueue.enqueue(new SpanEndEvent(span, spanExporter, runningSpanStore, sampledSpanStore)); } } diff --git a/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java b/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java index f753a8473a..b15a8b9903 100644 --- a/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java @@ -16,14 +16,30 @@ import io.opencensus.common.Clock; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.internal.RandomHandler; +import javax.annotation.Nullable; /** Implementation of the {@link Tracer}. */ final class TracerImpl extends Tracer { + private final SpanBuilderImpl.Options spanBuilderOptions; + TracerImpl( RandomHandler randomHandler, SpanImpl.StartEndHandler startEndHandler, Clock clock, TraceConfig traceConfig) { - super(new SpanFactoryImpl(randomHandler, startEndHandler, clock, traceConfig)); + spanBuilderOptions = + new SpanBuilderImpl.Options(randomHandler, startEndHandler, clock, traceConfig); + } + + @Override + public SpanBuilder spanBuilder(@Nullable Span parent, String name) { + return SpanBuilderImpl.createBuilder(parent, name, spanBuilderOptions); + } + + @Override + public SpanBuilder spanBuilderWithRemoteParent( + SpanContext remoteParentSpanContext, String name) { + return SpanBuilderImpl.createBuilderWithRemoteParent( + remoteParentSpanContext, name, spanBuilderOptions); } } diff --git a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java index a6b809860d..fa968f4e19 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java @@ -43,8 +43,8 @@ public SampledSpanStoreImpl getSampledSpanStore() { } /** - * Returns a new {@code ExportComponentImpl} that has valid instances for {@link - * RunningSpanStore} and {@link SampledSpanStore}. + * Returns a new {@code ExportComponentImpl} that has valid instances for {@link RunningSpanStore} + * and {@link SampledSpanStore}. * * @return a new {@code ExportComponentImpl}. */ @@ -65,8 +65,8 @@ public static ExportComponentImpl createWithoutInProcessStores() { /** * Constructs a new {@code ExportComponentImpl}. * - * @param supportInProcessStores {@code true} to instantiate {@link RunningSpanStore} and - * {@link SampledSpanStore}. + * @param supportInProcessStores {@code true} to instantiate {@link RunningSpanStore} and {@link + * SampledSpanStore}. */ private ExportComponentImpl(boolean supportInProcessStores) { this.spanExporter = SpanExporterImpl.create(EXPORTER_BUFFER_SIZE, EXPORTER_SCHEDULE_DELAY_MS); diff --git a/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java index a2a986e5bb..b9a62e00be 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java @@ -40,6 +40,7 @@ public final class SampledSpanStoreImpl extends SampledSpanStore { private static final int MAX_PER_SPAN_NAME_SAMPLES = NUM_SAMPLES_PER_LATENCY_BUCKET * NUM_LATENCY_BUCKETS + NUM_SAMPLES_PER_ERROR_BUCKET * NUM_ERROR_BUCKETS; + @GuardedBy("samples") private final Map samples; @@ -91,8 +92,8 @@ private int getNumSamples() { } /** - * Keeps samples for a given span name. Samples for all the latency buckets and for all - * canonical codes other than OK. + * Keeps samples for a given span name. Samples for all the latency buckets and for all canonical + * codes other than OK. */ private static final class PerSpanNameSamples { @@ -210,8 +211,8 @@ public Summary getSummary() { } /** - * Considers to save the given spans to the stored samples. This must be called at the end of - * each Span with the option RECORD_EVENTS. + * Considers to save the given spans to the stored samples. This must be called at the end of each + * Span with the option RECORD_EVENTS. * * @param span the span to be consider for storing into the store buckets. */ diff --git a/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java b/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java index 602a0acc49..d04d00520d 100644 --- a/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java +++ b/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java @@ -31,16 +31,12 @@ public abstract class RandomHandler { */ public abstract Random current(); - /** - * Implementation of the {@link RandomHandler} using {@link SecureRandom}. - */ + /** Implementation of the {@link RandomHandler} using {@link SecureRandom}. */ @ThreadSafe public static final class SecureRandomHandler extends RandomHandler { private final Random random = new SecureRandom(); - /** - * Constructs a new {@link SecureRandomHandler}. - */ + /** Constructs a new {@link SecureRandomHandler}. */ public SecureRandomHandler() {} @Override diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java similarity index 68% rename from impl_core/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java rename to impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java index 1d5cf3acd4..afcd3b8b03 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanFactoryImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java @@ -20,7 +20,6 @@ import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.StartSpanOptions; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceConfig; @@ -36,11 +35,11 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -/** Unit tests for {@link SpanFactoryImpl}. */ +/** Unit tests for {@link SpanBuilderImpl}. */ @RunWith(JUnit4.class) -public class SpanFactoryImplTest { +public class SpanBuilderImplTest { private static final String SPAN_NAME = "MySpanName"; - private SpanFactoryImpl spanFactory; + private SpanBuilderImpl.Options spanBuilderOptions; private TraceParams alwaysSampleTraceParams = TraceParams.DEFAULT.toBuilder().setSampler(Samplers.alwaysSample()).build(); private final TestClock testClock = TestClock.create(); @@ -51,14 +50,14 @@ public class SpanFactoryImplTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); - spanFactory = new SpanFactoryImpl(randomHandler, startEndHandler, testClock, traceConfig); + spanBuilderOptions = + new SpanBuilderImpl.Options(randomHandler, startEndHandler, testClock, traceConfig); + when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); } @Test public void startSpanNullParent() { - StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + Span span = SpanBuilderImpl.createBuilder(null, SPAN_NAME, spanBuilderOptions).startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); @@ -72,10 +71,11 @@ public void startSpanNullParent() { @Test public void startSpanNullParentWithRecordEvents() { - StartSpanOptions startSpanOptions = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).setRecordEvents(true).build(); - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + Span span = + SpanBuilderImpl.createBuilder(null, SPAN_NAME, spanBuilderOptions) + .setSampler(Samplers.neverSample()) + .setRecordEvents(true) + .startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(span.getContext().getTraceOptions().isSampled()).isFalse(); @@ -87,38 +87,23 @@ public void startSpanNullParentWithRecordEvents() { @Test public void startSpanNullParentNoRecordOptions() { - StartSpanOptions startSpanOptions = - StartSpanOptions.builder().setSampler(Samplers.neverSample()).build(); - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span span = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + Span span = + SpanBuilderImpl.createBuilder(null, SPAN_NAME, spanBuilderOptions) + .setSampler(Samplers.neverSample()) + .startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isFalse(); assertThat(span.getContext().getTraceOptions().isSampled()).isFalse(); } - @Test - public void startRemoteSpanNullParent() { - StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span span = spanFactory.startSpanWithRemoteParent(null, SPAN_NAME, startSpanOptions); - assertThat(span.getContext().isValid()).isTrue(); - assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); - assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); - assertThat(span instanceof SpanImpl).isTrue(); - SpanData spanData = ((SpanImpl) span).toSpanData(); - assertThat(spanData.getParentSpanId()).isNull(); - assertThat(spanData.getHasRemoteParent()).isFalse(); - } - @Test public void startChildSpan() { - StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span rootSpan = spanFactory.startSpan(null, SPAN_NAME, startSpanOptions); + Span rootSpan = SpanBuilderImpl.createBuilder(null, SPAN_NAME, spanBuilderOptions).startSpan(); assertThat(rootSpan.getContext().isValid()).isTrue(); assertThat(rootSpan.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isTrue(); - Span childSpan = spanFactory.startSpan(rootSpan, SPAN_NAME, startSpanOptions); + Span childSpan = + SpanBuilderImpl.createBuilder(rootSpan, SPAN_NAME, spanBuilderOptions).startSpan(); assertThat(childSpan.getContext().isValid()).isTrue(); assertThat(childSpan.getContext().getTraceId()).isEqualTo(rootSpan.getContext().getTraceId()); assertThat(((SpanImpl) childSpan).toSpanData().getParentSpanId()) @@ -127,12 +112,17 @@ public void startChildSpan() { .isEqualTo(((SpanImpl) rootSpan).getTimestampConverter()); } + @Test(expected = NullPointerException.class) + public void startRemoteSpan_NullParent() { + SpanBuilderImpl.createBuilderWithRemoteParent(null, SPAN_NAME, spanBuilderOptions); + } + @Test public void startRemoteSpanInvalidParent() { - StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); Span span = - spanFactory.startSpanWithRemoteParent(SpanContext.INVALID, SPAN_NAME, startSpanOptions); + SpanBuilderImpl.createBuilderWithRemoteParent( + SpanContext.INVALID, SPAN_NAME, spanBuilderOptions) + .startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); @@ -149,9 +139,9 @@ public void startRemoteSpan() { TraceId.generateRandomId(randomHandler.current()), SpanId.generateRandomId(randomHandler.current()), TraceOptions.DEFAULT); - StartSpanOptions startSpanOptions = StartSpanOptions.DEFAULT; - when(traceConfig.getActiveTraceParams()).thenReturn(alwaysSampleTraceParams); - Span span = spanFactory.startSpanWithRemoteParent(spanContext, SPAN_NAME, startSpanOptions); + Span span = + SpanBuilderImpl.createBuilderWithRemoteParent(spanContext, SPAN_NAME, spanBuilderOptions) + .startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getContext().getTraceId()).isEqualTo(spanContext.getTraceId()); assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); diff --git a/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java b/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java new file mode 100644 index 0000000000..9ee70c98be --- /dev/null +++ b/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.testing.common.TestClock; +import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.internal.RandomHandler.SecureRandomHandler; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link TracerImpl}. */ +@RunWith(JUnit4.class) +public class TracerImplTest { + private static final String SPAN_NAME = "MySpanName"; + @Mock private StartEndHandler startEndHandler; + @Mock private TraceConfig traceConfig; + private TracerImpl tracer; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + tracer = + new TracerImpl(new SecureRandomHandler(), startEndHandler, TestClock.create(), traceConfig); + } + + @Test + public void createSpanBuilder() { + SpanBuilder spanBuilder = tracer.spanBuilder(BlankSpan.INSTANCE, SPAN_NAME); + assertThat(spanBuilder).isInstanceOf(SpanBuilderImpl.class); + } + + @Test + public void createSpanBuilderWithRemoteParet() { + SpanBuilder spanBuilder = tracer.spanBuilderWithRemoteParent(SpanContext.INVALID, SPAN_NAME); + assertThat(spanBuilder).isInstanceOf(SpanBuilderImpl.class); + } +} From 39ac27f3005d647c7825714ea5c5b5c0a5a84fda Mon Sep 17 00:00:00 2001 From: Yang Song Date: Fri, 30 Jun 2017 15:40:06 -0700 Subject: [PATCH 0218/1581] Refactor MeasurementDescriptor. (#396) * Refactor MeasurementDescriptor. * Remove Measure.Name class for now. --- .../java/io/opencensus/stats/Measure.java | 119 +++++++++++ .../stats/MeasurementDescriptor.java | 188 ------------------ .../io/opencensus/stats/MeasurementMap.java | 78 ++++---- .../io/opencensus/stats/MeasurementValue.java | 10 +- .../stats/RpcMeasurementConstants.java | 150 +++++++------- .../io/opencensus/stats/ViewDescriptor.java | 20 +- .../java/io/opencensus/stats/MeasureTest.java | 116 +++++++++++ .../stats/MeasurementDescriptorTest.java | 126 ------------ .../opencensus/stats/MeasurementMapTest.java | 29 ++- .../opencensus/stats/ViewDescriptorTest.java | 38 ++-- .../java/io/opencensus/stats/ViewTest.java | 14 +- ...orToViewMap.java => MeasureToViewMap.java} | 16 +- .../io/opencensus/stats/StatsManager.java | 10 +- ...MapTest.java => MeasureToViewMapTest.java} | 20 +- .../opencensus/stats/ViewManagerImplTest.java | 31 ++- .../examples/stats/StatsRunner.java | 16 +- 16 files changed, 439 insertions(+), 542 deletions(-) create mode 100644 core/src/main/java/io/opencensus/stats/Measure.java delete mode 100644 core/src/main/java/io/opencensus/stats/MeasurementDescriptor.java create mode 100644 core/src/test/java/io/opencensus/stats/MeasureTest.java delete mode 100644 core/src/test/java/io/opencensus/stats/MeasurementDescriptorTest.java rename core_impl/src/main/java/io/opencensus/stats/{MeasurementDescriptorToViewMap.java => MeasureToViewMap.java} (87%) rename core_impl/src/test/java/io/opencensus/stats/{MeasurementDescriptorToViewMapTest.java => MeasureToViewMapTest.java} (78%) diff --git a/core/src/main/java/io/opencensus/stats/Measure.java b/core/src/main/java/io/opencensus/stats/Measure.java new file mode 100644 index 0000000000..3f637c95fc --- /dev/null +++ b/core/src/main/java/io/opencensus/stats/Measure.java @@ -0,0 +1,119 @@ +/* + * Copyright 2016, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import com.google.auto.value.AutoValue; +import io.opencensus.common.Function; +import javax.annotation.concurrent.Immutable; + +/** + * Measure. + */ +@Immutable +public abstract class Measure { + + /** + * Applies the given match function to the underlying data type. + */ + public abstract T match(Function p0, Function p1); + + /** + * Name of measure, as a {@code String}. + */ + public abstract String getName(); + + /** + * Detailed description of the measure, used in documentation. + */ + public abstract String getDescription(); + + /** + * The units in which {@link Measure} values are measured. + * + *

            The grammar for a unit is as follows: + * Expression = Component { "." Component } { "/" Component } ; + * Component = [ PREFIX ] UNIT [ Annotation ] | Annotation | "1" ; + * Annotation = "{" NAME "}" ; + * For example, string “MBy{transmitted}/ms” stands for megabytes per milliseconds, and the + * annotation transmitted inside {} is just a comment of the unit. + */ + public abstract String getUnit(); + + // Prevents this class from being subclassed anywhere else. + private Measure() { + } + + @Immutable + @AutoValue + public abstract static class DoubleMeasure extends Measure { + + DoubleMeasure() { + } + + /** + * Constructs a new {@link DoubleMeasure}. + */ + public static DoubleMeasure create(String name, String description, String unit) { + // TODO(dpo): ensure that measure names are unique, and consider if there should be any + // restricitons on name (e.g. size, characters). + return new AutoValue_Measure_DoubleMeasure(name, description, unit); + } + + @Override + public T match(Function p0, Function p1) { + return p0.apply(this); + } + + @Override + public abstract String getName(); + + @Override + public abstract String getDescription(); + + @Override + public abstract String getUnit(); + } + + @Immutable + @AutoValue + // TODO: determine whether we want to support LongMeasure in V0.1 + public abstract static class LongMeasure extends Measure { + + LongMeasure() { + } + + /** + * Constructs a new {@link LongMeasure}. + */ + public static LongMeasure create(String name, String description, String unit) { + // TODO(dpo): ensure that measure names are unique, and consider if there should be any + // restricitons on name (e.g. size, characters). + return new AutoValue_Measure_LongMeasure(name, description, unit); + } + + @Override + public T match(Function p0, Function p1) { + return p1.apply(this); + } + + @Override + public abstract String getName(); + + @Override + public abstract String getDescription(); + + @Override + public abstract String getUnit(); + } +} diff --git a/core/src/main/java/io/opencensus/stats/MeasurementDescriptor.java b/core/src/main/java/io/opencensus/stats/MeasurementDescriptor.java deleted file mode 100644 index 996686977b..0000000000 --- a/core/src/main/java/io/opencensus/stats/MeasurementDescriptor.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import com.google.auto.value.AutoValue; -import io.opencensus.internal.StringUtil; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javax.annotation.concurrent.Immutable; - -/** - * MeasurementDescriptor. - * - *

            Note: MeasurementDescriptor names are {@link String}s with enforced restrictions. - */ -@Immutable -@AutoValue -public abstract class MeasurementDescriptor { - public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; - - MeasurementDescriptor() {} - - /** - * Constructs a new {@link MeasurementDescriptor}. - */ - public static MeasurementDescriptor create( - String name, String description, MeasurementUnit unit) { - return create(Name.create(name), description, unit); - } - - /** - * Constructs a new {@link MeasurementDescriptor}. - */ - public static MeasurementDescriptor create( - Name name, String description, MeasurementUnit unit) { - return new AutoValue_MeasurementDescriptor(name, description, unit); - } - - /** - * Name of measurement, e.g. rpc_latency, cpu. Must be unique. - */ - public abstract MeasurementDescriptor.Name getMeasurementDescriptorName(); - - /** - * Name of measurement, as a {@code String}. - */ - public final String getName() { - return getMeasurementDescriptorName().asString(); - } - - /** - * Detailed description of the measurement, used in documentation. - */ - public abstract String getDescription(); - - /** - * The units in which {@link MeasurementDescriptor} values are measured. - */ - public abstract MeasurementUnit getUnit(); - - /** - * Fundamental units of measurement. - */ - public enum BasicUnit { - SCALAR, - BITS, - BYTES, - SECONDS, - CORES; - } - - /** - * The name of a {@code MeasurementDescriptor}. - */ - // This type should be used as the key when associating data with MeasurementDescriptors. - @Immutable - @AutoValue - public abstract static class Name { - - Name() {} - - /** - * Returns the name as a {@code String}. - * - * @return the name as a {@code String}. - */ - public abstract String asString(); - - /** - * Creates a {@code MeasurementDescriptor.Name} from a {@code String}. - * - * @param name the name {@code String}. - * @return a {@code MeasurementDescriptor.Name} with the given name {@code String}. - */ - public static Name create(String name) { - return new AutoValue_MeasurementDescriptor_Name(StringUtil.sanitize(name)); - } - } - - /** - * MeasurementUnit lets you build compound units of the form - * 10^n * (A * B * ...) / (X * Y * ...), - * where the elements in the numerator and denominator are all BasicUnits. A - * MeasurementUnit must have at least one BasicUnit in its numerator. - * - *

            To specify multiplication in the numerator or denominator, simply specify - * multiple numerator or denominator fields. For example: - * - *

            - byte-seconds (i.e. bytes * seconds): - * numerator: BYTES - * numerator: SECS - * - *

            - events/sec^2 (i.e. rate of change of events/sec): - * numerator: SCALAR - * denominator: SECS - * denominator: SECS - * - *

            To specify multiples (in power of 10) of units, specify a non-zero power10 - * value, for example: - * - *

            - MB/s (i.e. megabytes / s): - * power10: 6 - * numerator: BYTES - * denominator: SECS - * - *

            - nanoseconds - * power10: -9 - * numerator: SECS - */ - @Immutable - @AutoValue - public abstract static class MeasurementUnit { - - MeasurementUnit() {} - - /** - * Constructs a {@link MeasurementUnit}. - */ - public static MeasurementUnit create( - int power10, List numerators, List denominators) { - return new AutoValue_MeasurementDescriptor_MeasurementUnit( - power10, - Collections.unmodifiableList(new ArrayList(numerators)), - Collections.unmodifiableList(new ArrayList(denominators))); - } - - /** - * Constructs a {@link MeasurementUnit} without the optional {@code denominators}. - */ - public static MeasurementUnit create(int power10, List numerators) { - return new AutoValue_MeasurementDescriptor_MeasurementUnit( - power10, numerators, Collections.emptyList()); - } - - /** - * Unit multiplier (i.e. 10^power10). - */ - public abstract int getPower10(); - - /** - * Unit Numerators. - * - *

            Note: The returned list is unmodifiable and attempts to update it will throw an - * UnsupportedOperationException. - */ - public abstract List getNumerators(); - - /** - * Unit Denominators. - * - *

            Note: The returned list is unmodifiable and attempts to update it will throw an - * UnsupportedOperationException. - */ - public abstract List getDenominators(); - } -} diff --git a/core/src/main/java/io/opencensus/stats/MeasurementMap.java b/core/src/main/java/io/opencensus/stats/MeasurementMap.java index a961bf17d5..6694a93398 100644 --- a/core/src/main/java/io/opencensus/stats/MeasurementMap.java +++ b/core/src/main/java/io/opencensus/stats/MeasurementMap.java @@ -18,34 +18,34 @@ import java.util.NoSuchElementException; /** - * A map from {@link MeasurementDescriptor}'s to measured values. + * A map from {@link Measure}'s to measured values. */ public final class MeasurementMap implements Iterable { /** - * Constructs a {@link MeasurementMap} from the given {@link MeasurementDescriptor} + * Constructs a {@link MeasurementMap} from the given {@link Measure} * and associated value. */ - public static MeasurementMap of(MeasurementDescriptor measurement, double value) { - return builder().put(measurement, value).build(); + public static MeasurementMap of(Measure measure, double value) { + return builder().put(measure, value).build(); } /** - * Constructs a {@link MeasurementMap} from the given {@link MeasurementDescriptor}'s + * Constructs a {@link MeasurementMap} from the given {@link Measure}'s * and associated values. */ - public static MeasurementMap of(MeasurementDescriptor measurement1, double value1, - MeasurementDescriptor measurement2, double value2) { - return builder().put(measurement1, value1).put(measurement2, value2).build(); + public static MeasurementMap of(Measure measure1, double value1, + Measure measure2, double value2) { + return builder().put(measure1, value1).put(measure2, value2).build(); } /** - * Constructs a {@link MeasurementMap} from the given {@link MeasurementDescriptor}'s + * Constructs a {@link MeasurementMap} from the given {@link Measure}'s * and associated values. */ - public static MeasurementMap of(MeasurementDescriptor measurement1, double value1, - MeasurementDescriptor measurement2, double value2, - MeasurementDescriptor measurement3, double value3) { - return builder().put(measurement1, value1).put(measurement2, value2).put(measurement3, value3) + public static MeasurementMap of(Measure measure1, double value1, + Measure measure2, double value2, + Measure measure3, double value3) { + return builder().put(measure1, value1).put(measure2, value2).put(measure3, value3) .build(); } @@ -57,14 +57,14 @@ public static Builder builder() { } /** - * Returns the number of measurements in this {@link MeasurementMap}. + * Returns the number of measures in this {@link MeasurementMap}. */ public int size() { - return measurements.size(); + return measures.size(); } /** - * Returns an {@link Iterator} over the measurement/value mappings in this {@link MeasurementMap}. + * Returns an {@link Iterator} over the measure/value mappings in this {@link MeasurementMap}. * The {@code Iterator} does not support {@link Iterator#remove()}. */ @Override @@ -72,10 +72,10 @@ public Iterator iterator() { return new MeasurementMapIterator(); } - private final ArrayList measurements; + private final ArrayList measures; - private MeasurementMap(ArrayList measurements) { - this.measurements = measurements; + private MeasurementMap(ArrayList measures) { + this.measures = measures; } /** @@ -83,45 +83,45 @@ private MeasurementMap(ArrayList measurements) { */ public static class Builder { /** - * Associates the {@link MeasurementDescriptor} with the given value. Subsequent updates to the - * same {@link MeasurementDescriptor} are ignored. + * Associates the {@link Measure} with the given value. Subsequent updates to the + * same {@link Measure} are ignored. * - * @param measurement the {@link MeasurementDescriptor} - * @param value the value to be associated with {@code measurement} + * @param measure the {@link Measure} + * @param value the value to be associated with {@code measure} * @return this */ - public Builder put(MeasurementDescriptor measurement, double value) { - measurements.add(MeasurementValue.create(measurement, value)); + public Builder put(Measure measure, double value) { + measures.add(MeasurementValue.create(measure, value)); return this; } /** - * Constructs a {@link MeasurementMap} from the current measurements. + * Constructs a {@link MeasurementMap} from the current measures. */ public MeasurementMap build() { - // Note: this makes adding measurements quadratic but is fastest for the sizes of + // Note: this makes adding measures quadratic but is fastest for the sizes of // MeasurementMaps that we should see. We may want to go to a strategy of sort/eliminate // for larger MeasurementMaps. - for (int i = 0; i < measurements.size(); i++) { - MeasurementDescriptor.Name current = - measurements.get(i).getMeasurement().getMeasurementDescriptorName(); - for (int j = i + 1; j < measurements.size(); j++) { - if (current.equals(measurements.get(j).getMeasurement().getMeasurementDescriptorName())) { - measurements.remove(j); + for (int i = 0; i < measures.size(); i++) { + String current = + measures.get(i).getMeasurement().getName(); + for (int j = i + 1; j < measures.size(); j++) { + if (current.equals(measures.get(j).getMeasurement().getName())) { + measures.remove(j); j--; } } } - return new MeasurementMap(measurements); + return new MeasurementMap(measures); } - private final ArrayList measurements = new ArrayList(); + private final ArrayList measures = new ArrayList(); private Builder() { } } - // Provides an unmodifiable Iterator over this instance's measurements. + // Provides an unmodifiable Iterator over this instance's measures. private final class MeasurementMapIterator implements Iterator { @Override public boolean hasNext() { @@ -130,10 +130,10 @@ public boolean hasNext() { @Override public MeasurementValue next() { - if (position >= measurements.size()) { + if (position >= measures.size()) { throw new NoSuchElementException(); } - return measurements.get(position++); + return measures.get(position++); } @Override @@ -141,7 +141,7 @@ public void remove() { throw new UnsupportedOperationException(); } - private final int length = measurements.size(); + private final int length = measures.size(); private int position = 0; } } diff --git a/core/src/main/java/io/opencensus/stats/MeasurementValue.java b/core/src/main/java/io/opencensus/stats/MeasurementValue.java index 6c9cc3a65f..efee6f3954 100644 --- a/core/src/main/java/io/opencensus/stats/MeasurementValue.java +++ b/core/src/main/java/io/opencensus/stats/MeasurementValue.java @@ -21,14 +21,14 @@ public class MeasurementValue { /** * Constructs a measured value. */ - public static MeasurementValue create(MeasurementDescriptor name, double value) { + public static MeasurementValue create(Measure name, double value) { return new MeasurementValue(name, value); } /** - * Extracts the measured {@link MeasurementDescriptor}. + * Extracts the measured {@link Measure}. */ - public MeasurementDescriptor getMeasurement() { + public Measure getMeasurement() { return name; } @@ -39,10 +39,10 @@ public double getValue() { return value; } - private final MeasurementDescriptor name; + private final Measure name; private final double value; - private MeasurementValue(MeasurementDescriptor name, double value) { + private MeasurementValue(Measure name, double value) { this.name = name; this.value = value; } diff --git a/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java b/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java index c015e17cb1..415529a161 100644 --- a/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java @@ -13,14 +13,10 @@ package io.opencensus.stats; -import io.opencensus.stats.MeasurementDescriptor.BasicUnit; -import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; -import java.util.Arrays; -import java.util.List; - /** * Constants for collecting rpc stats. */ +// TODO(songya): change *_COUNT constants to LongMeasure if it's supported in v0.1. public final class RpcMeasurementConstants { // Rpc tag keys. @@ -28,125 +24,125 @@ public final class RpcMeasurementConstants { public static final TagKey RPC_CLIENT_METHOD = TagKey.create("method"); public static final TagKey RPC_SERVER_METHOD = TagKey.create("method"); - // Constants used to define the following MeasurementDescriptors. - private static final List bytes = Arrays.asList(BasicUnit.BYTES); - private static final List scalar = Arrays.asList(BasicUnit.SCALAR); - private static final List seconds = Arrays.asList(BasicUnit.SECONDS); + // Constants used to define the following Measures. + private static final String BYTE = "By"; + private static final String COUNT = "1"; + private static final String MILLISECOND = "ms"; - // RPC client {@link MeasurementDescriptor}s. - public static final MeasurementDescriptor RPC_CLIENT_ERROR_COUNT = - MeasurementDescriptor.create( + // RPC client Measures. + public static final Measure RPC_CLIENT_ERROR_COUNT = + Measure.DoubleMeasure.create( "grpc.io/client/error_count", "RPC Errors", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_CLIENT_REQUEST_BYTES = - MeasurementDescriptor.create( + COUNT); + public static final Measure RPC_CLIENT_REQUEST_BYTES = + Measure.DoubleMeasure.create( "grpc.io/client/request_bytes", "Request bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_CLIENT_RESPONSE_BYTES = - MeasurementDescriptor.create( + BYTE); + public static final Measure RPC_CLIENT_RESPONSE_BYTES = + Measure.DoubleMeasure.create( "grpc.io/client/response_bytes", "Response bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_CLIENT_ROUNDTRIP_LATENCY = - MeasurementDescriptor.create( + BYTE); + public static final Measure RPC_CLIENT_ROUNDTRIP_LATENCY = + Measure.DoubleMeasure.create( "grpc.io/client/roundtrip_latency", "RPC roundtrip latency msec", - MeasurementUnit.create(-3, seconds)); - public static final MeasurementDescriptor RPC_CLIENT_SERVER_ELAPSED_TIME = - MeasurementDescriptor.create( + MILLISECOND); + public static final Measure RPC_CLIENT_SERVER_ELAPSED_TIME = + Measure.DoubleMeasure.create( "grpc.io/client/server_elapsed_time", "Server elapsed time in msecs", - MeasurementUnit.create(-3, seconds)); - public static final MeasurementDescriptor RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES = - MeasurementDescriptor.create( + MILLISECOND); + public static final Measure RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES = + Measure.DoubleMeasure.create( "grpc.io/client/uncompressed_request_bytes", "Uncompressed Request bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES = - MeasurementDescriptor.create( + BYTE); + public static final Measure RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES = + Measure.DoubleMeasure.create( "grpc.io/client/uncompressed_response_bytes", "Uncompressed Response bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_CLIENT_STARTED_COUNT = - MeasurementDescriptor.create( + BYTE); + public static final Measure RPC_CLIENT_STARTED_COUNT = + Measure.DoubleMeasure.create( "grpc.io/client/started_count", "Number of client RPCs (streams) started", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_CLIENT_FINISHED_COUNT = - MeasurementDescriptor.create( + COUNT); + public static final Measure RPC_CLIENT_FINISHED_COUNT = + Measure.DoubleMeasure.create( "grpc.io/client/finished_count", "Number of client RPCs (streams) finished", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_CLIENT_REQUEST_COUNT = - MeasurementDescriptor.create( + COUNT); + public static final Measure RPC_CLIENT_REQUEST_COUNT = + Measure.DoubleMeasure.create( "grpc.io/client/request_count", "Number of client RPC request messages", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_CLIENT_RESPONSE_COUNT = - MeasurementDescriptor.create( + COUNT); + public static final Measure RPC_CLIENT_RESPONSE_COUNT = + Measure.DoubleMeasure.create( "grpc.io/client/response_count", "Number of client RPC response messages", - MeasurementUnit.create(0, scalar)); + COUNT); - // RPC server {@link MeasurementDescriptor}s. - public static final MeasurementDescriptor RPC_SERVER_ERROR_COUNT = - MeasurementDescriptor.create( + // RPC server Measures. + public static final Measure RPC_SERVER_ERROR_COUNT = + Measure.DoubleMeasure.create( "grpc.io/server/error_count", "RPC Errors", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_SERVER_REQUEST_BYTES = - MeasurementDescriptor.create( + COUNT); + public static final Measure RPC_SERVER_REQUEST_BYTES = + Measure.DoubleMeasure.create( "grpc.io/server/request_bytes", "Request bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_SERVER_RESPONSE_BYTES = - MeasurementDescriptor.create( + BYTE); + public static final Measure RPC_SERVER_RESPONSE_BYTES = + Measure.DoubleMeasure.create( "grpc.io/server/response_bytes", "Response bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_SERVER_SERVER_ELAPSED_TIME = - MeasurementDescriptor.create( + BYTE); + public static final Measure RPC_SERVER_SERVER_ELAPSED_TIME = + Measure.DoubleMeasure.create( "grpc.io/server/server_elapsed_time", "Server elapsed time in msecs", - MeasurementUnit.create(-3, seconds)); - public static final MeasurementDescriptor RPC_SERVER_SERVER_LATENCY = - MeasurementDescriptor.create( + MILLISECOND); + public static final Measure RPC_SERVER_SERVER_LATENCY = + Measure.DoubleMeasure.create( "grpc.io/server/server_latency", "Latency in msecs", - MeasurementUnit.create(-3, seconds)); - public static final MeasurementDescriptor RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES = - MeasurementDescriptor.create( + MILLISECOND); + public static final Measure RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES = + Measure.DoubleMeasure.create( "grpc.io/server/uncompressed_request_bytes", "Uncompressed Request bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES = - MeasurementDescriptor.create( + BYTE); + public static final Measure RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES = + Measure.DoubleMeasure.create( "grpc.io/server/uncompressed_response_bytes", "Uncompressed Response bytes", - MeasurementUnit.create(0, bytes)); - public static final MeasurementDescriptor RPC_SERVER_STARTED_COUNT = - MeasurementDescriptor.create( + BYTE); + public static final Measure RPC_SERVER_STARTED_COUNT = + Measure.DoubleMeasure.create( "grpc.io/server/started_count", "Number of server RPCs (streams) started", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_SERVER_FINISHED_COUNT = - MeasurementDescriptor.create( + COUNT); + public static final Measure RPC_SERVER_FINISHED_COUNT = + Measure.DoubleMeasure.create( "grpc.io/server/finished_count", "Number of server RPCs (streams) finished", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_SERVER_REQUEST_COUNT = - MeasurementDescriptor.create( + COUNT); + public static final Measure RPC_SERVER_REQUEST_COUNT = + Measure.DoubleMeasure.create( "grpc.io/server/request_count", "Number of server RPC request messages", - MeasurementUnit.create(0, scalar)); - public static final MeasurementDescriptor RPC_SERVER_RESPONSE_COUNT = - MeasurementDescriptor.create( + COUNT); + public static final Measure RPC_SERVER_RESPONSE_COUNT = + Measure.DoubleMeasure.create( "grpc.io/server/response_count", "Number of server RPC response messages", - MeasurementUnit.create(0, scalar)); + COUNT); // Visible for testing. RpcMeasurementConstants() { diff --git a/core/src/main/java/io/opencensus/stats/ViewDescriptor.java b/core/src/main/java/io/opencensus/stats/ViewDescriptor.java index bef15cc5b1..22859ce6f1 100644 --- a/core/src/main/java/io/opencensus/stats/ViewDescriptor.java +++ b/core/src/main/java/io/opencensus/stats/ViewDescriptor.java @@ -46,10 +46,10 @@ public final String getName() { /** * Measurement type of this view. */ - public abstract MeasurementDescriptor getMeasurementDescriptor(); + public abstract Measure getMeasure(); /** - * Tag keys to match with the associated {@link MeasurementDescriptor}. If no keys are specified, + * Tag keys to match with the associated {@link Measure}. If no keys are specified, * then all stats are recorded. Keys must be unique. * *

            Note: The returned list is unmodifiable, attempts to update it will throw an @@ -104,13 +104,13 @@ public abstract static class DistributionViewDescriptor extends ViewDescriptor { public static DistributionViewDescriptor create( String name, String description, - MeasurementDescriptor measurementDescriptor, + Measure measure, DistributionAggregationDescriptor distributionAggregationDescriptor, List tagKeys) { return create( Name.create(name), description, - measurementDescriptor, + measure, distributionAggregationDescriptor, tagKeys); } @@ -121,13 +121,13 @@ public static DistributionViewDescriptor create( public static DistributionViewDescriptor create( Name name, String description, - MeasurementDescriptor measurementDescriptor, + Measure measure, DistributionAggregationDescriptor distributionAggregationDescriptor, List tagKeys) { return new AutoValue_ViewDescriptor_DistributionViewDescriptor( name, description, - measurementDescriptor, + measure, Collections.unmodifiableList(new ArrayList(tagKeys)), distributionAggregationDescriptor); } @@ -158,13 +158,13 @@ public abstract static class IntervalViewDescriptor extends ViewDescriptor { public static IntervalViewDescriptor create( String name, String description, - MeasurementDescriptor measurementDescriptor, + Measure measure, IntervalAggregationDescriptor intervalAggregationDescriptor, List tagKeys) { return create( Name.create(name), description, - measurementDescriptor, + measure, intervalAggregationDescriptor, tagKeys); } @@ -175,13 +175,13 @@ public static IntervalViewDescriptor create( public static IntervalViewDescriptor create( Name name, String description, - MeasurementDescriptor measurementDescriptor, + Measure measure, IntervalAggregationDescriptor intervalAggregationDescriptor, List tagKeys) { return new AutoValue_ViewDescriptor_IntervalViewDescriptor( name, description, - measurementDescriptor, + measure, Collections.unmodifiableList(new ArrayList(tagKeys)), intervalAggregationDescriptor); } diff --git a/core/src/test/java/io/opencensus/stats/MeasureTest.java b/core/src/test/java/io/opencensus/stats/MeasureTest.java new file mode 100644 index 0000000000..aff4c873f7 --- /dev/null +++ b/core/src/test/java/io/opencensus/stats/MeasureTest.java @@ -0,0 +1,116 @@ +/* + * Copyright 2016, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.internal.StringUtil; +import java.util.Arrays; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for {@link Measure} + */ +@RunWith(JUnit4.class) +public final class MeasureTest { + + @Ignore // TODO: determine whether there are any restrictions on measure names. + @Test + public void testNameMaxLength() { + char[] name = new char[StringUtil.MAX_LENGTH]; + char[] truncName = new char[StringUtil.MAX_LENGTH + 10]; + Arrays.fill(name, 'n'); + Arrays.fill(truncName, 'n'); + assertThat(makeSimpleMeasure(new String(name)).getName()) + .isEqualTo(makeSimpleMeasure(new String(truncName)).getName()); + } + + @Ignore // TODO: determine whether there are any restrictions on measure names. + @Test + public void testNameBadChar() { + assertThat(makeSimpleMeasure("\2ab\3cd").getName()) + .isEqualTo(StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + "ab" + + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + "cd"); + } + + @Test + public void testDoubleMeasureComponents() { + Measure measurement = Measure.DoubleMeasure.create( + "Foo", + "The description of Foo", + "Mbit/s"); + assertThat(measurement.getName()).isEqualTo("Foo"); + assertThat(measurement.getDescription()).isEqualTo("The description of Foo"); + assertThat(measurement.getUnit()).isEqualTo("Mbit/s"); + } + + @Test + public void testLongMeasureComponents() { + Measure measurement = Measure.LongMeasure.create( + "Bar", + "The description of Bar", + "1"); + assertThat(measurement.getName()).isEqualTo("Bar"); + assertThat(measurement.getDescription()).isEqualTo("The description of Bar"); + assertThat(measurement.getUnit()).isEqualTo("1"); + } + + @Test + public void testDoubleMeasureEquals() { + new EqualsTester() + .addEqualityGroup( + Measure.DoubleMeasure.create( + "name", + "description", + "bit/s"), + Measure.DoubleMeasure.create( + "name", + "description", + "bit/s")) + .addEqualityGroup( + Measure.DoubleMeasure.create( + "name", + "description 2", + "bit/s")) + .testEquals(); + } + + @Test + public void testLongMeasureEquals() { + new EqualsTester() + .addEqualityGroup( + Measure.LongMeasure.create( + "name", + "description", + "bit/s"), + Measure.LongMeasure.create( + "name", + "description", + "bit/s")) + .addEqualityGroup( + Measure.LongMeasure.create( + "name", + "description 2", + "bit/s")) + .testEquals(); + } + + private static final Measure makeSimpleMeasure(String name) { + return Measure.DoubleMeasure.create(name, name + " description", "1"); + } +} diff --git a/core/src/test/java/io/opencensus/stats/MeasurementDescriptorTest.java b/core/src/test/java/io/opencensus/stats/MeasurementDescriptorTest.java deleted file mode 100644 index 47b6bc5759..0000000000 --- a/core/src/test/java/io/opencensus/stats/MeasurementDescriptorTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.testing.EqualsTester; -import io.opencensus.internal.StringUtil; -import io.opencensus.stats.MeasurementDescriptor.BasicUnit; -import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; -import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests for {@link MeasurementDescriptor} - */ -@RunWith(JUnit4.class) -public final class MeasurementDescriptorTest { - @Test - public void testNameMaxLength() { - char[] name = new char[MeasurementDescriptor.MAX_LENGTH]; - char[] truncName = new char[MeasurementDescriptor.MAX_LENGTH + 10]; - Arrays.fill(name, 'n'); - Arrays.fill(truncName, 'n'); - assertThat(makeSimpleDescriptor(new String(name)).getName()) - .isEqualTo(makeSimpleDescriptor(new String(truncName)).getName()); - } - - @Test - public void testNameBadChar() { - assertThat(makeSimpleDescriptor("\2ab\3cd").getName()) - .isEqualTo(StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + "ab" - + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + "cd"); - } - - @Test - public void testComponents() { - MeasurementDescriptor measurement = MeasurementDescriptor.create( - "Foo", - "The description of Foo", - MeasurementUnit.create( - 6, Arrays.asList(BasicUnit.BITS), Arrays.asList(BasicUnit.SECONDS))); - assertThat(measurement.getName()).isEqualTo("Foo"); - assertThat(measurement.getMeasurementDescriptorName()) - .isEqualTo(MeasurementDescriptor.Name.create("Foo")); - assertThat(measurement.getDescription()).isEqualTo("The description of Foo"); - assertThat(measurement.getUnit().getPower10()).isEqualTo(6); - assertThat(measurement.getUnit().getNumerators()).hasSize(1); - assertThat(measurement.getUnit().getNumerators().get(0)).isEqualTo(BasicUnit.BITS); - assertThat(measurement.getUnit().getDenominators()).hasSize(1); - assertThat(measurement.getUnit().getDenominators().get(0)).isEqualTo(BasicUnit.SECONDS); - } - - @Test - public void testMeasurementDescriptorNameSanitization() { - assertThat(MeasurementDescriptor.Name.create("md\1").asString()) - .isEqualTo("md" + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE); - } - - @Test - public void testMeasurementDescriptorNameEquals() { - new EqualsTester() - .addEqualityGroup( - MeasurementDescriptor.Name.create("md1"), MeasurementDescriptor.Name.create("md1")) - .addEqualityGroup(MeasurementDescriptor.Name.create("md2")) - .testEquals(); - } - - @Test - public void testMeasurementUnitEquals() { - new EqualsTester() - .addEqualityGroup( - MeasurementUnit.create( - 1, Arrays.asList(BasicUnit.BYTES), Arrays.asList(BasicUnit.SECONDS)), - MeasurementUnit.create( - 1, Arrays.asList(BasicUnit.BYTES), Arrays.asList(BasicUnit.SECONDS))) - .addEqualityGroup( - MeasurementUnit.create( - 2, Arrays.asList(BasicUnit.BYTES), Arrays.asList(BasicUnit.SECONDS))) - .addEqualityGroup(MeasurementUnit.create(1, Arrays.asList(BasicUnit.BYTES))) - .testEquals(); - } - - @Test - public void testMeasurementDescriptorEquals() { - new EqualsTester() - .addEqualityGroup( - MeasurementDescriptor.create( - "name", - "description", - MeasurementUnit.create( - 1, Arrays.asList(BasicUnit.BITS), Arrays.asList(BasicUnit.SECONDS))), - MeasurementDescriptor.create( - MeasurementDescriptor.Name.create("name"), - "description", - MeasurementUnit.create( - 1, Arrays.asList(BasicUnit.BITS), Arrays.asList(BasicUnit.SECONDS)))) - .addEqualityGroup( - MeasurementDescriptor.create( - "name", - "description 2", - MeasurementUnit.create( - 1, Arrays.asList(BasicUnit.BYTES), Arrays.asList(BasicUnit.SECONDS)))) - .testEquals(); - } - - private static final MeasurementDescriptor makeSimpleDescriptor(String name) { - return MeasurementDescriptor.create( - name, - name + " description", - MeasurementUnit.create(1, Arrays.asList(BasicUnit.SCALAR))); - } -} diff --git a/core/src/test/java/io/opencensus/stats/MeasurementMapTest.java b/core/src/test/java/io/opencensus/stats/MeasurementMapTest.java index 0f9f52f155..ad5af9ba63 100644 --- a/core/src/test/java/io/opencensus/stats/MeasurementMapTest.java +++ b/core/src/test/java/io/opencensus/stats/MeasurementMapTest.java @@ -16,10 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; -import io.opencensus.stats.MeasurementDescriptor.BasicUnit; -import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; import java.util.ArrayList; -import java.util.Arrays; import java.util.Iterator; import org.junit.Test; import org.junit.runner.RunWith; @@ -68,14 +65,14 @@ public void testBuilder() { ArrayList expected = new ArrayList(10); MeasurementMap.Builder builder = MeasurementMap.builder(); for (int i = 1; i <= 10; i++) { - expected.add(MeasurementValue.create(makeSimpleMeasurement("m" + i), i * 11.1)); - builder.put(makeSimpleMeasurement("m" + i), i * 11.1); + expected.add(MeasurementValue.create(makeSimpleMeasure("m" + i), i * 11.1)); + builder.put(makeSimpleMeasure("m" + i), i * 11.1); assertEquals(expected, builder.build()); } } @Test - public void testDuplicateMeasurementDescriptors() { + public void testDuplicateMeasures() { assertEquals(MeasurementMap.of(M1, 1.0, M1, 1.0), MeasurementMap.of(M1, 1.0)); assertEquals(MeasurementMap.of(M1, 1.0, M1, 2.0), MeasurementMap.of(M1, 1.0)); assertEquals(MeasurementMap.of(M1, 1.0, M1, 2.0, M1, 3.0), MeasurementMap.of(M1, 1.0)); @@ -87,20 +84,18 @@ public void testDuplicateMeasurementDescriptors() { public void testSize() { MeasurementMap.Builder builder = MeasurementMap.builder(); for (int i = 1; i <= 10; i++) { - builder.put(makeSimpleMeasurement("m" + i), i * 11.1); + builder.put(makeSimpleMeasure("m" + i), i * 11.1); assertThat(builder.build()).hasSize(i); } } - private static final MeasurementUnit simpleMeasurementUnit = - MeasurementUnit.create(1, Arrays.asList(BasicUnit.SCALAR)); - private static final MeasurementDescriptor M1 = makeSimpleMeasurement("m1"); - private static final MeasurementDescriptor M2 = makeSimpleMeasurement("m2"); - private static final MeasurementDescriptor M3 = makeSimpleMeasurement("m3"); + private static final Measure M1 = makeSimpleMeasure("m1"); + private static final Measure M2 = makeSimpleMeasure("m2"); + private static final Measure M3 = makeSimpleMeasure("m3"); - private static final MeasurementDescriptor makeSimpleMeasurement(String measurement) { - return MeasurementDescriptor.create( - measurement, measurement + " description", simpleMeasurementUnit); + private static final Measure makeSimpleMeasure(String measure) { + return Measure.DoubleMeasure.create( + measure, measure + " description", "1"); } private static void assertEquals( @@ -110,8 +105,8 @@ private static void assertEquals( while (e.hasNext() && a.hasNext()) { MeasurementValue expectedMeasurement = e.next(); MeasurementValue actualMeasurement = a.next(); - assertThat(expectedMeasurement.getMeasurement().getMeasurementDescriptorName()) - .isEqualTo(actualMeasurement.getMeasurement().getMeasurementDescriptorName()); + assertThat(expectedMeasurement.getMeasurement().getName()) + .isEqualTo(actualMeasurement.getMeasurement().getName()); assertThat(expectedMeasurement.getValue()) .isWithin(0.00000001).of(actualMeasurement.getValue()); } diff --git a/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java b/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java index c0ee71437e..e8c5cd803b 100644 --- a/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java @@ -19,8 +19,6 @@ import com.google.common.testing.EqualsTester; import io.opencensus.common.Duration; import io.opencensus.common.Function; -import io.opencensus.stats.MeasurementDescriptor.BasicUnit; -import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Arrays; @@ -38,13 +36,13 @@ public final class ViewDescriptorTest { public void testDistributionViewDescriptor() { DistributionAggregationDescriptor dAggrDescriptor = DistributionAggregationDescriptor.create(); final ViewDescriptor viewDescriptor = DistributionViewDescriptor.create( - name, description, measurementDescriptor, dAggrDescriptor, keys); + name, description, measure, dAggrDescriptor, keys); assertThat(viewDescriptor.getViewDescriptorName()).isEqualTo(name); assertThat(viewDescriptor.getName()).isEqualTo(name.asString()); assertThat(viewDescriptor.getDescription()).isEqualTo(description); - assertThat(viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()) - .isEqualTo(measurementDescriptor.getMeasurementDescriptorName()); + assertThat(viewDescriptor.getMeasure().getName()) + .isEqualTo(measure.getName()); assertThat(viewDescriptor.getTagKeys()).hasSize(2); assertThat(viewDescriptor.getTagKeys().get(0).toString()).isEqualTo("foo"); assertThat(viewDescriptor.getTagKeys().get(1).toString()).isEqualTo("bar"); @@ -66,13 +64,13 @@ public void testIntervalViewDescriptor() { IntervalAggregationDescriptor iAggrDescriptor = IntervalAggregationDescriptor.create( Arrays.asList(Duration.fromMillis(1), Duration.fromMillis(22), Duration.fromMillis(333))); final ViewDescriptor viewDescriptor = IntervalViewDescriptor.create( - name, description, measurementDescriptor, iAggrDescriptor, keys); + name, description, measure, iAggrDescriptor, keys); assertThat(viewDescriptor.getViewDescriptorName()).isEqualTo(name); assertThat(viewDescriptor.getName()).isEqualTo(name.asString()); assertThat(viewDescriptor.getDescription()).isEqualTo(description); - assertThat(viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()) - .isEqualTo(measurementDescriptor.getMeasurementDescriptorName()); + assertThat(viewDescriptor.getMeasure().getName()) + .isEqualTo(measure.getName()); assertThat(viewDescriptor.getTagKeys()).hasSize(2); assertThat(viewDescriptor.getTagKeys().get(0).toString()).isEqualTo("foo"); assertThat(viewDescriptor.getTagKeys().get(1).toString()).isEqualTo("bar"); @@ -97,20 +95,20 @@ public void testViewDescriptorEquals() { new EqualsTester() .addEqualityGroup( DistributionViewDescriptor.create( - name, description, measurementDescriptor, dAggrDescriptor, keys), + name, description, measure, dAggrDescriptor, keys), DistributionViewDescriptor.create( - name, description, measurementDescriptor, dAggrDescriptor, keys)) + name, description, measure, dAggrDescriptor, keys)) .addEqualityGroup( DistributionViewDescriptor.create( - name, description + 2, measurementDescriptor, dAggrDescriptor, keys)) + name, description + 2, measure, dAggrDescriptor, keys)) .addEqualityGroup( IntervalViewDescriptor.create( - name, description, measurementDescriptor, iAggrDescriptor, keys), + name, description, measure, iAggrDescriptor, keys), IntervalViewDescriptor.create( - name, description, measurementDescriptor, iAggrDescriptor, keys)) + name, description, measure, iAggrDescriptor, keys)) .addEqualityGroup( IntervalViewDescriptor.create( - name, description + 2, measurementDescriptor, iAggrDescriptor, keys)) + name, description + 2, measure, iAggrDescriptor, keys)) .testEquals(); } @@ -119,7 +117,7 @@ public void preventNullDistributionViewDescriptorName() { DistributionViewDescriptor.create( (ViewDescriptor.Name) null, description, - measurementDescriptor, + measure, DistributionAggregationDescriptor.create(), keys); } @@ -129,7 +127,7 @@ public void preventNullDistributionViewDescriptorStringName() { DistributionViewDescriptor.create( (String) null, description, - measurementDescriptor, + measure, DistributionAggregationDescriptor.create(), keys); } @@ -139,7 +137,7 @@ public void preventNullIntervalViewDescriptorName() { IntervalViewDescriptor.create( (ViewDescriptor.Name) null, description, - measurementDescriptor, + measure, IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(1))), keys); } @@ -149,7 +147,7 @@ public void preventNullIntervalViewDescriptorStringName() { IntervalViewDescriptor.create( (String) null, description, - measurementDescriptor, + measure, IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(1))), keys); } @@ -175,9 +173,9 @@ public void testViewDescriptorNameEquals() { private final ViewDescriptor.Name name = ViewDescriptor.Name.create("test-view-name"); private final String description = "test-view-name description"; - private final MeasurementDescriptor measurementDescriptor = MeasurementDescriptor.create( + private final Measure measure = Measure.DoubleMeasure.create( "measurement", "measurement description", - MeasurementUnit.create(1, Arrays.asList(BasicUnit.SCALAR))); + "1"); private final List keys = Arrays.asList(TagKey.create("foo"), TagKey.create("bar")); } diff --git a/core/src/test/java/io/opencensus/stats/ViewTest.java b/core/src/test/java/io/opencensus/stats/ViewTest.java index 1089af5dea..6a42c01ac7 100644 --- a/core/src/test/java/io/opencensus/stats/ViewTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewTest.java @@ -22,8 +22,6 @@ import io.opencensus.common.Timestamp; import io.opencensus.stats.DistributionAggregation.Range; import io.opencensus.stats.IntervalAggregation.Interval; -import io.opencensus.stats.MeasurementDescriptor.BasicUnit; -import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; import io.opencensus.stats.View.DistributionView; import io.opencensus.stats.View.IntervalView; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; @@ -46,7 +44,7 @@ public void testDistributionView() { DistributionAggregationDescriptor.create(Arrays.asList(10.0, 20.0, 30.0, 40.0)); final DistributionViewDescriptor viewDescriptor = DistributionViewDescriptor.create( - name, description, measurementDescriptor, aggregationDescriptor, tagKeys); + name, description, measure, aggregationDescriptor, tagKeys); final List aggregations = Arrays.asList( DistributionAggregation.create(5, 5.0, 15.0, Range.create(1.0, 5.0), tags1, Arrays.asList(1L, 1L, 1L, 1L, 1L)), @@ -80,7 +78,7 @@ public void testIntervalView() { IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(111))); final IntervalViewDescriptor viewDescriptor = IntervalViewDescriptor.create( - name, description, measurementDescriptor, aggregationDescriptor, tagKeys); + name, description, measure, aggregationDescriptor, tagKeys); final List aggregations = Arrays.asList( IntervalAggregation.create(tags1, Arrays.asList( Interval.create(Duration.fromMillis(111), 10, 100))), @@ -110,7 +108,7 @@ public void testViewEquals() { DistributionViewDescriptor.create( name, description, - measurementDescriptor, + measure, DistributionAggregationDescriptor.create(Arrays.asList(10.0)), tagKeys); List dAggregations = @@ -121,7 +119,7 @@ public void testViewEquals() { IntervalViewDescriptor.create( name, description, - measurementDescriptor, + measure, IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(111))), tagKeys); List iAggregations = @@ -175,10 +173,10 @@ public void testViewEquals() { // description private final String description = "test-view-descriptor description"; // measurement descriptor - private final MeasurementDescriptor measurementDescriptor = MeasurementDescriptor.create( + private final Measure measure = Measure.DoubleMeasure.create( "measurement-descriptor", "measurement-descriptor description", - MeasurementUnit.create(1, Arrays.asList(BasicUnit.SCALAR))); + "1"); private static final boolean shallowListEquals(List l1, List l2) { if (l1.size() != l2.size()) { diff --git a/core_impl/src/main/java/io/opencensus/stats/MeasurementDescriptorToViewMap.java b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java similarity index 87% rename from core_impl/src/main/java/io/opencensus/stats/MeasurementDescriptorToViewMap.java rename to core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java index 5b39ef97ad..128c1f52db 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MeasurementDescriptorToViewMap.java +++ b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java @@ -28,18 +28,18 @@ import javax.annotation.concurrent.GuardedBy; /** - * A class that stores a singleton map from {@link MeasurementDescriptor.Name}s to {@link + * A class that stores a singleton map from {@code MeasureName}s to {@link * MutableView}s. */ -final class MeasurementDescriptorToViewMap { +final class MeasureToViewMap { /* - * A synchronized singleton map that stores the one-to-many mapping from MeasurementDescriptors + * A synchronized singleton map that stores the one-to-many mapping from Measures * to MutableViews. */ @GuardedBy("this") - private final Multimap mutableMap = - HashMultimap.create(); + private final Multimap mutableMap = + HashMultimap.create(); @GuardedBy("this") private final Map registeredViews = @@ -58,7 +58,7 @@ private synchronized MutableView getMutableView(ViewDescriptor.Name viewName) { return null; } Collection views = - mutableMap.get(viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName()); + mutableMap.get(viewDescriptor.getMeasure().getName()); for (MutableView view : views) { if (view.getViewDescriptor().getViewDescriptorName().equals(viewName)) { return view; @@ -86,14 +86,14 @@ synchronized void registerView(ViewDescriptor viewDescriptor, Clock clock) { new CreateMutableDistributionViewFunction(clock), new CreateMutableIntervalViewFunction()); mutableMap.put( - viewDescriptor.getMeasurementDescriptor().getMeasurementDescriptorName(), mutableView); + viewDescriptor.getMeasure().getName(), mutableView); } // Records stats with a set of tags. synchronized void record(StatsContextImpl tags, MeasurementMap stats) { for (MeasurementValue mv : stats) { Collection views = - mutableMap.get(mv.getMeasurement().getMeasurementDescriptorName()); + mutableMap.get(mv.getMeasurement().getName()); for (MutableView view : views) { view.record(tags, mv.getValue()); } diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java index 97b1c30dfa..7197826d25 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java @@ -25,8 +25,8 @@ final class StatsManager { // clock used throughout the stats implementation private final Clock clock; - private final MeasurementDescriptorToViewMap measurementDescriptorToViewMap = - new MeasurementDescriptorToViewMap(); + private final MeasureToViewMap measureToViewMap = + new MeasureToViewMap(); StatsManager(EventQueue queue, Clock clock) { this.queue = queue; @@ -40,11 +40,11 @@ void registerView(ViewDescriptor viewDescriptor) { throw new UnsupportedOperationException( "The prototype will only support distribution views."); } - measurementDescriptorToViewMap.registerView(viewDescriptor, clock); + measureToViewMap.registerView(viewDescriptor, clock); } View getView(ViewDescriptor.Name viewName) { - View view = measurementDescriptorToViewMap.getView(viewName, clock); + View view = measureToViewMap.getView(viewName, clock); if (view == null) { throw new IllegalArgumentException( "View for view descriptor " + viewName + " not found."); @@ -71,7 +71,7 @@ private static final class StatsEvent implements EventQueue.Entry { @Override public void process() { - viewManager.measurementDescriptorToViewMap.record(tags, stats); + viewManager.measureToViewMap.record(tags, stats); } } } diff --git a/core_impl/src/test/java/io/opencensus/stats/MeasurementDescriptorToViewMapTest.java b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java similarity index 78% rename from core_impl/src/test/java/io/opencensus/stats/MeasurementDescriptorToViewMapTest.java rename to core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java index 0f61803e51..2d691e7fde 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MeasurementDescriptorToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java @@ -18,8 +18,6 @@ import io.opencensus.common.Function; import io.opencensus.common.Timestamp; -import io.opencensus.stats.MeasurementDescriptor.BasicUnit; -import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; import io.opencensus.stats.View.DistributionView; import io.opencensus.stats.View.IntervalView; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; @@ -29,15 +27,15 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link MeasurementDescriptorToViewMap}. */ +/** Tests for {@link MeasureToViewMap}. */ @RunWith(JUnit4.class) -public class MeasurementDescriptorToViewMapTest { +public class MeasureToViewMapTest { - private static final MeasurementDescriptor MEASUREMENT_DESCRIPTOR = - MeasurementDescriptor.create( + private static final Measure MEASUREMENT_DESCRIPTOR = + Measure.DoubleMeasure.create( "my measurement", "measurement description", - MeasurementUnit.create(0, Arrays.asList(BasicUnit.BYTES))); + "By"); private static final ViewDescriptor.Name VIEW_NAME = ViewDescriptor.Name.create("my view"); @@ -51,12 +49,12 @@ public class MeasurementDescriptorToViewMapTest { @Test public void testRegisterAndGetDistributionView() { - MeasurementDescriptorToViewMap measurementDescriptorToViewMap = - new MeasurementDescriptorToViewMap(); + MeasureToViewMap measureToViewMap = + new MeasureToViewMap(); TestClock clock = TestClock.create(Timestamp.create(10, 20)); - measurementDescriptorToViewMap.registerView(VIEW_DESCRIPTOR, clock); + measureToViewMap.registerView(VIEW_DESCRIPTOR, clock); clock.setTime(Timestamp.create(30, 40)); - View actual = measurementDescriptorToViewMap.getView(VIEW_NAME, clock); + View actual = measureToViewMap.getView(VIEW_NAME, clock); actual.match( new Function() { @Override diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index c4d3f98d29..f784d98c8c 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -19,8 +19,6 @@ import io.opencensus.common.Duration; import io.opencensus.common.Timestamp; import io.opencensus.internal.SimpleEventQueue; -import io.opencensus.stats.MeasurementDescriptor.BasicUnit; -import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; import io.opencensus.stats.View.DistributionView; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; @@ -45,19 +43,16 @@ public class ViewManagerImplTest { private static final TagValue VALUE = TagValue.create("VALUE"); private static final TagValue VALUE_2 = TagValue.create("VALUE_2"); - private static final MeasurementDescriptor.Name MEASUREMENT_NAME = - MeasurementDescriptor.Name.create("my measurement"); + private static final String MEASUREMENT_NAME = "my measurement"; - private static final MeasurementDescriptor.Name MEASUREMENT_NAME_2 = - MeasurementDescriptor.Name.create("my measurement 2"); + private static final String MEASUREMENT_NAME_2 = "my measurement 2"; - private static final MeasurementUnit MEASUREMENT_UNIT = - MeasurementUnit.create(-6, Arrays.asList(BasicUnit.SECONDS)); + private static final String MEASUREMENT_UNIT = "us"; private static final String MEASUREMENT_DESCRIPTION = "measurement description"; - private static final MeasurementDescriptor MEASUREMENT_DESCRIPTOR = - MeasurementDescriptor.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); + private static final Measure MEASUREMENT_DESCRIPTOR = + Measure.DoubleMeasure.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); private static final ViewDescriptor.Name VIEW_NAME = ViewDescriptor.Name.create("my view"); private static final ViewDescriptor.Name VIEW_NAME_2 = ViewDescriptor.Name.create("my view 2"); @@ -88,7 +83,7 @@ private static DistributionViewDescriptor createDistributionViewDescriptor() { private static DistributionViewDescriptor createDistributionViewDescriptor( ViewDescriptor.Name name, - MeasurementDescriptor measureDescr, + Measure measureDescr, DistributionAggregationDescriptor aggDescr, List keys) { return DistributionViewDescriptor.create(name, VIEW_DESCRIPTION, measureDescr, aggDescr, keys); @@ -282,11 +277,11 @@ public void testRecordWithNonExistentMeasurementDescriptor() { viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, - MeasurementDescriptor.create(MEASUREMENT_NAME, "measurement", MEASUREMENT_UNIT), + Measure.DoubleMeasure.create(MEASUREMENT_NAME, "measurement", MEASUREMENT_UNIT), DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); - MeasurementDescriptor measure2 = - MeasurementDescriptor.create(MEASUREMENT_NAME_2, "measurement", MEASUREMENT_UNIT); + Measure measure2 = + Measure.DoubleMeasure.create(MEASUREMENT_NAME_2, "measurement", MEASUREMENT_UNIT); statsRecorder.record(createContext(factory, KEY, VALUE), MeasurementMap.of(measure2, 10.0)); DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertThat(view.getDistributionAggregations()).isEmpty(); @@ -403,10 +398,10 @@ public void testMultipleViewsSameMeasure() { @Test public void testMultipleViewsDifferentMeasures() { - MeasurementDescriptor measureDescr1 = - MeasurementDescriptor.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); - MeasurementDescriptor measureDescr2 = - MeasurementDescriptor.create(MEASUREMENT_NAME_2, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); + Measure measureDescr1 = + Measure.DoubleMeasure.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); + Measure measureDescr2 = + Measure.DoubleMeasure.create(MEASUREMENT_NAME_2, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); ViewDescriptor viewDescr1 = createDistributionViewDescriptor( VIEW_NAME, measureDescr1, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); diff --git a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java index 86a4e3dc04..2595b855e9 100644 --- a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java +++ b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java @@ -14,16 +14,13 @@ package io.opencensus.examples.stats; import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.stats.MeasurementDescriptor; -import io.opencensus.stats.MeasurementDescriptor.BasicUnit; -import io.opencensus.stats.MeasurementDescriptor.MeasurementUnit; +import io.opencensus.stats.Measure; import io.opencensus.stats.MeasurementMap; import io.opencensus.stats.Stats; import io.opencensus.stats.StatsContext; import io.opencensus.stats.StatsContextFactory; import io.opencensus.stats.TagKey; import io.opencensus.stats.TagValue; -import java.util.Arrays; /** Simple program that uses Stats contexts. */ public class StatsRunner { @@ -37,12 +34,11 @@ public class StatsRunner { private static final TagValue V3 = TagValue.create("v3"); private static final TagValue V4 = TagValue.create("v4"); - private static final MeasurementUnit simpleMeasurementUnit = - MeasurementUnit.create(1, Arrays.asList(BasicUnit.SCALAR)); - private static final MeasurementDescriptor M1 = - MeasurementDescriptor.create("m1", "1st test metric", simpleMeasurementUnit); - private static final MeasurementDescriptor M2 = - MeasurementDescriptor.create("m2", "2nd test metric", simpleMeasurementUnit); + private static final String UNIT = "1"; + private static final Measure M1 = + Measure.DoubleMeasure.create("m1", "1st test metric", UNIT); + private static final Measure M2 = + Measure.DoubleMeasure.create("m2", "2nd test metric", UNIT); private static final StatsContextFactory factory = Stats.getStatsContextFactory(); private static final StatsContext DEFAULT = factory.getDefault(); From fddce49a1f113de5c9d63062c2a9b336d70f9bde Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Sat, 1 Jul 2017 11:20:45 +0200 Subject: [PATCH 0219/1581] Added error messages to Preconditions checks. --- .../io/opencensus/contrib/agent/AgentMain.java | 12 ++++++------ .../io/opencensus/contrib/agent/Resources.java | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index 03d617dde7..1d612f782a 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -46,20 +46,20 @@ private AgentMain() { * Initializes the OpenCensus Agent for Java. * * @param agentArgs agent options, passed as a single string by the JVM - * @param inst the {@link Instrumentation} object provided by the JVM for instrumenting Java - * programming language code + * @param instrumentation the {@link Instrumentation} object provided by the JVM for + * instrumenting Java programming language code * @throws Exception if initialization of the agent fails * * @see java.lang.instrument */ - public static void premain(String agentArgs, Instrumentation inst) throws Exception { - checkNotNull(inst); + public static void premain(String agentArgs, Instrumentation instrumentation) throws Exception { + checkNotNull(instrumentation, "instrumentation"); logger.info("Initializing."); // The classes in bootstrap.jar will be referenced from classes loaded by the bootstrap // classloader. Thus, these classes have to be loaded by the bootstrap classloader, too. - inst.appendToBootstrapClassLoaderSearch( + instrumentation.appendToBootstrapClassLoaderSearch( new JarFile(Resources.getResourceAsTempFile("bootstrap.jar"))); AgentBuilder agentBuilder = new AgentBuilder.Default() @@ -68,7 +68,7 @@ public static void premain(String agentArgs, Instrumentation inst) throws Except .with(new AgentBuilderListener()) .ignore(none()); // TODO(stschmidt): Add instrumentation for context propagation. - agentBuilder.installOn(inst); + agentBuilder.installOn(instrumentation); logger.info("Initialized."); } diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java index 0ab5bced50..530fe92768 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java @@ -40,7 +40,7 @@ final class Resources { * @throws IOException if an I/O error occurs */ static File getResourceAsTempFile(String resourceName) throws IOException { - checkArgument(!Strings.isNullOrEmpty(resourceName)); + checkArgument(!Strings.isNullOrEmpty(resourceName), "resourceName"); File file = File.createTempFile(resourceName, ".tmp"); try (OutputStream os = new FileOutputStream(file)) { @@ -50,20 +50,20 @@ static File getResourceAsTempFile(String resourceName) throws IOException { } @VisibleForTesting - static void getResourceAsTempFile(String resourceName, File file, OutputStream os) + static void getResourceAsTempFile(String resourceName, File file, OutputStream outputStream) throws IOException { - checkArgument(!Strings.isNullOrEmpty(resourceName)); - checkNotNull(file); - checkNotNull(os); + checkArgument(!Strings.isNullOrEmpty(resourceName), "resourceName"); + checkNotNull(file, "file"); + checkNotNull(outputStream, "outputStream"); try (InputStream is = getResourceAsStream(resourceName)) { file.deleteOnExit(); - ByteStreams.copy(is, os); + ByteStreams.copy(is, outputStream); } } private static InputStream getResourceAsStream(String resourceName) throws FileNotFoundException { - checkArgument(!Strings.isNullOrEmpty(resourceName)); + checkArgument(!Strings.isNullOrEmpty(resourceName), "resourceName"); InputStream is = Resources.class.getResourceAsStream(resourceName); if (is == null) { From bac6f5a3afd0af6680ad7837ce22c56fcb2d22ee Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Sat, 1 Jul 2017 15:41:16 +0200 Subject: [PATCH 0220/1581] Mark file for delete on exit first. --- .../src/main/java/io/opencensus/contrib/agent/Resources.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java index 530fe92768..db24dc4140 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/Resources.java @@ -56,8 +56,9 @@ static void getResourceAsTempFile(String resourceName, File file, OutputStream o checkNotNull(file, "file"); checkNotNull(outputStream, "outputStream"); + file.deleteOnExit(); + try (InputStream is = getResourceAsStream(resourceName)) { - file.deleteOnExit(); ByteStreams.copy(is, outputStream); } } From 93641e81ad38377e905cc14833a640480d96007e Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 4 Jul 2017 00:28:23 +0200 Subject: [PATCH 0221/1581] Upgrade to Gradle 3.5. I've run the following command line: ./gradlew wrapper --gradle-version=3.5 Among other things, this fixes the issue described in https://github.com/gradle/gradle/issues/1387 ("Exception: java.lang.IllegalStateException thrown from the UncaughtExceptionHandler in thread..."). I've run into this issue when adding more instrumentation logic to the Java agent. It makes debugging the actual issue nearly impossible as any useful debug output is lost. While there, also upgrade the errorprone-plugin to 0.0.10 (was 0.0.9) because the previous version is broken in Gradle 3.5, cf. https://github.com/tbroyer/gradle-errorprone-plugin/issues/37. --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 54212 -> 54212 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 319a3bf36f..2ca6b295bb 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.3.0' - classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.9' + classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.10' classpath "net.ltgt.gradle:gradle-apt-plugin:0.10" } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2942b5023498c9800581d7562e88981472ec705d..e963759cbac1b5cb57af132b0be81a3aa0870a17 100644 GIT binary patch delta 26 gcmX@IocYLd<_)ojn9Z1?IsgCw diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e560f34c49..c5cc309a1e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Mar 18 12:22:37 PDT 2017 +#Tue Jul 04 00:25:44 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip From f93d676f532e1a351eb8028bf8441b9e2cb165d9 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 3 Jul 2017 15:28:24 -0700 Subject: [PATCH 0222/1581] Change tracer API names to create a SpanBuilder. (#407) --- .../java/io/opencensus/trace/SpanBuilder.java | 34 +++++----- .../main/java/io/opencensus/trace/Tracer.java | 65 ++++++++++--------- .../trace/propagation/BinaryFormat.java | 2 +- .../java/io/opencensus/trace/TracerTest.java | 20 +++--- ...ordTraceEventsNonSampledSpanBenchmark.java | 10 ++- ...RecordTraceEventsSampledSpanBenchmark.java | 10 ++- .../trace/StartEndSpanBenchmark.java | 24 +++++-- .../BinaryPropagationImplBenchmark.java | 6 +- .../trace/MultiSpansContextTracing.java | 2 +- .../trace/MultiSpansScopedTracing.java | 2 +- .../examples/trace/MultiSpansTracing.java | 4 +- .../io/opencensus/trace/SpanBuilderImpl.java | 33 +++++----- .../java/io/opencensus/trace/TracerImpl.java | 10 +-- .../opencensus/trace/SpanBuilderImplTest.java | 46 +++++++------ .../io/opencensus/trace/TracerImplTest.java | 4 +- 15 files changed, 155 insertions(+), 117 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/SpanBuilder.java b/api/src/main/java/io/opencensus/trace/SpanBuilder.java index f573d9a65c..be55906f95 100644 --- a/api/src/main/java/io/opencensus/trace/SpanBuilder.java +++ b/api/src/main/java/io/opencensus/trace/SpanBuilder.java @@ -86,14 +86,14 @@ *

            {@code
              * class MyClass {
              *   private static final Tracer tracer = Tracing.getTracer();
            - *   void DoWork() {
            - *     Span span = tracer.spanBuilder(null, "MyRootSpan").startSpan();
            - *     span.addAnnotation("my annotation");
            + *   void DoWork(Span parent) {
            + *     Span childSpan = tracer.spanBuilderWithExplicitParent("MyChildSpan", parent).startSpan();
            + *     childSpan.addAnnotation("my annotation");
              *     try {
            - *       doSomeWork(span); // Manually propagate the new span down the stack.
            + *       doSomeWork(childSpan); // Manually propagate the new span down the stack.
              *     } finally {
              *       // To make sure we end the span even in case of an exception.
            - *       span.end();  // Manually end the span.
            + *       childSpan.end();  // Manually end the span.
              *     }
              *   }
              * }
            @@ -145,14 +145,14 @@ public abstract class SpanBuilder {
                * 
            {@code
                * class MyClass {
                *   private static final Tracer tracer = Tracing.getTracer();
            -   *   void DoWork() {
            -   *     Span span = tracer.spanBuilder(null, "MyRootSpan").startSpan();
            -   *     span.addAnnotation("my annotation");
            +   *   void DoWork(Span parent) {
            +   *     Span childSpan = tracer.spanBuilderWithExplicitParent("MyChildSpan", parent).startSpan();
            +   *     childSpan.addAnnotation("my annotation");
                *     try {
            -   *       doSomeWork(span); // Manually propagate the new span down the stack.
            +   *       doSomeWork(childSpan); // Manually propagate the new span down the stack.
                *     } finally {
                *       // To make sure we end the span even in case of an exception.
            -   *       span.end();  // Manually end the span.
            +   *       childSpan.end();  // Manually end the span.
                *     }
                *   }
                * }
            @@ -222,13 +222,13 @@ public final NonThrowingCloseable startScopedSpan() {
               }
             
               static final class NoopSpanBuilder extends SpanBuilder {
            -    NoopSpanBuilder(@Nullable Span parentSpan, String name) {
            -      checkNotNull(name, "name");
            +    static NoopSpanBuilder createWithParent(String spanName, @Nullable Span parent) {
            +      return new NoopSpanBuilder(spanName);
                 }
             
            -    NoopSpanBuilder(SpanContext remoteParentSpanContext, String name) {
            -      checkNotNull(remoteParentSpanContext, "remoteParentSpanContext");
            -      checkNotNull(name, "name");
            +    static NoopSpanBuilder createWithRemoteParent(
            +        String spanName, @Nullable SpanContext remoteParentSpanContext) {
            +      return new NoopSpanBuilder(spanName);
                 }
             
                 @Override
            @@ -250,5 +250,9 @@ public SpanBuilder setParentLinks(List parentLinks) {
                 public SpanBuilder setRecordEvents(boolean recordEvents) {
                   return this;
                 }
            +
            +    private NoopSpanBuilder(String name) {
            +      checkNotNull(name, "name");
            +    }
               }
             }
            diff --git a/api/src/main/java/io/opencensus/trace/Tracer.java b/api/src/main/java/io/opencensus/trace/Tracer.java
            index ef5616a9fd..97cd0998a6 100644
            --- a/api/src/main/java/io/opencensus/trace/Tracer.java
            +++ b/api/src/main/java/io/opencensus/trace/Tracer.java
            @@ -16,6 +16,7 @@
             import static com.google.common.base.Preconditions.checkNotNull;
             
             import io.opencensus.common.NonThrowingCloseable;
            +import io.opencensus.trace.SpanBuilder.NoopSpanBuilder;
             import javax.annotation.Nullable;
             
             /**
            @@ -49,15 +50,14 @@
              * 
            {@code
              * class MyClass {
              *   private static final Tracer tracer = Tracing.getTracer();
            - *   void doWork() {
            - *     Span span = tracer.spanBuilder(null, "MyRootSpan").startSpan();
            - *     span.addAnnotation("Starting the work.");
            + *   void doWork(Span parent) {
            + *     Span childSpan = tracer.spanBuilderWithExplicitParent("MyChildSpan", parent).startSpan();
            + *     childSpan.addAnnotation("Starting the work.");
              *     try {
            - *       doSomeWork(span); // Manually propagate the new span down the stack.
            + *       doSomeWork(childSpan); // Manually propagate the new span down the stack.
              *     } finally {
            - *       span.addAnnotation("Finished working.");
              *       // To make sure we end the span even in case of an exception.
            - *       span.end();  // Manually end the span.
            + *       childSpan.end();  // Manually end the span.
              *     }
              *   }
              * }
            @@ -139,7 +139,7 @@ public final Span getCurrentSpan() {
                * @param span The {@link Span} to be set to the current Context.
                * @return an object that defines a scope where the given {@link Span} will be set to the current
                *     Context.
            -   * @throws NullPointerException if {@code span} is null.
            +   * @throws NullPointerException if {@code span} is {@code null}.
                */
               public final NonThrowingCloseable withSpan(Span span) {
                 return ContextUtils.withSpan(checkNotNull(span, "span"));
            @@ -154,12 +154,18 @@ public final NonThrowingCloseable withSpan(Span span) {
                * 

            This must be used to create a {@code Span} when automatic Context propagation is * used. * - * @param name The name of the returned Span. + *

            This is equivalent with: + * + *

            {@code
            +   * tracer.spanBuilderWithExplicitParent("MySpanName",tracer.getCurrentSpan());
            +   * }
            + * + * @param spanName The name of the returned Span. * @return a {@code SpanBuilder} to create and start a new {@code Span}. - * @throws NullPointerException if {@code name} is null. + * @throws NullPointerException if {@code spanName} is {@code null}. */ - public final SpanBuilder spanBuilder(String name) { - return spanBuilder(ContextUtils.getCurrentSpan(), name); + public final SpanBuilder spanBuilder(String spanName) { + return spanBuilderWithExplicitParent(spanName, ContextUtils.getCurrentSpan()); } /** @@ -169,51 +175,50 @@ public final SpanBuilder spanBuilder(String name) { * *

            See {@link SpanBuilder} for usage examples. * - *

            This must be used to create a {@code Span} when manual Context propagation is used - * OR when creating a root {@code Span} with a {@code null} parent. + *

            This must be used to create a {@code Span} when manual Context propagation is used OR + * when creating a root {@code Span} with a {@code null} parent. * - * @param parent The parent of the returned Span. If null the {@code SpanBuilder} will build a - * root {@code Span}. - * @param name The name of the returned Span. + * @param spanName The name of the returned Span. + * @param parent The parent of the returned Span. If {@code null} the {@code SpanBuilder} will + * build a root {@code Span}. * @return a {@code SpanBuilder} to create and start a new {@code Span}. - * @throws NullPointerException if {@code name} is null. + * @throws NullPointerException if {@code spanName} is {@code null}. */ - public abstract SpanBuilder spanBuilder(@Nullable Span parent, String name); + public abstract SpanBuilder spanBuilderWithExplicitParent(String spanName, @Nullable Span parent); /** * Returns a {@link SpanBuilder} to create and start a new child {@link Span} (or root if parent - * is an invalid {@link SpanContext}), with parent being the {@link Span} designated by the {@link - * SpanContext}. + * is {@link SpanContext#INVALID} or {@code null}), with parent being the remote {@link Span} + * designated by the {@link SpanContext}. * *

            See {@link SpanBuilder} for usage examples. * *

            This must be used to create a {@code Span} when the parent is in a different process. * This is only intended for use by RPC systems or similar. * - *

            If no {@link SpanContext} OR fail to parse the {@link SpanContext} on the server side, - * users must call this method with an {@link SpanContext#INVALID} remote parent {@code - * SpanContext}. + *

            If no {@link SpanContext} OR fail to parse the {@link SpanContext} on the server side, users + * must call this method with a {@code null} remote parent {@code SpanContext}. * + * @param spanName The name of the returned Span. * @param remoteParentSpanContext The remote parent of the returned Span. - * @param name The name of the returned Span. * @return a {@code SpanBuilder} to create and start a new {@code Span}. - * @throws NullPointerException if {@code name} or {@code remoteParentSpanContext} are null. + * @throws NullPointerException if {@code spanName} is {@code null}. */ public abstract SpanBuilder spanBuilderWithRemoteParent( - SpanContext remoteParentSpanContext, String name); + String spanName, @Nullable SpanContext remoteParentSpanContext); // No-Op implementation of the Tracer. private static final class NoopTracer extends Tracer { @Override - public SpanBuilder spanBuilder(@Nullable Span parent, String name) { - return new SpanBuilder.NoopSpanBuilder(parent, name); + public SpanBuilder spanBuilderWithExplicitParent(String spanName, @Nullable Span parent) { + return NoopSpanBuilder.createWithParent(spanName, parent); } @Override public SpanBuilder spanBuilderWithRemoteParent( - SpanContext remoteParentSpanContext, String name) { - return new SpanBuilder.NoopSpanBuilder(remoteParentSpanContext, name); + String spanName, @Nullable SpanContext remoteParentSpanContext) { + return NoopSpanBuilder.createWithRemoteParent(spanName, remoteParentSpanContext); } private NoopTracer() {} diff --git a/api/src/main/java/io/opencensus/trace/propagation/BinaryFormat.java b/api/src/main/java/io/opencensus/trace/propagation/BinaryFormat.java index d34f69f9dd..284576ec85 100644 --- a/api/src/main/java/io/opencensus/trace/propagation/BinaryFormat.java +++ b/api/src/main/java/io/opencensus/trace/propagation/BinaryFormat.java @@ -52,7 +52,7 @@ * // Maybe log the exception. * } * try (NonThrowingCloseable ss = - * tracer.spanBuilderWithRemoteParent(spanContext, "Recv.MyRequest").startScopedSpan()) { + * tracer.spanBuilderWithRemoteParent("Recv.MyRequest", spanContext).startScopedSpan()) { * // Handle request and send response back. * } * } diff --git a/api/src/test/java/io/opencensus/trace/TracerTest.java b/api/src/test/java/io/opencensus/trace/TracerTest.java index 3c69068ba2..a0830428ee 100644 --- a/api/src/test/java/io/opencensus/trace/TracerTest.java +++ b/api/src/test/java/io/opencensus/trace/TracerTest.java @@ -101,12 +101,13 @@ public void defaultSpanBuilderWithName() { @Test(expected = NullPointerException.class) public void spanBuilderWithParentAndName_NullName() { - noopTracer.spanBuilder(null, null); + noopTracer.spanBuilderWithExplicitParent(null, null); } @Test public void defaultSpanBuilderWithParentAndName() { - assertThat(noopTracer.spanBuilder(null, SPAN_NAME).startSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat(noopTracer.spanBuilderWithExplicitParent(SPAN_NAME, null).startSpan()) + .isSameAs(BlankSpan.INSTANCE); } @Test(expected = NullPointerException.class) @@ -114,14 +115,15 @@ public void spanBuilderWithRemoteParent_NullName() { noopTracer.spanBuilderWithRemoteParent(null, null); } - @Test(expected = NullPointerException.class) - public void defaultSpanBuilderWitRemoteParent_NullParent() { - noopTracer.spanBuilderWithRemoteParent(null, SPAN_NAME); + @Test + public void defaultSpanBuilderWithRemoteParent_NullParent() { + assertThat(noopTracer.spanBuilderWithRemoteParent(SPAN_NAME, null).startSpan()) + .isSameAs(BlankSpan.INSTANCE); } @Test public void defaultSpanBuilderWithRemoteParent() { - assertThat(noopTracer.spanBuilderWithRemoteParent(SpanContext.INVALID, SPAN_NAME).startSpan()) + assertThat(noopTracer.spanBuilderWithRemoteParent(SPAN_NAME, SpanContext.INVALID).startSpan()) .isSameAs(BlankSpan.INSTANCE); } @@ -130,7 +132,8 @@ public void startSpanWithParentFromContext() { NonThrowingCloseable ws = tracer.withSpan(span); try { assertThat(tracer.getCurrentSpan()).isSameAs(span); - when(tracer.spanBuilder(same(span), same(SPAN_NAME))).thenReturn(spanBuilder); + when(tracer.spanBuilderWithExplicitParent(same(SPAN_NAME), same(span))) + .thenReturn(spanBuilder); assertThat(tracer.spanBuilder(SPAN_NAME)).isSameAs(spanBuilder); } finally { ws.close(); @@ -142,7 +145,8 @@ public void startSpanWithInvalidParentFromContext() { NonThrowingCloseable ws = tracer.withSpan(BlankSpan.INSTANCE); try { assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); - when(tracer.spanBuilder(same(BlankSpan.INSTANCE), same(SPAN_NAME))).thenReturn(spanBuilder); + when(tracer.spanBuilderWithExplicitParent(same(SPAN_NAME), same(BlankSpan.INSTANCE))) + .thenReturn(spanBuilder); assertThat(tracer.spanBuilder(SPAN_NAME)).isSameAs(spanBuilder); } finally { ws.close(); diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java index 06a1412ffd..ebc30072e6 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java @@ -36,9 +36,15 @@ public class RecordTraceEventsNonSampledSpanBenchmark { private static final String ATTRIBUTE_KEY = "MyAttributeKey"; private static final String ATTRIBUTE_VALUE = "MyAttributeValue"; private Span linkedSpan = - tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); + tracer + .spanBuilderWithExplicitParent(SPAN_NAME, null) + .setSampler(Samplers.neverSample()) + .startSpan(); private Span span = - tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); + tracer + .spanBuilderWithExplicitParent(SPAN_NAME, null) + .setSampler(Samplers.neverSample()) + .startSpan(); /** TearDown method. */ @TearDown diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java index 5773923ff4..6a80a26d97 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java @@ -36,9 +36,15 @@ public class RecordTraceEventsSampledSpanBenchmark { private static final String ATTRIBUTE_KEY = "MyAttributeKey"; private static final String ATTRIBUTE_VALUE = "MyAttributeValue"; private Span linkedSpan = - tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.alwaysSample()).startSpan(); + tracer + .spanBuilderWithExplicitParent(SPAN_NAME, null) + .setSampler(Samplers.alwaysSample()) + .startSpan(); private Span span = - tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.alwaysSample()).startSpan(); + tracer + .spanBuilderWithExplicitParent(SPAN_NAME, null) + .setSampler(Samplers.alwaysSample()) + .startSpan(); /** TearDown method. */ @TearDown diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java index 8418184ff2..6827c097da 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java @@ -29,7 +29,10 @@ public class StartEndSpanBenchmark { private static final Tracer tracer = Tracing.getTracer(); private static final String SPAN_NAME = "MySpanName"; private Span rootSpan = - tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); + tracer + .spanBuilderWithExplicitParent(SPAN_NAME, null) + .setSampler(Samplers.neverSample()) + .startSpan(); @TearDown public void doTearDown() { @@ -45,7 +48,10 @@ public void doTearDown() { @OutputTimeUnit(TimeUnit.NANOSECONDS) public Span startEndNonSampledRootSpan() { Span span = - tracer.spanBuilder(null, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); + tracer + .spanBuilderWithExplicitParent(SPAN_NAME, null) + .setSampler(Samplers.neverSample()) + .startSpan(); span.end(); return span; } @@ -60,7 +66,7 @@ public Span startEndNonSampledRootSpan() { public Span startEndRecordEventsRootSpan() { Span span = tracer - .spanBuilder(null, SPAN_NAME) + .spanBuilderWithExplicitParent(SPAN_NAME, null) .setSampler(Samplers.neverSample()) .setRecordEvents(true) .startSpan(); @@ -89,7 +95,10 @@ public Span startEndSampledRootSpan() { @OutputTimeUnit(TimeUnit.NANOSECONDS) public Span startEndNonSampledChildSpan() { Span span = - tracer.spanBuilder(rootSpan, SPAN_NAME).setSampler(Samplers.neverSample()).startSpan(); + tracer + .spanBuilderWithExplicitParent(SPAN_NAME, rootSpan) + .setSampler(Samplers.neverSample()) + .startSpan(); span.end(); return span; } @@ -104,7 +113,7 @@ public Span startEndNonSampledChildSpan() { public Span startEndRecordEventsChildSpan() { Span span = tracer - .spanBuilder(rootSpan, SPAN_NAME) + .spanBuilderWithExplicitParent(SPAN_NAME, rootSpan) .setSampler(Samplers.neverSample()) .setRecordEvents(true) .startSpan(); @@ -120,7 +129,10 @@ public Span startEndRecordEventsChildSpan() { @OutputTimeUnit(TimeUnit.NANOSECONDS) public Span startEndSampledChildSpan() { Span span = - tracer.spanBuilder(rootSpan, SPAN_NAME).setSampler(Samplers.alwaysSample()).startSpan(); + tracer + .spanBuilderWithExplicitParent(SPAN_NAME, rootSpan) + .setSampler(Samplers.alwaysSample()) + .startSpan(); span.end(); return span; } diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java index 4a49b9c891..d99f0dbd02 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java @@ -38,8 +38,7 @@ public class BinaryPropagationImplBenchmark { private static final TraceOptions traceOptions = TraceOptions.fromBytes(traceOptionsBytes); private static final SpanContext spanContext = SpanContext.create(traceId, spanId, traceOptions); private static final BinaryFormat BINARY_PROPAGATION = new BinaryFormatImpl(); - private static final byte[] spanContextBinary = - BINARY_PROPAGATION.toBinaryValue(spanContext); + private static final byte[] spanContextBinary = BINARY_PROPAGATION.toBinaryValue(spanContext); /** * This benchmark attempts to measure performance of {@link @@ -72,7 +71,6 @@ public SpanContext fromBinaryValueSpanContext() throws ParseException { @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public SpanContext toFromBinarySpanContext() throws ParseException { - return BINARY_PROPAGATION.fromBinaryValue( - BINARY_PROPAGATION.toBinaryValue(spanContext)); + return BINARY_PROPAGATION.fromBinaryValue(BINARY_PROPAGATION.toBinaryValue(spanContext)); } } diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java index c6fa0317a7..b59ba01e33 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java @@ -49,7 +49,7 @@ private static void doWork() { /** Main method. */ public static void main(String[] args) { LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); - Span span = tracer.spanBuilder(null,"MyRootSpan").startSpan(); + Span span = tracer.spanBuilderWithExplicitParent("MyRootSpan", null).startSpan(); try (NonThrowingCloseable ws = tracer.withSpan(span)) { doWork(); } diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java index 547403bb7d..c73c3cc279 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java @@ -48,7 +48,7 @@ private static void doWork() { public static void main(String[] args) { LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); try (NonThrowingCloseable ss = - tracer.spanBuilder(null,"MyRootSpan").startScopedSpan()) { + tracer.spanBuilderWithExplicitParent("MyRootSpan", null).startScopedSpan()) { doWork(); } } diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java index 6b8f3ed60b..25f71973f1 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java @@ -24,9 +24,9 @@ public final class MultiSpansTracing { private static final Tracer tracer = Tracing.getTracer(); private static void doWork() { - Span rootSpan = tracer.spanBuilder(null, "MyRootSpan").startSpan(); + Span rootSpan = tracer.spanBuilderWithExplicitParent("MyRootSpan", null).startSpan(); rootSpan.addAnnotation("Annotation to the root Span before child is created."); - Span childSpan = tracer.spanBuilder(rootSpan, "MyChildSpan").startSpan(); + Span childSpan = tracer.spanBuilderWithExplicitParent("MyChildSpan", rootSpan).startSpan(); childSpan.addAnnotation("Annotation to the child Span"); childSpan.end(); rootSpan.addAnnotation("Annotation to the root Span after child is ended."); diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java index 74a4ae34f5..f9a0bf0c56 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java @@ -37,13 +37,13 @@ final class SpanBuilderImpl extends SpanBuilder { private final Options options; private final String name; - private final Span parentSpan; + private final Span parent; private final SpanContext remoteParentSpanContext; private Sampler sampler; private List parentLinks = Collections.emptyList(); private Boolean recordEvents; - private Span startSpanInternal( + private SpanImpl startSpanInternal( @Nullable SpanContext parent, boolean hasRemoteParent, String name, @@ -80,7 +80,7 @@ private Span startSpanInternal( if (traceOptions.isSampled() || Boolean.TRUE.equals(recordEvents)) { spanOptions.add(Span.Options.RECORD_EVENTS); } - Span span = + SpanImpl span = SpanImpl.startSpan( SpanContext.create(traceId, spanId, traceOptions), spanOptions, @@ -105,36 +105,35 @@ private static void linkSpans(Span span, List parentLinks) { } } - static SpanBuilder createBuilder(@Nullable Span parentSpan, String name, Options options) { - return new SpanBuilderImpl(parentSpan, null, name, options); + static SpanBuilderImpl createWithParent(String spanName, @Nullable Span parent, Options options) { + return new SpanBuilderImpl(spanName, null, parent, options); } - static SpanBuilder createBuilderWithRemoteParent( - SpanContext remoteParentSpanContext, String name, Options options) { - return new SpanBuilderImpl(null, checkNotNull(remoteParentSpanContext, - "remoteParentSpanContext"), name, options); + static SpanBuilderImpl createWithRemoteParent( + String spanName, @Nullable SpanContext remoteParentSpanContext, Options options) { + return new SpanBuilderImpl(spanName, remoteParentSpanContext, null, options); } private SpanBuilderImpl( - @Nullable Span parentSpan, - @Nullable SpanContext remoteParentSpanContext, String name, + @Nullable SpanContext remoteParentSpanContext, + @Nullable Span parent, Options options) { this.name = checkNotNull(name, "name"); - this.parentSpan = parentSpan; + this.parent = parent; this.remoteParentSpanContext = remoteParentSpanContext; this.options = options; } @Override - public Span startSpan() { + public SpanImpl startSpan() { SpanContext parentContext = remoteParentSpanContext; boolean hasRemoteParent = parentContext != null; TimestampConverter timestampConverter = null; if (!hasRemoteParent) { // This is not a child of a remote Span. Get the parent SpanContext from the parent Span if // any. - Span parent = parentSpan; + Span parent = this.parent; if (parent != null) { parentContext = parent.getContext(); // Pass the timestamp converter from the parent to ensure that the recorded events are in @@ -173,19 +172,19 @@ static final class Options { } @Override - public SpanBuilder setSampler(Sampler sampler) { + public SpanBuilderImpl setSampler(Sampler sampler) { this.sampler = checkNotNull(sampler, "sampler"); return this; } @Override - public SpanBuilder setParentLinks(List parentLinks) { + public SpanBuilderImpl setParentLinks(List parentLinks) { this.parentLinks = checkNotNull(parentLinks, "parentLinks"); return this; } @Override - public SpanBuilder setRecordEvents(boolean recordEvents) { + public SpanBuilderImpl setRecordEvents(boolean recordEvents) { this.recordEvents = recordEvents; return this; } diff --git a/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java b/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java index b15a8b9903..0dfdf361cb 100644 --- a/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java @@ -32,14 +32,14 @@ final class TracerImpl extends Tracer { } @Override - public SpanBuilder spanBuilder(@Nullable Span parent, String name) { - return SpanBuilderImpl.createBuilder(parent, name, spanBuilderOptions); + public SpanBuilder spanBuilderWithExplicitParent(String spanName, @Nullable Span parent) { + return SpanBuilderImpl.createWithParent(spanName, parent, spanBuilderOptions); } @Override public SpanBuilder spanBuilderWithRemoteParent( - SpanContext remoteParentSpanContext, String name) { - return SpanBuilderImpl.createBuilderWithRemoteParent( - remoteParentSpanContext, name, spanBuilderOptions); + String spanName, @Nullable SpanContext remoteParentSpanContext) { + return SpanBuilderImpl.createWithRemoteParent( + spanName, remoteParentSpanContext, spanBuilderOptions); } } diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java index afcd3b8b03..3e827485e1 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java @@ -57,12 +57,12 @@ public void setUp() { @Test public void startSpanNullParent() { - Span span = SpanBuilderImpl.createBuilder(null, SPAN_NAME, spanBuilderOptions).startSpan(); + SpanImpl span = + SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions).startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); - assertThat(span instanceof SpanImpl).isTrue(); - SpanData spanData = ((SpanImpl) span).toSpanData(); + SpanData spanData = span.toSpanData(); assertThat(spanData.getParentSpanId()).isNull(); assertThat(spanData.getHasRemoteParent()).isFalse(); assertThat(spanData.getStartTimestamp()).isEqualTo(testClock.now()); @@ -71,16 +71,15 @@ public void startSpanNullParent() { @Test public void startSpanNullParentWithRecordEvents() { - Span span = - SpanBuilderImpl.createBuilder(null, SPAN_NAME, spanBuilderOptions) + SpanImpl span = + SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions) .setSampler(Samplers.neverSample()) .setRecordEvents(true) .startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(span.getContext().getTraceOptions().isSampled()).isFalse(); - assertThat(span instanceof SpanImpl).isTrue(); - SpanData spanData = ((SpanImpl) span).toSpanData(); + SpanData spanData = span.toSpanData(); assertThat(spanData.getParentSpanId()).isNull(); assertThat(spanData.getHasRemoteParent()).isFalse(); } @@ -88,7 +87,7 @@ public void startSpanNullParentWithRecordEvents() { @Test public void startSpanNullParentNoRecordOptions() { Span span = - SpanBuilderImpl.createBuilder(null, SPAN_NAME, spanBuilderOptions) + SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions) .setSampler(Samplers.neverSample()) .startSpan(); assertThat(span.getContext().isValid()).isTrue(); @@ -98,12 +97,13 @@ public void startSpanNullParentNoRecordOptions() { @Test public void startChildSpan() { - Span rootSpan = SpanBuilderImpl.createBuilder(null, SPAN_NAME, spanBuilderOptions).startSpan(); + Span rootSpan = + SpanBuilderImpl.createWithParent(SPAN_NAME, null, spanBuilderOptions).startSpan(); assertThat(rootSpan.getContext().isValid()).isTrue(); assertThat(rootSpan.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isTrue(); Span childSpan = - SpanBuilderImpl.createBuilder(rootSpan, SPAN_NAME, spanBuilderOptions).startSpan(); + SpanBuilderImpl.createWithParent(SPAN_NAME, rootSpan, spanBuilderOptions).startSpan(); assertThat(childSpan.getContext().isValid()).isTrue(); assertThat(childSpan.getContext().getTraceId()).isEqualTo(rootSpan.getContext().getTraceId()); assertThat(((SpanImpl) childSpan).toSpanData().getParentSpanId()) @@ -112,22 +112,27 @@ public void startChildSpan() { .isEqualTo(((SpanImpl) rootSpan).getTimestampConverter()); } - @Test(expected = NullPointerException.class) + @Test public void startRemoteSpan_NullParent() { - SpanBuilderImpl.createBuilderWithRemoteParent(null, SPAN_NAME, spanBuilderOptions); + SpanImpl span = + SpanBuilderImpl.createWithRemoteParent(SPAN_NAME, null, spanBuilderOptions).startSpan(); + assertThat(span.getContext().isValid()).isTrue(); + assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); + assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); + SpanData spanData = span.toSpanData(); + assertThat(spanData.getParentSpanId()).isNull(); + assertThat(spanData.getHasRemoteParent()).isFalse(); } @Test public void startRemoteSpanInvalidParent() { - Span span = - SpanBuilderImpl.createBuilderWithRemoteParent( - SpanContext.INVALID, SPAN_NAME, spanBuilderOptions) + SpanImpl span = + SpanBuilderImpl.createWithRemoteParent(SPAN_NAME, SpanContext.INVALID, spanBuilderOptions) .startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); - assertThat(span instanceof SpanImpl).isTrue(); - SpanData spanData = ((SpanImpl) span).toSpanData(); + SpanData spanData = span.toSpanData(); assertThat(spanData.getParentSpanId()).isNull(); assertThat(spanData.getHasRemoteParent()).isFalse(); } @@ -139,14 +144,13 @@ public void startRemoteSpan() { TraceId.generateRandomId(randomHandler.current()), SpanId.generateRandomId(randomHandler.current()), TraceOptions.DEFAULT); - Span span = - SpanBuilderImpl.createBuilderWithRemoteParent(spanContext, SPAN_NAME, spanBuilderOptions) + SpanImpl span = + SpanBuilderImpl.createWithRemoteParent(SPAN_NAME, spanContext, spanBuilderOptions) .startSpan(); assertThat(span.getContext().isValid()).isTrue(); assertThat(span.getContext().getTraceId()).isEqualTo(spanContext.getTraceId()); assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); - assertThat(span instanceof SpanImpl).isTrue(); - SpanData spanData = ((SpanImpl) span).toSpanData(); + SpanData spanData = span.toSpanData(); assertThat(spanData.getParentSpanId()).isEqualTo(spanContext.getSpanId()); assertThat(spanData.getHasRemoteParent()).isTrue(); } diff --git a/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java b/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java index 9ee70c98be..1cb27e20bd 100644 --- a/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java @@ -43,13 +43,13 @@ public void setUp() { @Test public void createSpanBuilder() { - SpanBuilder spanBuilder = tracer.spanBuilder(BlankSpan.INSTANCE, SPAN_NAME); + SpanBuilder spanBuilder = tracer.spanBuilderWithExplicitParent(SPAN_NAME, BlankSpan.INSTANCE); assertThat(spanBuilder).isInstanceOf(SpanBuilderImpl.class); } @Test public void createSpanBuilderWithRemoteParet() { - SpanBuilder spanBuilder = tracer.spanBuilderWithRemoteParent(SpanContext.INVALID, SPAN_NAME); + SpanBuilder spanBuilder = tracer.spanBuilderWithRemoteParent(SPAN_NAME, SpanContext.INVALID); assertThat(spanBuilder).isInstanceOf(SpanBuilderImpl.class); } } From 4f17a4687bc05c06f2f97092d023059ac1c41e94 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 4 Jul 2017 10:43:57 -0700 Subject: [PATCH 0223/1581] Mark benchmark variables to be final. Add javadoc for main argument. (#409) --- .../trace/RecordTraceEventsNonSampledSpanBenchmark.java | 4 ++-- .../trace/RecordTraceEventsSampledSpanBenchmark.java | 4 ++-- .../jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java | 2 +- .../main/java/io/opencensus/examples/stats/StatsRunner.java | 6 +++++- .../opencensus/examples/trace/MultiSpansContextTracing.java | 6 +++++- .../opencensus/examples/trace/MultiSpansScopedTracing.java | 6 +++++- .../io/opencensus/examples/trace/MultiSpansTracing.java | 6 +++++- 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java index ebc30072e6..2a6872d002 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java @@ -35,12 +35,12 @@ public class RecordTraceEventsNonSampledSpanBenchmark { private static final String ANNOTATION_DESCRIPTION = "MyAnnotation"; private static final String ATTRIBUTE_KEY = "MyAttributeKey"; private static final String ATTRIBUTE_VALUE = "MyAttributeValue"; - private Span linkedSpan = + private final Span linkedSpan = tracer .spanBuilderWithExplicitParent(SPAN_NAME, null) .setSampler(Samplers.neverSample()) .startSpan(); - private Span span = + private final Span span = tracer .spanBuilderWithExplicitParent(SPAN_NAME, null) .setSampler(Samplers.neverSample()) diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java index 6a80a26d97..db591f55c9 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java @@ -35,12 +35,12 @@ public class RecordTraceEventsSampledSpanBenchmark { private static final String ANNOTATION_DESCRIPTION = "MyAnnotation"; private static final String ATTRIBUTE_KEY = "MyAttributeKey"; private static final String ATTRIBUTE_VALUE = "MyAttributeValue"; - private Span linkedSpan = + private final Span linkedSpan = tracer .spanBuilderWithExplicitParent(SPAN_NAME, null) .setSampler(Samplers.alwaysSample()) .startSpan(); - private Span span = + private final Span span = tracer .spanBuilderWithExplicitParent(SPAN_NAME, null) .setSampler(Samplers.alwaysSample()) diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java index 6827c097da..c952fc4306 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java @@ -28,7 +28,7 @@ public class StartEndSpanBenchmark { private static final Tracer tracer = Tracing.getTracer(); private static final String SPAN_NAME = "MySpanName"; - private Span rootSpan = + private final Span rootSpan = tracer .spanBuilderWithExplicitParent(SPAN_NAME, null) .setSampler(Samplers.neverSample()) diff --git a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java index 2595b855e9..c1fcfa55a7 100644 --- a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java +++ b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java @@ -43,7 +43,11 @@ public class StatsRunner { private static final StatsContextFactory factory = Stats.getStatsContextFactory(); private static final StatsContext DEFAULT = factory.getDefault(); - /** Main method. */ + /** + * Main method. + * + * @param args the main arguments. + */ public static void main(String[] args) { System.out.println("Hello Stats World"); System.out.println("Default Tags: " + DEFAULT); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java index b59ba01e33..d8df1011b9 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java @@ -46,7 +46,11 @@ private static void doWork() { tracer.getCurrentSpan().addAnnotation("Annotation to the root Span after child is ended."); } - /** Main method. */ + /** + * Main method. + * + * @param args the main arguments. + */ public static void main(String[] args) { LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); Span span = tracer.spanBuilderWithExplicitParent("MyRootSpan", null).startSpan(); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java index c73c3cc279..ebdc352a29 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java @@ -44,7 +44,11 @@ private static void doWork() { tracer.getCurrentSpan().addAnnotation("Annotation to the root Span after child is ended."); } - /** Main method. */ + /** + * Main method. + * + * @param args the main arguments. + */ public static void main(String[] args) { LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); try (NonThrowingCloseable ss = diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java index 25f71973f1..8c9aec4f4c 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java @@ -33,7 +33,11 @@ private static void doWork() { rootSpan.end(); } - /** Main method. */ + /** + * Main method. + * + * @param args the main arguments. + */ public static void main(String[] args) { LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); doWork(); From 8d05cb32b05e39cd803637094be8ad95c29fbd6e Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 4 Jul 2017 15:59:08 -0700 Subject: [PATCH 0224/1581] Move Sampler abstract class and EndSpanOptions to the main package. (#412) --- .../main/java/io/opencensus/trace/BlankSpan.java | 1 - .../opencensus/trace/{base => }/EndSpanOptions.java | 4 ++-- .../io/opencensus/trace/{base => }/Sampler.java | 7 +++---- api/src/main/java/io/opencensus/trace/Span.java | 1 - .../main/java/io/opencensus/trace/SpanBuilder.java | 2 -- .../io/opencensus/trace/config/TraceParams.java | 2 +- .../trace/samplers/AlwaysSampleSampler.java | 9 +++------ .../trace/samplers/NeverSampleSampler.java | 9 +++------ .../trace/samplers/ProbabilitySampler.java | 13 ++++++------- .../java/io/opencensus/trace/samplers/Samplers.java | 2 +- .../java/io/opencensus/trace/BlankSpanTest.java | 1 - .../trace/{base => }/EndSpanOptionsTest.java | 3 ++- .../io/opencensus/trace/ScopedSpanHandleTest.java | 1 - api/src/test/java/io/opencensus/trace/SpanTest.java | 1 - .../io/opencensus/trace/samplers/SamplersTest.java | 2 +- .../java/io/opencensus/trace/SpanBuilderImpl.java | 1 - .../src/main/java/io/opencensus/trace/SpanImpl.java | 1 - .../test/java/io/opencensus/trace/SpanImplTest.java | 1 - .../trace/export/SampledSpanStoreImplTest.java | 2 +- 19 files changed, 23 insertions(+), 40 deletions(-) rename api/src/main/java/io/opencensus/trace/{base => }/EndSpanOptions.java (97%) rename api/src/main/java/io/opencensus/trace/{base => }/Sampler.java (93%) rename api/src/test/java/io/opencensus/trace/{base => }/EndSpanOptionsTest.java (97%) diff --git a/api/src/main/java/io/opencensus/trace/BlankSpan.java b/api/src/main/java/io/opencensus/trace/BlankSpan.java index f78c3907fa..b4e112177b 100644 --- a/api/src/main/java/io/opencensus/trace/BlankSpan.java +++ b/api/src/main/java/io/opencensus/trace/BlankSpan.java @@ -15,7 +15,6 @@ import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; import java.util.Map; diff --git a/api/src/main/java/io/opencensus/trace/base/EndSpanOptions.java b/api/src/main/java/io/opencensus/trace/EndSpanOptions.java similarity index 97% rename from api/src/main/java/io/opencensus/trace/base/EndSpanOptions.java rename to api/src/main/java/io/opencensus/trace/EndSpanOptions.java index 00cd8ffbec..37d08edeb2 100644 --- a/api/src/main/java/io/opencensus/trace/base/EndSpanOptions.java +++ b/api/src/main/java/io/opencensus/trace/EndSpanOptions.java @@ -11,12 +11,12 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; import com.google.auto.value.AutoValue; -import io.opencensus.trace.Span; +import io.opencensus.trace.base.Status; import javax.annotation.concurrent.Immutable; /** diff --git a/api/src/main/java/io/opencensus/trace/base/Sampler.java b/api/src/main/java/io/opencensus/trace/Sampler.java similarity index 93% rename from api/src/main/java/io/opencensus/trace/base/Sampler.java rename to api/src/main/java/io/opencensus/trace/Sampler.java index 94bd2966fd..29f70c6d0b 100644 --- a/api/src/main/java/io/opencensus/trace/base/Sampler.java +++ b/api/src/main/java/io/opencensus/trace/Sampler.java @@ -11,11 +11,10 @@ * limitations under the License. */ -package io.opencensus.trace.base; - -import io.opencensus.trace.Span; -import io.opencensus.trace.SpanContext; +package io.opencensus.trace; +import io.opencensus.trace.base.SpanId; +import io.opencensus.trace.base.TraceId; import java.util.List; import javax.annotation.Nullable; diff --git a/api/src/main/java/io/opencensus/trace/Span.java b/api/src/main/java/io/opencensus/trace/Span.java index af6e3adb40..156890572c 100644 --- a/api/src/main/java/io/opencensus/trace/Span.java +++ b/api/src/main/java/io/opencensus/trace/Span.java @@ -18,7 +18,6 @@ import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; import java.util.Collections; diff --git a/api/src/main/java/io/opencensus/trace/SpanBuilder.java b/api/src/main/java/io/opencensus/trace/SpanBuilder.java index be55906f95..e61318ea3e 100644 --- a/api/src/main/java/io/opencensus/trace/SpanBuilder.java +++ b/api/src/main/java/io/opencensus/trace/SpanBuilder.java @@ -16,8 +16,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.trace.base.EndSpanOptions; -import io.opencensus.trace.base.Sampler; import java.util.List; import javax.annotation.Nullable; diff --git a/api/src/main/java/io/opencensus/trace/config/TraceParams.java b/api/src/main/java/io/opencensus/trace/config/TraceParams.java index 5f1ba3b054..d07ae0434f 100644 --- a/api/src/main/java/io/opencensus/trace/config/TraceParams.java +++ b/api/src/main/java/io/opencensus/trace/config/TraceParams.java @@ -16,11 +16,11 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.auto.value.AutoValue; +import io.opencensus.trace.Sampler; import io.opencensus.trace.Span; import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; -import io.opencensus.trace.base.Sampler; import io.opencensus.trace.samplers.Samplers; import javax.annotation.concurrent.Immutable; diff --git a/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java b/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java index f3daed4b4d..f78fcd18f2 100644 --- a/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java +++ b/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java @@ -13,23 +13,20 @@ package io.opencensus.trace.samplers; +import io.opencensus.trace.Sampler; import io.opencensus.trace.Span; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.Sampler; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import java.util.List; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; -/** - * Sampler that always makes a "yes" decision on {@link Span} sampling. - */ +/** Sampler that always makes a "yes" decision on {@link Span} sampling. */ @Immutable final class AlwaysSampleSampler extends Sampler { - AlwaysSampleSampler() { - } + AlwaysSampleSampler() {} // Returns always makes a "yes" decision on {@link Span} sampling. @Override diff --git a/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java b/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java index bca64df4d5..9fa8ea7bf8 100644 --- a/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java +++ b/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java @@ -13,23 +13,20 @@ package io.opencensus.trace.samplers; +import io.opencensus.trace.Sampler; import io.opencensus.trace.Span; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.Sampler; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import java.util.List; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; -/** - * Sampler that always makes a "no" decision on {@link Span} sampling. - */ +/** Sampler that always makes a "no" decision on {@link Span} sampling. */ @Immutable final class NeverSampleSampler extends Sampler { - NeverSampleSampler() { - } + NeverSampleSampler() {} // Returns always makes a "no" decision on {@link Span} sampling. @Override diff --git a/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java b/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java index c5c9c00237..1173562922 100644 --- a/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java +++ b/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java @@ -16,9 +16,9 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.auto.value.AutoValue; +import io.opencensus.trace.Sampler; import io.opencensus.trace.Span; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.Sampler; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import java.util.List; @@ -29,23 +29,22 @@ * We assume the lower 64 bits of the traceId's are randomly distributed around the whole (long) * range. We convert an incoming probability into an upper bound on that value, such that we can * just compare the absolute value of the id and the bound to see if we are within the desired - * probability range. Using the low bits of the traceId also ensures that systems that only use - * 64 bit ID's will also work with this sampler. + * probability range. Using the low bits of the traceId also ensures that systems that only use 64 + * bit ID's will also work with this sampler. */ @AutoValue @Immutable abstract class ProbabilitySampler extends Sampler { - ProbabilitySampler() { - } + ProbabilitySampler() {} abstract double getProbability(); abstract long getIdUpperBound(); /** - * Returns a new {@link ProbabilitySampler}. The probability of sampling a trace is equal to - * that of the specified probability. + * Returns a new {@link ProbabilitySampler}. The probability of sampling a trace is equal to that + * of the specified probability. * * @param probability The desired probability of sampling. Must be within [0.0, 1.0]. * @return a new {@link ProbabilitySampler}. diff --git a/api/src/main/java/io/opencensus/trace/samplers/Samplers.java b/api/src/main/java/io/opencensus/trace/samplers/Samplers.java index 40d7293159..f5ff453182 100644 --- a/api/src/main/java/io/opencensus/trace/samplers/Samplers.java +++ b/api/src/main/java/io/opencensus/trace/samplers/Samplers.java @@ -13,8 +13,8 @@ package io.opencensus.trace.samplers; +import io.opencensus.trace.Sampler; import io.opencensus.trace.Span; -import io.opencensus.trace.base.Sampler; /** Static class to access a set of pre-defined {@link Sampler Samplers}. */ public final class Samplers { diff --git a/api/src/test/java/io/opencensus/trace/BlankSpanTest.java b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java index c2f4c35d6f..c62b5bf6c7 100644 --- a/api/src/test/java/io/opencensus/trace/BlankSpanTest.java +++ b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java @@ -17,7 +17,6 @@ import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; import java.util.HashMap; diff --git a/api/src/test/java/io/opencensus/trace/base/EndSpanOptionsTest.java b/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java similarity index 97% rename from api/src/test/java/io/opencensus/trace/base/EndSpanOptionsTest.java rename to api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java index 87ff8df8ae..5fc50b7b52 100644 --- a/api/src/test/java/io/opencensus/trace/base/EndSpanOptionsTest.java +++ b/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java @@ -11,11 +11,12 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; +import io.opencensus.trace.base.Status; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java b/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java index cf043d09f7..8922f4c2d2 100644 --- a/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java +++ b/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java @@ -18,7 +18,6 @@ import static org.mockito.Mockito.verify; import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.trace.base.EndSpanOptions; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/api/src/test/java/io/opencensus/trace/SpanTest.java b/api/src/test/java/io/opencensus/trace/SpanTest.java index 0ab481d922..186e6b1bd6 100644 --- a/api/src/test/java/io/opencensus/trace/SpanTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanTest.java @@ -19,7 +19,6 @@ import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; import io.opencensus.trace.base.SpanId; diff --git a/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java b/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java index 5e99683511..12ec754810 100644 --- a/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java +++ b/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java @@ -15,9 +15,9 @@ import static com.google.common.truth.Truth.assertThat; +import io.opencensus.trace.Sampler; import io.opencensus.trace.Span; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.Sampler; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java index f9a0bf0c56..977baabf1c 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java @@ -19,7 +19,6 @@ import io.opencensus.internal.TimestampConverter; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.Link.Type; -import io.opencensus.trace.base.Sampler; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.TraceId; import io.opencensus.trace.base.TraceOptions; diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java index 53a8053ef6..b5483e8f3f 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java @@ -22,7 +22,6 @@ import io.opencensus.internal.TimestampConverter; import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; import io.opencensus.trace.base.SpanId; diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java index ed4aae7415..451aabd506 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java @@ -23,7 +23,6 @@ import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.base.Annotation; import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.Link; import io.opencensus.trace.base.NetworkEvent; import io.opencensus.trace.base.SpanId; diff --git a/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java index 3679f56052..46d7ccd493 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java @@ -18,12 +18,12 @@ import io.opencensus.common.Duration; import io.opencensus.common.Timestamp; import io.opencensus.testing.common.TestClock; +import io.opencensus.trace.EndSpanOptions; import io.opencensus.trace.Span; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanContext; import io.opencensus.trace.SpanImpl; import io.opencensus.trace.SpanImpl.StartEndHandler; -import io.opencensus.trace.base.EndSpanOptions; import io.opencensus.trace.base.SpanId; import io.opencensus.trace.base.Status; import io.opencensus.trace.base.Status.CanonicalCode; From b21c6ef72a2845066edf8ca27dabd3f36bb0e2f3 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Wed, 5 Jul 2017 10:13:43 -0700 Subject: [PATCH 0225/1581] Fix sereral issues on Measure. (#406) --- .../java/io/opencensus/stats/Measure.java | 19 +++++++++++-------- .../java/io/opencensus/stats/MeasureTest.java | 6 ++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/io/opencensus/stats/Measure.java b/core/src/main/java/io/opencensus/stats/Measure.java index 3f637c95fc..bb8c78b692 100644 --- a/core/src/main/java/io/opencensus/stats/Measure.java +++ b/core/src/main/java/io/opencensus/stats/Measure.java @@ -1,5 +1,5 @@ /* - * Copyright 2016, Google Inc. + * Copyright 2017, Google Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -26,7 +26,9 @@ public abstract class Measure { /** * Applies the given match function to the underlying data type. */ - public abstract T match(Function p0, Function p1); + public abstract T match( + Function p0, + Function p1); /** * Name of measure, as a {@code String}. @@ -41,13 +43,14 @@ public abstract class Measure { /** * The units in which {@link Measure} values are measured. * - *

            The grammar for a unit is as follows: - * Expression = Component { "." Component } { "/" Component } ; - * Component = [ PREFIX ] UNIT [ Annotation ] | Annotation | "1" ; - * Annotation = "{" NAME "}" ; + *

            The suggested grammar for a unit is as follows: + * Expression = Component { "." Component } { "/" Component } ; + * Component = [ PREFIX ] UNIT [ Annotation ] | Annotation | "1" ; + * Annotation = "{" NAME "}" ; * For example, string “MBy{transmitted}/ms” stands for megabytes per milliseconds, and the * annotation transmitted inside {} is just a comment of the unit. */ + // TODO(songya): determine whether we want to check the grammar on string unit. public abstract String getUnit(); // Prevents this class from being subclassed anywhere else. @@ -71,7 +74,7 @@ public static DoubleMeasure create(String name, String description, String unit) } @Override - public T match(Function p0, Function p1) { + public T match(Function p0, Function p1) { return p0.apply(this); } @@ -103,7 +106,7 @@ public static LongMeasure create(String name, String description, String unit) { } @Override - public T match(Function p0, Function p1) { + public T match(Function p0, Function p1) { return p1.apply(this); } diff --git a/core/src/test/java/io/opencensus/stats/MeasureTest.java b/core/src/test/java/io/opencensus/stats/MeasureTest.java index aff4c873f7..a5774c87cc 100644 --- a/core/src/test/java/io/opencensus/stats/MeasureTest.java +++ b/core/src/test/java/io/opencensus/stats/MeasureTest.java @@ -110,6 +110,12 @@ public void testLongMeasureEquals() { .testEquals(); } + @Test + public void testDoubleMeasureIsNotEqualToLongMeasure() { + assertThat(Measure.DoubleMeasure.create("name", "description", "bit/s")) + .isNotEqualTo(Measure.LongMeasure.create("name", "description", "bit/s")); + } + private static final Measure makeSimpleMeasure(String name) { return Measure.DoubleMeasure.create(name, name + " description", "1"); } From 9676a3f7b66021d846f5ca92dca69bd122e501d5 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 5 Jul 2017 10:21:28 -0700 Subject: [PATCH 0226/1581] Clarify the nature of the Link.Type enum (#413) --- .../java/io/opencensus/trace/base/Link.java | 4 +-- .../io/opencensus/trace/BlankSpanTest.java | 3 +- .../io/opencensus/trace/base/LinkTest.java | 28 +++++++++---------- .../opencensus/trace/export/SpanDataTest.java | 2 +- ...ordTraceEventsNonSampledSpanBenchmark.java | 2 +- ...RecordTraceEventsSampledSpanBenchmark.java | 2 +- .../io/opencensus/trace/SpanBuilderImpl.java | 4 +-- .../io/opencensus/trace/SpanImplTest.java | 10 +++---- 8 files changed, 28 insertions(+), 27 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/base/Link.java b/api/src/main/java/io/opencensus/trace/base/Link.java index 363bd212b5..3f8b93f885 100644 --- a/api/src/main/java/io/opencensus/trace/base/Link.java +++ b/api/src/main/java/io/opencensus/trace/base/Link.java @@ -33,9 +33,9 @@ public abstract class Link { /** The relationship with the linked {@code Span} relative to the current {@code Span}. */ public enum Type { /** When the linked {@code Span} is a child of the current {@code Span}. */ - CHILD, + CHILD_LINKED_SPAN, /** When the linked {@code Span} is a parent of the current {@code Span}. */ - PARENT + PARENT_LINKED_SPAN } /** diff --git a/api/src/test/java/io/opencensus/trace/BlankSpanTest.java b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java index c62b5bf6c7..f9690321b0 100644 --- a/api/src/test/java/io/opencensus/trace/BlankSpanTest.java +++ b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java @@ -52,7 +52,8 @@ public void doNotCrash() { BlankSpan.INSTANCE.addAnnotation("MyAnnotation", multipleAttributes); BlankSpan.INSTANCE.addAnnotation(Annotation.fromDescription("MyAnnotation")); BlankSpan.INSTANCE.addNetworkEvent(NetworkEvent.builder(NetworkEvent.Type.SENT, 1L).build()); - BlankSpan.INSTANCE.addLink(Link.fromSpanContext(SpanContext.INVALID, Link.Type.CHILD)); + BlankSpan.INSTANCE.addLink( + Link.fromSpanContext(SpanContext.INVALID, Link.Type.CHILD_LINKED_SPAN)); BlankSpan.INSTANCE.end(EndSpanOptions.DEFAULT); BlankSpan.INSTANCE.end(); } diff --git a/api/src/test/java/io/opencensus/trace/base/LinkTest.java b/api/src/test/java/io/opencensus/trace/base/LinkTest.java index 4fafa02ad7..d0bfc46eb5 100644 --- a/api/src/test/java/io/opencensus/trace/base/LinkTest.java +++ b/api/src/test/java/io/opencensus/trace/base/LinkTest.java @@ -33,18 +33,18 @@ public class LinkTest { @Test public void fromSpanContext_ChildLink() { - Link link = Link.fromSpanContext(spanContext, Type.CHILD); + Link link = Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN); assertThat(link.getTraceId()).isEqualTo(spanContext.getTraceId()); assertThat(link.getSpanId()).isEqualTo(spanContext.getSpanId()); - assertThat(link.getType()).isEqualTo(Type.CHILD); + assertThat(link.getType()).isEqualTo(Type.CHILD_LINKED_SPAN); } @Test public void fromSpanContext_ParentLink() { - Link link = Link.fromSpanContext(spanContext, Type.PARENT); + Link link = Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN); assertThat(link.getTraceId()).isEqualTo(spanContext.getTraceId()); assertThat(link.getSpanId()).isEqualTo(spanContext.getSpanId()); - assertThat(link.getType()).isEqualTo(Type.PARENT); + assertThat(link.getType()).isEqualTo(Type.PARENT_LINKED_SPAN); } @Test @@ -52,25 +52,25 @@ public void link_EqualsAndHashCode() { EqualsTester tester = new EqualsTester(); tester .addEqualityGroup( - Link.fromSpanContext(spanContext, Type.PARENT), - Link.fromSpanContext(spanContext, Type.PARENT)) + Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN), + Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN)) .addEqualityGroup( - Link.fromSpanContext(spanContext, Type.CHILD), - Link.fromSpanContext(spanContext, Type.CHILD)) - .addEqualityGroup(Link.fromSpanContext(SpanContext.INVALID, Type.CHILD)) - .addEqualityGroup(Link.fromSpanContext(SpanContext.INVALID, Type.PARENT)); + Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN), + Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN)) + .addEqualityGroup(Link.fromSpanContext(SpanContext.INVALID, Type.CHILD_LINKED_SPAN)) + .addEqualityGroup(Link.fromSpanContext(SpanContext.INVALID, Type.PARENT_LINKED_SPAN)); tester.testEquals(); } @Test public void link_ToString() { - Link link = Link.fromSpanContext(spanContext, Type.CHILD); + Link link = Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN); assertThat(link.toString()).contains(spanContext.getTraceId().toString()); assertThat(link.toString()).contains(spanContext.getSpanId().toString()); - assertThat(link.toString()).contains("CHILD"); - link = Link.fromSpanContext(spanContext, Type.PARENT); + assertThat(link.toString()).contains("CHILD_LINKED_SPAN"); + link = Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN); assertThat(link.toString()).contains(spanContext.getTraceId().toString()); assertThat(link.toString()).contains(spanContext.getSpanId().toString()); - assertThat(link.toString()).contains("PARENT"); + assertThat(link.toString()).contains("PARENT_LINKED_SPAN"); } } diff --git a/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java index 1a92b0e634..6ea20fcc01 100644 --- a/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java +++ b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java @@ -85,7 +85,7 @@ public void setUp() { networkEventsList.add(SpanData.TimedEvent.create(eventTimestamp1, recvNetworkEvent)); networkEventsList.add(SpanData.TimedEvent.create(eventTimestamp2, sentNetworkEvent)); networkEvents = TimedEvents.create(networkEventsList, 3); - linksList.add(Link.fromSpanContext(spanContext, Type.CHILD)); + linksList.add(Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN)); links = Links.create(linksList, 0); } diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java index 2a6872d002..00f68efdc0 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java @@ -87,7 +87,7 @@ public Span addNetworkEvent() { @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public Span addLink() { - span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Link.Type.PARENT)); + span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Link.Type.PARENT_LINKED_SPAN)); return span; } } diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java index db591f55c9..de821b0695 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java @@ -87,7 +87,7 @@ public Span addNetworkEvent() { @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public Span addLink() { - span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Link.Type.PARENT)); + span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Link.Type.PARENT_LINKED_SPAN)); return span; } } diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java index 977baabf1c..e001d4b2e0 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java @@ -96,10 +96,10 @@ private SpanImpl startSpanInternal( private static void linkSpans(Span span, List parentLinks) { if (!parentLinks.isEmpty()) { - Link childLink = Link.fromSpanContext(span.getContext(), Type.CHILD); + Link childLink = Link.fromSpanContext(span.getContext(), Type.CHILD_LINKED_SPAN); for (Span linkedSpan : parentLinks) { linkedSpan.addLink(childLink); - span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Type.PARENT)); + span.addLink(Link.fromSpanContext(linkedSpan.getContext(), Type.PARENT_LINKED_SPAN)); } } } diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java index 451aabd506..4db23b2f9c 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java @@ -91,7 +91,7 @@ public void toSpanData_NoRecordEvents() { span.addAnnotation(Annotation.fromDescription(ANNOTATION_DESCRIPTION)); span.addAnnotation(ANNOTATION_DESCRIPTION, attributes); span.addNetworkEvent(NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build()); - span.addLink(Link.fromSpanContext(spanContext, Link.Type.CHILD)); + span.addLink(Link.fromSpanContext(spanContext, Link.Type.CHILD_LINKED_SPAN)); span.end(); exception.expect(IllegalStateException.class); span.toSpanData(); @@ -117,7 +117,7 @@ public void noEventsRecordedAfterEnd() { span.addAnnotation(Annotation.fromDescription(ANNOTATION_DESCRIPTION)); span.addAnnotation(ANNOTATION_DESCRIPTION, attributes); span.addNetworkEvent(NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build()); - span.addLink(Link.fromSpanContext(spanContext, Link.Type.CHILD)); + span.addLink(Link.fromSpanContext(spanContext, Link.Type.CHILD_LINKED_SPAN)); SpanData spanData = span.toSpanData(); assertThat(spanData.getStartTimestamp()).isEqualTo(timestamp); assertThat(spanData.getAttributes().getAttributeMap()).isEmpty(); @@ -152,7 +152,7 @@ public void toSpanData_ActiveSpan() { NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build(); span.addNetworkEvent(networkEvent); testClock.advanceTime(Duration.create(0, 100)); - Link link = Link.fromSpanContext(spanContext, Link.Type.CHILD); + Link link = Link.fromSpanContext(spanContext, Link.Type.CHILD_LINKED_SPAN); span.addLink(link); SpanData spanData = span.toSpanData(); assertThat(spanData.getContext()).isEqualTo(spanContext); @@ -207,7 +207,7 @@ public void toSpanData_EndedSpan() { NetworkEvent networkEvent = NetworkEvent.builder(NetworkEvent.Type.RECV, 1).setMessageSize(3).build(); span.addNetworkEvent(networkEvent); - Link link = Link.fromSpanContext(spanContext, Link.Type.CHILD); + Link link = Link.fromSpanContext(spanContext, Link.Type.CHILD_LINKED_SPAN); span.addLink(link); testClock.advanceTime(Duration.create(0, 100)); span.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build()); @@ -450,7 +450,7 @@ public void droppingLinks() { startEndHandler, timestampConverter, testClock); - Link link = Link.fromSpanContext(spanContext, Link.Type.CHILD); + Link link = Link.fromSpanContext(spanContext, Link.Type.CHILD_LINKED_SPAN); for (int i = 0; i < 2 * maxNumberOfLinks; i++) { span.addLink(link); } From 6bf1e1d397a20cd1a1f6c80da8b7f1d07357852c Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 5 Jul 2017 20:37:10 -0700 Subject: [PATCH 0227/1581] Move logging exporter into an independent package. (#416) * Move logging exporter into an independent package. * Change package to opencensus-trace-logging-exporter --- .../opencensus/trace/export/SpanExporter.java | 41 ------------- examples/build.gradle | 3 +- .../examples/stats/StatsRunner.java | 9 +-- .../trace/MultiSpansContextTracing.java | 4 +- .../trace/MultiSpansScopedTracing.java | 4 +- .../examples/trace/MultiSpansTracing.java | 4 +- exporters/trace_logging/build.gradle | 10 ++++ .../trace/export/LoggingExportHandler.java | 59 +++++++++++++++++++ .../export/LoggingExportHandlerTest.java | 15 ++--- settings.gradle | 2 + 10 files changed, 88 insertions(+), 63 deletions(-) create mode 100644 exporters/trace_logging/build.gradle create mode 100644 exporters/trace_logging/src/main/java/io/opencensus/trace/export/LoggingExportHandler.java rename api/src/test/java/io/opencensus/trace/export/SpanExporterTest.java => exporters/trace_logging/src/test/java/io/opencensus/trace/export/LoggingExportHandlerTest.java (72%) diff --git a/api/src/main/java/io/opencensus/trace/export/SpanExporter.java b/api/src/main/java/io/opencensus/trace/export/SpanExporter.java index 39e0a583c0..bfae4bad82 100644 --- a/api/src/main/java/io/opencensus/trace/export/SpanExporter.java +++ b/api/src/main/java/io/opencensus/trace/export/SpanExporter.java @@ -16,8 +16,6 @@ import io.opencensus.trace.Span; import io.opencensus.trace.base.TraceOptions; import java.util.Collection; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.annotation.concurrent.ThreadSafe; /** @@ -84,43 +82,4 @@ public void registerHandler(String name, Handler handler) {} @Override public void unregisterHandler(String name) {} } - - /** Implementation of the {@link Handler} which logs all the exported {@link SpanData}. */ - @ThreadSafe - public static final class LoggingHandler extends Handler { - - private static final Logger logger = Logger.getLogger(LoggingHandler.class.getName()); - private static final String REGISTER_NAME = - "io.opencensus.trace.export.SpanExporter$LoggingHandler"; - private static final LoggingHandler INSTANCE = new LoggingHandler(); - - private LoggingHandler() {} - - /** - * Registers the {@code LoggingHandler} to the {@code ExportComponent}. - * - * @param spanExporter the instance of the {@code SpanExporter} where this service is - * registered. - */ - public static void register(SpanExporter spanExporter) { - spanExporter.registerHandler(REGISTER_NAME, INSTANCE); - } - - /** - * Unregisters the {@code LoggingHandler} from the {@code ExportComponent}. - * - * @param spanExporter the instance of the {@code SpanExporter} from where this service is - * unregistered. - */ - public static void unregister(SpanExporter spanExporter) { - spanExporter.unregisterHandler(REGISTER_NAME); - } - - @Override - public void export(Collection spanDataList) { - for (SpanData spanData : spanDataList) { - logger.log(Level.INFO, spanData.toString()); - } - } - } } diff --git a/examples/build.gradle b/examples/build.gradle index 0ff5102b71..5e45e8464d 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -7,7 +7,8 @@ tasks.withType(JavaCompile) { dependencies { compile project(':core'), - project(':opencensus-api') + project(':opencensus-api'), + project(':opencensus-trace-logging-exporter') runtime project(':core_impl_java'), project(':opencensus-impl') diff --git a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java index c1fcfa55a7..d0107efbf6 100644 --- a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java +++ b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java @@ -35,10 +35,8 @@ public class StatsRunner { private static final TagValue V4 = TagValue.create("v4"); private static final String UNIT = "1"; - private static final Measure M1 = - Measure.DoubleMeasure.create("m1", "1st test metric", UNIT); - private static final Measure M2 = - Measure.DoubleMeasure.create("m2", "2nd test metric", UNIT); + private static final Measure M1 = Measure.DoubleMeasure.create("m1", "1st test metric", UNIT); + private static final Measure M2 = Measure.DoubleMeasure.create("m2", "2nd test metric", UNIT); private static final StatsContextFactory factory = Stats.getStatsContextFactory(); private static final StatsContext DEFAULT = factory.getDefault(); @@ -56,8 +54,7 @@ public static void main(String[] args) { try (NonThrowingCloseable scopedStatsCtx1 = factory.withStatsContext(tags1)) { System.out.println(" Current Tags: " + factory.getCurrentStatsContext()); System.out.println( - " Current == Default + tags1: " - + factory.getCurrentStatsContext().equals(tags1)); + " Current == Default + tags1: " + factory.getCurrentStatsContext().equals(tags1)); StatsContext tags2 = tags1.with(K3, V3, K4, V4); try (NonThrowingCloseable scopedStatsCtx2 = factory.withStatsContext(tags2)) { System.out.println(" Current Tags: " + factory.getCurrentStatsContext()); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java index d8df1011b9..9e0667169f 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java @@ -17,7 +17,7 @@ import io.opencensus.trace.Span; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; -import io.opencensus.trace.export.SpanExporter.LoggingHandler; +import io.opencensus.trace.export.LoggingExportHandler; /** * Example showing how to create a child {@link Span}, install it to the current context and add @@ -52,7 +52,7 @@ private static void doWork() { * @param args the main arguments. */ public static void main(String[] args) { - LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); + LoggingExportHandler.register(Tracing.getExportComponent().getSpanExporter()); Span span = tracer.spanBuilderWithExplicitParent("MyRootSpan", null).startSpan(); try (NonThrowingCloseable ws = tracer.withSpan(span)) { doWork(); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java index ebdc352a29..e663ae1121 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java @@ -17,7 +17,7 @@ import io.opencensus.trace.Span; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; -import io.opencensus.trace.export.SpanExporter.LoggingHandler; +import io.opencensus.trace.export.LoggingExportHandler; /** * Example showing how to create a child {@link Span} using scoped Spans, install it in the current @@ -50,7 +50,7 @@ private static void doWork() { * @param args the main arguments. */ public static void main(String[] args) { - LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); + LoggingExportHandler.register(Tracing.getExportComponent().getSpanExporter()); try (NonThrowingCloseable ss = tracer.spanBuilderWithExplicitParent("MyRootSpan", null).startScopedSpan()) { doWork(); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java index 8c9aec4f4c..d3edb77547 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java @@ -16,7 +16,7 @@ import io.opencensus.trace.Span; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; -import io.opencensus.trace.export.SpanExporter.LoggingHandler; +import io.opencensus.trace.export.LoggingExportHandler; /** Example showing how to directly create a child {@link Span} and add annotations. */ public final class MultiSpansTracing { @@ -39,7 +39,7 @@ private static void doWork() { * @param args the main arguments. */ public static void main(String[] args) { - LoggingHandler.register(Tracing.getExportComponent().getSpanExporter()); + LoggingExportHandler.register(Tracing.getExportComponent().getSpanExporter()); doWork(); } } diff --git a/exporters/trace_logging/build.gradle b/exporters/trace_logging/build.gradle new file mode 100644 index 0000000000..be505a6aa4 --- /dev/null +++ b/exporters/trace_logging/build.gradle @@ -0,0 +1,10 @@ +description = 'OpenCensus Trace Logging Exporter' + +dependencies { + compile project(':opencensus-api'), + libraries.guava + + testCompile project(':opencensus-api') + + signature "org.codehaus.mojo.signature:java16:+@signature" +} \ No newline at end of file diff --git a/exporters/trace_logging/src/main/java/io/opencensus/trace/export/LoggingExportHandler.java b/exporters/trace_logging/src/main/java/io/opencensus/trace/export/LoggingExportHandler.java new file mode 100644 index 0000000000..32c9441120 --- /dev/null +++ b/exporters/trace_logging/src/main/java/io/opencensus/trace/export/LoggingExportHandler.java @@ -0,0 +1,59 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace.export; + +import io.opencensus.trace.export.SpanExporter.Handler; +import java.util.Collection; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.concurrent.ThreadSafe; + +/** Implementation of the {@link Handler} which logs all the exported {@link SpanData}. */ +@ThreadSafe +public final class LoggingExportHandler extends Handler { + + private static final Logger logger = Logger.getLogger(LoggingExportHandler.class.getName()); + private static final String REGISTER_NAME = LoggingExportHandler.class.getName(); + private static final LoggingExportHandler INSTANCE = new LoggingExportHandler(); + + private LoggingExportHandler() {} + + /** + * Registers the {@code LoggingHandler} to the {@code ExportComponent}. + * + * @param spanExporter the instance of the {@code SpanExporter} where this service is registered. + */ + public static void register(SpanExporter spanExporter) { + spanExporter.registerHandler(REGISTER_NAME, INSTANCE); + } + + /** + * Unregisters the {@code LoggingHandler} from the {@code ExportComponent}. + * + * @param spanExporter the instance of the {@code SpanExporter} from where this service is + * unregistered. + */ + public static void unregister(SpanExporter spanExporter) { + spanExporter.unregisterHandler(REGISTER_NAME); + } + + @Override + public void export(Collection spanDataList) { + // TODO(bdrutu): Use JSON as a standard format for logging SpanData and define this to be + // compatible between languages. + for (SpanData spanData : spanDataList) { + logger.log(Level.INFO, spanData.toString()); + } + } +} diff --git a/api/src/test/java/io/opencensus/trace/export/SpanExporterTest.java b/exporters/trace_logging/src/test/java/io/opencensus/trace/export/LoggingExportHandlerTest.java similarity index 72% rename from api/src/test/java/io/opencensus/trace/export/SpanExporterTest.java rename to exporters/trace_logging/src/test/java/io/opencensus/trace/export/LoggingExportHandlerTest.java index 464806881a..3a1b3773ac 100644 --- a/api/src/test/java/io/opencensus/trace/export/SpanExporterTest.java +++ b/exporters/trace_logging/src/test/java/io/opencensus/trace/export/LoggingExportHandlerTest.java @@ -17,7 +17,6 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; -import io.opencensus.trace.export.SpanExporter.LoggingHandler; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -25,9 +24,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -/** Unit tests for {@link ExportComponent}. */ +/** Unit tests for {@link LoggingExportHandler}. */ @RunWith(JUnit4.class) -public class SpanExporterTest { +public class LoggingExportHandlerTest { @Mock private SpanExporter spanExporter; @Before @@ -37,13 +36,11 @@ public void setUp() { @Test public void registerUnregisterLoggingService() { - LoggingHandler.register(spanExporter); + LoggingExportHandler.register(spanExporter); verify(spanExporter) .registerHandler( - eq("io.opencensus.trace.export.SpanExporter$LoggingHandler"), - any(LoggingHandler.class)); - LoggingHandler.unregister(spanExporter); - verify(spanExporter) - .unregisterHandler(eq("io.opencensus.trace.export.SpanExporter$LoggingHandler")); + eq("io.opencensus.trace.export.LoggingExportHandler"), any(LoggingExportHandler.class)); + LoggingExportHandler.unregister(spanExporter); + verify(spanExporter).unregisterHandler(eq("io.opencensus.trace.export.LoggingExportHandler")); } } diff --git a/settings.gradle b/settings.gradle index c87aed4a81..09a752878b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -6,6 +6,7 @@ include ":opencensus-impl-core" include ":opencensus-impl-lite" include ":opencensus-impl" include ":opencensus-testing" +include ":opencensus-trace-logging-exporter" include ":all" include ":core" include ":core_impl" @@ -18,6 +19,7 @@ project(':opencensus-impl-core').projectDir = "$rootDir/impl_core" as File project(':opencensus-impl-lite').projectDir = "$rootDir/impl_lite" as File project(':opencensus-impl').projectDir = "$rootDir/impl" as File project(':opencensus-testing').projectDir = "$rootDir/testing" as File +project(':opencensus-trace-logging-exporter').projectDir = "$rootDir/exporters/trace_logging" as File // Java8 projects only if (JavaVersion.current().isJava8Compatible()) { From d51699ee80ba3d19cda27ce269c56b486e795521 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 6 Jul 2017 08:12:08 -0700 Subject: [PATCH 0228/1581] Get rid of base directory and move everything on level up. (#417) * Get rid of base directory and move everything on level up. * Remove unused imports in tests. --- .../trace/{base => }/Annotation.java | 2 +- .../trace/{base => }/AttributeValue.java | 2 +- .../java/io/opencensus/trace/BlankSpan.java | 4 ---- .../io/opencensus/trace/EndSpanOptions.java | 1 - .../io/opencensus/trace/{base => }/Link.java | 4 +--- .../trace/{base => }/NetworkEvent.java | 2 +- .../main/java/io/opencensus/trace/Sampler.java | 2 -- .../main/java/io/opencensus/trace/Span.java | 4 ---- .../java/io/opencensus/trace/SpanContext.java | 3 --- .../io/opencensus/trace/{base => }/SpanId.java | 2 +- .../io/opencensus/trace/{base => }/Status.java | 3 +-- .../opencensus/trace/{base => }/TraceId.java | 2 +- .../trace/{base => }/TraceOptions.java | 2 +- .../opencensus/trace/config/TraceParams.java | 6 +++--- .../trace/export/ExportComponent.java | 2 +- .../trace/export/SampledSpanStore.java | 4 ++-- .../io/opencensus/trace/export/SpanData.java | 12 ++++++------ .../opencensus/trace/export/SpanExporter.java | 2 +- .../trace/samplers/AlwaysSampleSampler.java | 4 ++-- .../trace/samplers/NeverSampleSampler.java | 4 ++-- .../trace/samplers/ProbabilitySampler.java | 4 ++-- .../trace/{base => }/AnnotationTest.java | 2 +- .../trace/{base => }/AttributeValueTest.java | 2 +- .../io/opencensus/trace/BlankSpanTest.java | 4 ---- .../opencensus/trace/EndSpanOptionsTest.java | 1 - .../opencensus/trace/{base => }/LinkTest.java | 5 ++--- .../trace/{base => }/NetworkEventTest.java | 2 +- .../io/opencensus/trace/SpanContextTest.java | 3 --- .../trace/{base => }/SpanIdTest.java | 2 +- .../java/io/opencensus/trace/SpanTest.java | 7 ------- .../trace/{base => }/StatusTest.java | 2 +- .../trace/{base => }/TraceIdTest.java | 2 +- .../trace/{base => }/TraceOptionsTest.java | 2 +- .../opencensus/trace/export/SpanDataTest.java | 18 +++++++++--------- .../trace/samplers/SamplersTest.java | 6 +++--- ...cordTraceEventsNonSampledSpanBenchmark.java | 3 --- .../RecordTraceEventsSampledSpanBenchmark.java | 3 --- .../BinaryPropagationImplBenchmark.java | 6 +++--- .../io/opencensus/trace/SpanBuilderImpl.java | 6 +----- .../java/io/opencensus/trace/SpanImpl.java | 6 ------ .../trace/export/SampledSpanStoreImpl.java | 4 ++-- .../trace/propagation/BinaryFormatImpl.java | 6 +++--- .../opencensus/trace/SpanBuilderImplTest.java | 3 --- .../java/io/opencensus/trace/SpanImplTest.java | 8 -------- ...Test.java => RunningSpanStoreImplTest.java} | 10 +++++----- .../trace/export/SampledSpanStoreImplTest.java | 10 +++++----- .../trace/export/SpanExporterImplTest.java | 6 +++--- .../propagation/BinaryFormatImplTest.java | 6 +++--- 48 files changed, 73 insertions(+), 133 deletions(-) rename api/src/main/java/io/opencensus/trace/{base => }/Annotation.java (98%) rename api/src/main/java/io/opencensus/trace/{base => }/AttributeValue.java (98%) rename api/src/main/java/io/opencensus/trace/{base => }/Link.java (95%) rename api/src/main/java/io/opencensus/trace/{base => }/NetworkEvent.java (99%) rename api/src/main/java/io/opencensus/trace/{base => }/SpanId.java (99%) rename api/src/main/java/io/opencensus/trace/{base => }/Status.java (99%) rename api/src/main/java/io/opencensus/trace/{base => }/TraceId.java (99%) rename api/src/main/java/io/opencensus/trace/{base => }/TraceOptions.java (99%) rename api/src/test/java/io/opencensus/trace/{base => }/AnnotationTest.java (99%) rename api/src/test/java/io/opencensus/trace/{base => }/AttributeValueTest.java (98%) rename api/src/test/java/io/opencensus/trace/{base => }/LinkTest.java (96%) rename api/src/test/java/io/opencensus/trace/{base => }/NetworkEventTest.java (99%) rename api/src/test/java/io/opencensus/trace/{base => }/SpanIdTest.java (98%) rename api/src/test/java/io/opencensus/trace/{base => }/StatusTest.java (98%) rename api/src/test/java/io/opencensus/trace/{base => }/TraceIdTest.java (98%) rename api/src/test/java/io/opencensus/trace/{base => }/TraceOptionsTest.java (98%) rename impl_core/src/test/java/io/opencensus/trace/export/{RunningSpanStoreTest.java => RunningSpanStoreImplTest.java} (96%) diff --git a/api/src/main/java/io/opencensus/trace/base/Annotation.java b/api/src/main/java/io/opencensus/trace/Annotation.java similarity index 98% rename from api/src/main/java/io/opencensus/trace/base/Annotation.java rename to api/src/main/java/io/opencensus/trace/Annotation.java index b86b93d8a6..f72070e815 100644 --- a/api/src/main/java/io/opencensus/trace/base/Annotation.java +++ b/api/src/main/java/io/opencensus/trace/Annotation.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/api/src/main/java/io/opencensus/trace/base/AttributeValue.java b/api/src/main/java/io/opencensus/trace/AttributeValue.java similarity index 98% rename from api/src/main/java/io/opencensus/trace/base/AttributeValue.java rename to api/src/main/java/io/opencensus/trace/AttributeValue.java index 86f0c84ab0..f66fd42597 100644 --- a/api/src/main/java/io/opencensus/trace/base/AttributeValue.java +++ b/api/src/main/java/io/opencensus/trace/AttributeValue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/api/src/main/java/io/opencensus/trace/BlankSpan.java b/api/src/main/java/io/opencensus/trace/BlankSpan.java index b4e112177b..40e49551b7 100644 --- a/api/src/main/java/io/opencensus/trace/BlankSpan.java +++ b/api/src/main/java/io/opencensus/trace/BlankSpan.java @@ -13,10 +13,6 @@ package io.opencensus.trace; -import io.opencensus.trace.base.Annotation; -import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.NetworkEvent; import java.util.Map; import javax.annotation.concurrent.Immutable; diff --git a/api/src/main/java/io/opencensus/trace/EndSpanOptions.java b/api/src/main/java/io/opencensus/trace/EndSpanOptions.java index 37d08edeb2..e58a06c381 100644 --- a/api/src/main/java/io/opencensus/trace/EndSpanOptions.java +++ b/api/src/main/java/io/opencensus/trace/EndSpanOptions.java @@ -16,7 +16,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.auto.value.AutoValue; -import io.opencensus.trace.base.Status; import javax.annotation.concurrent.Immutable; /** diff --git a/api/src/main/java/io/opencensus/trace/base/Link.java b/api/src/main/java/io/opencensus/trace/Link.java similarity index 95% rename from api/src/main/java/io/opencensus/trace/base/Link.java rename to api/src/main/java/io/opencensus/trace/Link.java index 3f8b93f885..058bd8a961 100644 --- a/api/src/main/java/io/opencensus/trace/base/Link.java +++ b/api/src/main/java/io/opencensus/trace/Link.java @@ -11,11 +11,9 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import com.google.auto.value.AutoValue; -import io.opencensus.trace.Span; -import io.opencensus.trace.SpanContext; import javax.annotation.concurrent.Immutable; /** diff --git a/api/src/main/java/io/opencensus/trace/base/NetworkEvent.java b/api/src/main/java/io/opencensus/trace/NetworkEvent.java similarity index 99% rename from api/src/main/java/io/opencensus/trace/base/NetworkEvent.java rename to api/src/main/java/io/opencensus/trace/NetworkEvent.java index 9edc6f2505..10687074c4 100644 --- a/api/src/main/java/io/opencensus/trace/base/NetworkEvent.java +++ b/api/src/main/java/io/opencensus/trace/NetworkEvent.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/api/src/main/java/io/opencensus/trace/Sampler.java b/api/src/main/java/io/opencensus/trace/Sampler.java index 29f70c6d0b..327bfa422f 100644 --- a/api/src/main/java/io/opencensus/trace/Sampler.java +++ b/api/src/main/java/io/opencensus/trace/Sampler.java @@ -13,8 +13,6 @@ package io.opencensus.trace; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; import java.util.List; import javax.annotation.Nullable; diff --git a/api/src/main/java/io/opencensus/trace/Span.java b/api/src/main/java/io/opencensus/trace/Span.java index 156890572c..428f0201d4 100644 --- a/api/src/main/java/io/opencensus/trace/Span.java +++ b/api/src/main/java/io/opencensus/trace/Span.java @@ -16,10 +16,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import io.opencensus.trace.base.Annotation; -import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.NetworkEvent; import java.util.Collections; import java.util.EnumSet; import java.util.Map; diff --git a/api/src/main/java/io/opencensus/trace/SpanContext.java b/api/src/main/java/io/opencensus/trace/SpanContext.java index 8847a3ce8f..56a046f183 100644 --- a/api/src/main/java/io/opencensus/trace/SpanContext.java +++ b/api/src/main/java/io/opencensus/trace/SpanContext.java @@ -15,9 +15,6 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Objects; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; import javax.annotation.concurrent.Immutable; /** diff --git a/api/src/main/java/io/opencensus/trace/base/SpanId.java b/api/src/main/java/io/opencensus/trace/SpanId.java similarity index 99% rename from api/src/main/java/io/opencensus/trace/base/SpanId.java rename to api/src/main/java/io/opencensus/trace/SpanId.java index 4e0b1bedca..8128c9d7de 100644 --- a/api/src/main/java/io/opencensus/trace/base/SpanId.java +++ b/api/src/main/java/io/opencensus/trace/SpanId.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/api/src/main/java/io/opencensus/trace/base/Status.java b/api/src/main/java/io/opencensus/trace/Status.java similarity index 99% rename from api/src/main/java/io/opencensus/trace/base/Status.java rename to api/src/main/java/io/opencensus/trace/Status.java index e0ab490463..fab8a83360 100644 --- a/api/src/main/java/io/opencensus/trace/base/Status.java +++ b/api/src/main/java/io/opencensus/trace/Status.java @@ -11,14 +11,13 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; -import io.opencensus.trace.Span; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/api/src/main/java/io/opencensus/trace/base/TraceId.java b/api/src/main/java/io/opencensus/trace/TraceId.java similarity index 99% rename from api/src/main/java/io/opencensus/trace/base/TraceId.java rename to api/src/main/java/io/opencensus/trace/TraceId.java index 293e2a7215..191f593fd1 100644 --- a/api/src/main/java/io/opencensus/trace/base/TraceId.java +++ b/api/src/main/java/io/opencensus/trace/TraceId.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/api/src/main/java/io/opencensus/trace/base/TraceOptions.java b/api/src/main/java/io/opencensus/trace/TraceOptions.java similarity index 99% rename from api/src/main/java/io/opencensus/trace/base/TraceOptions.java rename to api/src/main/java/io/opencensus/trace/TraceOptions.java index 3f20bb99b6..d41737fa44 100644 --- a/api/src/main/java/io/opencensus/trace/base/TraceOptions.java +++ b/api/src/main/java/io/opencensus/trace/TraceOptions.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkElementIndex; diff --git a/api/src/main/java/io/opencensus/trace/config/TraceParams.java b/api/src/main/java/io/opencensus/trace/config/TraceParams.java index d07ae0434f..7319234824 100644 --- a/api/src/main/java/io/opencensus/trace/config/TraceParams.java +++ b/api/src/main/java/io/opencensus/trace/config/TraceParams.java @@ -16,11 +16,11 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.auto.value.AutoValue; +import io.opencensus.trace.Annotation; +import io.opencensus.trace.Link; +import io.opencensus.trace.NetworkEvent; import io.opencensus.trace.Sampler; import io.opencensus.trace.Span; -import io.opencensus.trace.base.Annotation; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.NetworkEvent; import io.opencensus.trace.samplers.Samplers; import javax.annotation.concurrent.Immutable; diff --git a/api/src/main/java/io/opencensus/trace/export/ExportComponent.java b/api/src/main/java/io/opencensus/trace/export/ExportComponent.java index f1199e3984..be5cad4727 100644 --- a/api/src/main/java/io/opencensus/trace/export/ExportComponent.java +++ b/api/src/main/java/io/opencensus/trace/export/ExportComponent.java @@ -13,7 +13,7 @@ package io.opencensus.trace.export; -import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.TraceOptions; import javax.annotation.Nullable; /** diff --git a/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java b/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java index 0a47f4dd1c..316cc36bee 100644 --- a/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java +++ b/api/src/main/java/io/opencensus/trace/export/SampledSpanStore.java @@ -18,8 +18,8 @@ import com.google.auto.value.AutoValue; import io.opencensus.trace.Span; -import io.opencensus.trace.base.Status; -import io.opencensus.trace.base.Status.CanonicalCode; +import io.opencensus.trace.Status; +import io.opencensus.trace.Status.CanonicalCode; import java.util.Collection; import java.util.Collections; import java.util.HashMap; diff --git a/api/src/main/java/io/opencensus/trace/export/SpanData.java b/api/src/main/java/io/opencensus/trace/export/SpanData.java index 73e03f468d..762335af32 100644 --- a/api/src/main/java/io/opencensus/trace/export/SpanData.java +++ b/api/src/main/java/io/opencensus/trace/export/SpanData.java @@ -17,14 +17,14 @@ import com.google.auto.value.AutoValue; import io.opencensus.common.Timestamp; +import io.opencensus.trace.Annotation; +import io.opencensus.trace.AttributeValue; +import io.opencensus.trace.Link; +import io.opencensus.trace.NetworkEvent; import io.opencensus.trace.Span; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.Annotation; -import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.NetworkEvent; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.Status; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.Status; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; diff --git a/api/src/main/java/io/opencensus/trace/export/SpanExporter.java b/api/src/main/java/io/opencensus/trace/export/SpanExporter.java index bfae4bad82..44b9548840 100644 --- a/api/src/main/java/io/opencensus/trace/export/SpanExporter.java +++ b/api/src/main/java/io/opencensus/trace/export/SpanExporter.java @@ -14,7 +14,7 @@ package io.opencensus.trace.export; import io.opencensus.trace.Span; -import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.TraceOptions; import java.util.Collection; import javax.annotation.concurrent.ThreadSafe; diff --git a/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java b/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java index f78fcd18f2..e20265d9f8 100644 --- a/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java +++ b/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java @@ -16,8 +16,8 @@ import io.opencensus.trace.Sampler; import io.opencensus.trace.Span; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; import java.util.List; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; diff --git a/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java b/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java index 9fa8ea7bf8..f773f3a7bb 100644 --- a/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java +++ b/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java @@ -16,8 +16,8 @@ import io.opencensus.trace.Sampler; import io.opencensus.trace.Span; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; import java.util.List; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; diff --git a/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java b/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java index 1173562922..7a4029e5ca 100644 --- a/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java +++ b/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java @@ -19,8 +19,8 @@ import io.opencensus.trace.Sampler; import io.opencensus.trace.Span; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; import java.util.List; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; diff --git a/api/src/test/java/io/opencensus/trace/base/AnnotationTest.java b/api/src/test/java/io/opencensus/trace/AnnotationTest.java similarity index 99% rename from api/src/test/java/io/opencensus/trace/base/AnnotationTest.java rename to api/src/test/java/io/opencensus/trace/AnnotationTest.java index c6e0c2ceab..fbfe5fd354 100644 --- a/api/src/test/java/io/opencensus/trace/base/AnnotationTest.java +++ b/api/src/test/java/io/opencensus/trace/AnnotationTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/base/AttributeValueTest.java b/api/src/test/java/io/opencensus/trace/AttributeValueTest.java similarity index 98% rename from api/src/test/java/io/opencensus/trace/base/AttributeValueTest.java rename to api/src/test/java/io/opencensus/trace/AttributeValueTest.java index 43f85aa48f..7a999604e4 100644 --- a/api/src/test/java/io/opencensus/trace/base/AttributeValueTest.java +++ b/api/src/test/java/io/opencensus/trace/AttributeValueTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/BlankSpanTest.java b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java index f9690321b0..ad1eea8b1e 100644 --- a/api/src/test/java/io/opencensus/trace/BlankSpanTest.java +++ b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java @@ -15,10 +15,6 @@ import static com.google.common.truth.Truth.assertThat; -import io.opencensus.trace.base.Annotation; -import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.NetworkEvent; import java.util.HashMap; import java.util.Map; import org.junit.Test; diff --git a/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java b/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java index 5fc50b7b52..d531fba551 100644 --- a/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java +++ b/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java @@ -16,7 +16,6 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import io.opencensus.trace.base.Status; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/api/src/test/java/io/opencensus/trace/base/LinkTest.java b/api/src/test/java/io/opencensus/trace/LinkTest.java similarity index 96% rename from api/src/test/java/io/opencensus/trace/base/LinkTest.java rename to api/src/test/java/io/opencensus/trace/LinkTest.java index d0bfc46eb5..e6b4afe57b 100644 --- a/api/src/test/java/io/opencensus/trace/base/LinkTest.java +++ b/api/src/test/java/io/opencensus/trace/LinkTest.java @@ -11,13 +11,12 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.Link.Type; +import io.opencensus.trace.Link.Type; import java.util.Random; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/api/src/test/java/io/opencensus/trace/base/NetworkEventTest.java b/api/src/test/java/io/opencensus/trace/NetworkEventTest.java similarity index 99% rename from api/src/test/java/io/opencensus/trace/base/NetworkEventTest.java rename to api/src/test/java/io/opencensus/trace/NetworkEventTest.java index 09d796ee00..946e8ce142 100644 --- a/api/src/test/java/io/opencensus/trace/base/NetworkEventTest.java +++ b/api/src/test/java/io/opencensus/trace/NetworkEventTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/SpanContextTest.java b/api/src/test/java/io/opencensus/trace/SpanContextTest.java index eaa5bfc9f0..c0eb5d407f 100644 --- a/api/src/test/java/io/opencensus/trace/SpanContextTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanContextTest.java @@ -16,9 +16,6 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/api/src/test/java/io/opencensus/trace/base/SpanIdTest.java b/api/src/test/java/io/opencensus/trace/SpanIdTest.java similarity index 98% rename from api/src/test/java/io/opencensus/trace/base/SpanIdTest.java rename to api/src/test/java/io/opencensus/trace/SpanIdTest.java index 6db2dc8181..a35fddce62 100644 --- a/api/src/test/java/io/opencensus/trace/base/SpanIdTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanIdTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/SpanTest.java b/api/src/test/java/io/opencensus/trace/SpanTest.java index 186e6b1bd6..c8f7cb503f 100644 --- a/api/src/test/java/io/opencensus/trace/SpanTest.java +++ b/api/src/test/java/io/opencensus/trace/SpanTest.java @@ -17,13 +17,6 @@ import static org.mockito.Matchers.same; import static org.mockito.Mockito.verify; -import io.opencensus.trace.base.Annotation; -import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.NetworkEvent; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; import java.util.EnumSet; import java.util.Map; import java.util.Random; diff --git a/api/src/test/java/io/opencensus/trace/base/StatusTest.java b/api/src/test/java/io/opencensus/trace/StatusTest.java similarity index 98% rename from api/src/test/java/io/opencensus/trace/base/StatusTest.java rename to api/src/test/java/io/opencensus/trace/StatusTest.java index b8c2e19b07..c66a3428f4 100644 --- a/api/src/test/java/io/opencensus/trace/base/StatusTest.java +++ b/api/src/test/java/io/opencensus/trace/StatusTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/base/TraceIdTest.java b/api/src/test/java/io/opencensus/trace/TraceIdTest.java similarity index 98% rename from api/src/test/java/io/opencensus/trace/base/TraceIdTest.java rename to api/src/test/java/io/opencensus/trace/TraceIdTest.java index dd87d40d1b..cd1b7c24f0 100644 --- a/api/src/test/java/io/opencensus/trace/base/TraceIdTest.java +++ b/api/src/test/java/io/opencensus/trace/TraceIdTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/base/TraceOptionsTest.java b/api/src/test/java/io/opencensus/trace/TraceOptionsTest.java similarity index 98% rename from api/src/test/java/io/opencensus/trace/base/TraceOptionsTest.java rename to api/src/test/java/io/opencensus/trace/TraceOptionsTest.java index 0d247347dc..fb24064662 100644 --- a/api/src/test/java/io/opencensus/trace/base/TraceOptionsTest.java +++ b/api/src/test/java/io/opencensus/trace/TraceOptionsTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.base; +package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; diff --git a/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java index 6ea20fcc01..aeb99abfd4 100644 --- a/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java +++ b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java @@ -17,16 +17,16 @@ import com.google.common.testing.EqualsTester; import io.opencensus.common.Timestamp; +import io.opencensus.trace.Annotation; +import io.opencensus.trace.AttributeValue; +import io.opencensus.trace.Link; +import io.opencensus.trace.Link.Type; +import io.opencensus.trace.NetworkEvent; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.Annotation; -import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.Link.Type; -import io.opencensus.trace.base.NetworkEvent; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.Status; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.Status; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; import io.opencensus.trace.export.SpanData.Attributes; import io.opencensus.trace.export.SpanData.Links; import io.opencensus.trace.export.SpanData.TimedEvent; diff --git a/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java b/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java index 12ec754810..8b9d782ae8 100644 --- a/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java +++ b/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java @@ -18,9 +18,9 @@ import io.opencensus.trace.Sampler; import io.opencensus.trace.Span; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; import java.util.Collections; import java.util.Random; import org.junit.Test; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java index 00f68efdc0..d35f2673c8 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java @@ -13,9 +13,6 @@ package io.opencensus.trace; -import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.NetworkEvent; import io.opencensus.trace.samplers.Samplers; import java.util.HashMap; import java.util.concurrent.TimeUnit; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java index de821b0695..36040c594a 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java @@ -13,9 +13,6 @@ package io.opencensus.trace; -import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.NetworkEvent; import io.opencensus.trace.samplers.Samplers; import java.util.HashMap; import java.util.concurrent.TimeUnit; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java index d99f0dbd02..b5a658364c 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java @@ -14,9 +14,9 @@ package io.opencensus.trace.propagation; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; import java.text.ParseException; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java index e001d4b2e0..66f6451840 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java @@ -17,11 +17,7 @@ import io.opencensus.common.Clock; import io.opencensus.internal.TimestampConverter; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.Link.Type; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.Link.Type; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.internal.RandomHandler; diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java index b5483e8f3f..c2c6489def 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java @@ -20,12 +20,6 @@ import com.google.common.collect.EvictingQueue; import io.opencensus.common.Clock; import io.opencensus.internal.TimestampConverter; -import io.opencensus.trace.base.Annotation; -import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.NetworkEvent; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.Status; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.export.SpanData; import io.opencensus.trace.export.SpanData.TimedEvent; diff --git a/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java b/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java index b9a62e00be..33ec009633 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java @@ -15,8 +15,8 @@ import com.google.common.collect.EvictingQueue; import io.opencensus.trace.SpanImpl; -import io.opencensus.trace.base.Status; -import io.opencensus.trace.base.Status.CanonicalCode; +import io.opencensus.trace.Status; +import io.opencensus.trace.Status.CanonicalCode; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; diff --git a/impl_core/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java b/impl_core/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java index 890d5821ea..a4cb675f70 100644 --- a/impl_core/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java @@ -16,9 +16,9 @@ import static com.google.common.base.Preconditions.checkNotNull; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; import java.text.ParseException; /** diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java index 3e827485e1..5088e0e535 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java @@ -19,9 +19,6 @@ import io.opencensus.testing.common.TestClock; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.export.SpanData; diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java index 4db23b2f9c..6b74e5d19a 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java @@ -21,14 +21,6 @@ import io.opencensus.testing.common.TestClock; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanImpl.StartEndHandler; -import io.opencensus.trace.base.Annotation; -import io.opencensus.trace.base.AttributeValue; -import io.opencensus.trace.base.Link; -import io.opencensus.trace.base.NetworkEvent; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.Status; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.export.SpanData; import java.util.EnumSet; diff --git a/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreTest.java b/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreImplTest.java similarity index 96% rename from impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreTest.java rename to impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreImplTest.java index 16fc1f6e85..e3f408ee99 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreImplTest.java @@ -19,12 +19,12 @@ import io.opencensus.internal.SimpleEventQueue; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; import io.opencensus.trace.SpanImpl; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.StartEndHandlerImpl; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.export.RunningSpanStore.Filter; import java.util.EnumSet; @@ -33,9 +33,9 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@link RunningSpanStore}. */ +/** Unit tests for {@link RunningSpanStoreImpl}. */ @RunWith(JUnit4.class) -public class RunningSpanStoreTest { +public class RunningSpanStoreImplTest { private static final String SPAN_NAME_1 = "MySpanName/1"; private static final String SPAN_NAME_2 = "MySpanName/2"; diff --git a/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java index 46d7ccd493..fc82e61289 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java @@ -22,13 +22,13 @@ import io.opencensus.trace.Span; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; import io.opencensus.trace.SpanImpl; import io.opencensus.trace.SpanImpl.StartEndHandler; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.Status; -import io.opencensus.trace.base.Status.CanonicalCode; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.Status; +import io.opencensus.trace.Status.CanonicalCode; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.export.SampledSpanStore.ErrorFilter; import io.opencensus.trace.export.SampledSpanStore.LatencyBucketBoundaries; diff --git a/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java index b46987c50e..3c1900f851 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java @@ -21,12 +21,12 @@ import io.opencensus.internal.SimpleEventQueue; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; import io.opencensus.trace.SpanImpl; import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.StartEndHandlerImpl; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.export.SpanExporter.Handler; import java.util.ArrayList; diff --git a/impl_core/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java b/impl_core/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java index 6bc75578d3..b16c453b51 100644 --- a/impl_core/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java @@ -17,9 +17,9 @@ import static com.google.common.truth.Truth.assertWithMessage; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.base.SpanId; -import io.opencensus.trace.base.TraceId; -import io.opencensus.trace.base.TraceOptions; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; import java.text.ParseException; import org.junit.Rule; import org.junit.Test; From 77a930ffdf35c854b3d5da998eaef8cef8749698 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Thu, 6 Jul 2017 11:15:46 -0700 Subject: [PATCH 0229/1581] Refactor MeasurementValue and MeasurementMap (#405) --- .../java/io/opencensus/stats/MeasureMap.java | 125 +++++++++++++++ .../java/io/opencensus/stats/Measurement.java | 92 +++++++++++ .../io/opencensus/stats/MeasurementMap.java | 147 ------------------ .../io/opencensus/stats/MeasurementValue.java | 49 ------ .../io/opencensus/stats/StatsContext.java | 2 +- .../io/opencensus/stats/StatsRecorder.java | 2 +- .../io/opencensus/stats/MeasureMapTest.java | 123 +++++++++++++++ .../opencensus/stats/MeasurementMapTest.java | 116 -------------- .../io/opencensus/stats/MeasureToViewMap.java | 40 ++++- .../io/opencensus/stats/StatsContextImpl.java | 2 +- .../io/opencensus/stats/StatsManager.java | 6 +- .../opencensus/stats/StatsRecorderImpl.java | 2 +- .../stats/MeasureToViewMapTest.java | 3 +- .../io/opencensus/stats/StatsContextTest.java | 45 ++++-- .../opencensus/stats/ViewManagerImplTest.java | 56 ++++--- .../examples/stats/StatsRunner.java | 18 ++- 16 files changed, 461 insertions(+), 367 deletions(-) create mode 100644 core/src/main/java/io/opencensus/stats/MeasureMap.java create mode 100644 core/src/main/java/io/opencensus/stats/Measurement.java delete mode 100644 core/src/main/java/io/opencensus/stats/MeasurementMap.java delete mode 100644 core/src/main/java/io/opencensus/stats/MeasurementValue.java create mode 100644 core/src/test/java/io/opencensus/stats/MeasureMapTest.java delete mode 100644 core/src/test/java/io/opencensus/stats/MeasurementMapTest.java diff --git a/core/src/main/java/io/opencensus/stats/MeasureMap.java b/core/src/main/java/io/opencensus/stats/MeasureMap.java new file mode 100644 index 0000000000..5c9bb61b6f --- /dev/null +++ b/core/src/main/java/io/opencensus/stats/MeasureMap.java @@ -0,0 +1,125 @@ +/* + * Copyright 2016, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import io.opencensus.stats.Measure.DoubleMeasure; +import io.opencensus.stats.Measure.LongMeasure; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * A map from {@link Measure}'s to measured values. + */ +public final class MeasureMap { + + /** + * Returns a {@link Builder} for the {@link MeasureMap} class. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Returns an {@link Iterator} over the measure/value mappings in this {@link MeasureMap}. + * The {@code Iterator} does not support {@link Iterator#remove()}. + */ + Iterator iterator() { + return new MeasureMapIterator(); + } + + private final ArrayList measurements; + + private MeasureMap(ArrayList measurements) { + this.measurements = measurements; + } + + /** + * Builder for the {@link MeasureMap} class. + */ + public static class Builder { + /** + * Associates the {@link DoubleMeasure} with the given value. Subsequent updates to the + * same {@link DoubleMeasure} are ignored. + * + * @param measure the {@link DoubleMeasure} + * @param value the value to be associated with {@code measure} + * @return this + */ + public Builder set(DoubleMeasure measure, double value) { + measurements.add(Measurement.DoubleMeasurement.create(measure, value)); + return this; + } + + /** + * Associates the {@link LongMeasure} with the given value. Subsequent updates to the + * same {@link LongMeasure} are ignored. + * + * @param measure the {@link LongMeasure} + * @param value the value to be associated with {@code measure} + * @return this + */ + public Builder set(LongMeasure measure, long value) { + measurements.add(Measurement.LongMeasurement.create(measure, value)); + return this; + } + + /** + * Constructs a {@link MeasureMap} from the current measurements. + */ + public MeasureMap build() { + // Note: this makes adding measurements quadratic but is fastest for the sizes of + // MeasureMaps that we should see. We may want to go to a strategy of sort/eliminate + // for larger MeasureMaps. + for (int i = 0; i < measurements.size(); i++) { + for (int j = i + 1; j < measurements.size(); j++) { + if (measurements.get(i).getMeasure() == measurements.get(j).getMeasure()) { + measurements.remove(j); + j--; + } + } + } + return new MeasureMap(measurements); + } + + private final ArrayList measurements = new ArrayList(); + + private Builder() { + } + } + + // Provides an unmodifiable Iterator over this instance's measurements. + private final class MeasureMapIterator implements Iterator { + @Override + public boolean hasNext() { + return position < length; + } + + @Override + public Measurement next() { + if (position >= measurements.size()) { + throw new NoSuchElementException(); + } + return measurements.get(position++); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + private final int length = measurements.size(); + private int position = 0; + } +} diff --git a/core/src/main/java/io/opencensus/stats/Measurement.java b/core/src/main/java/io/opencensus/stats/Measurement.java new file mode 100644 index 0000000000..eeaaa0a55e --- /dev/null +++ b/core/src/main/java/io/opencensus/stats/Measurement.java @@ -0,0 +1,92 @@ +/* + * Copyright 2016, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import com.google.auto.value.AutoValue; +import io.opencensus.common.Function; +import io.opencensus.stats.Measure.DoubleMeasure; +import io.opencensus.stats.Measure.LongMeasure; +import javax.annotation.concurrent.Immutable; + +/** Immutable representation of a Measurement. */ +@Immutable +public abstract class Measurement { + + /** + * Applies the given match function to the underlying data type. + */ + public abstract T match( + Function p0, Function p1); + + /** + * Extracts the measured {@link Measure}. + */ + public abstract Measure getMeasure(); + + // Prevents this class from being subclassed anywhere else. + private Measurement() { + } + + @Immutable + @AutoValue + public abstract static class DoubleMeasurement extends Measurement { + + DoubleMeasurement() { + } + + /** + * Constructs a new {@link DoubleMeasurement}. + */ + public static DoubleMeasurement create(DoubleMeasure measure, double value) { + return new AutoValue_Measurement_DoubleMeasurement(measure, value); + } + + @Override + public abstract DoubleMeasure getMeasure(); + + public abstract Double getValue(); + + @Override + public T match( + Function p0, Function p1) { + return p0.apply(this); + } + } + + @Immutable + @AutoValue + public abstract static class LongMeasurement extends Measurement { + + LongMeasurement() { + } + + /** + * Constructs a new {@link LongMeasurement}. + */ + public static LongMeasurement create(LongMeasure measure, long value) { + return new AutoValue_Measurement_LongMeasurement(measure, value); + } + + @Override + public abstract LongMeasure getMeasure(); + + public abstract Long getValue(); + + @Override + public T match( + Function p0, Function p1) { + return p1.apply(this); + } + } +} diff --git a/core/src/main/java/io/opencensus/stats/MeasurementMap.java b/core/src/main/java/io/opencensus/stats/MeasurementMap.java deleted file mode 100644 index 6694a93398..0000000000 --- a/core/src/main/java/io/opencensus/stats/MeasurementMap.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * A map from {@link Measure}'s to measured values. - */ -public final class MeasurementMap implements Iterable { - /** - * Constructs a {@link MeasurementMap} from the given {@link Measure} - * and associated value. - */ - public static MeasurementMap of(Measure measure, double value) { - return builder().put(measure, value).build(); - } - - /** - * Constructs a {@link MeasurementMap} from the given {@link Measure}'s - * and associated values. - */ - public static MeasurementMap of(Measure measure1, double value1, - Measure measure2, double value2) { - return builder().put(measure1, value1).put(measure2, value2).build(); - } - - /** - * Constructs a {@link MeasurementMap} from the given {@link Measure}'s - * and associated values. - */ - public static MeasurementMap of(Measure measure1, double value1, - Measure measure2, double value2, - Measure measure3, double value3) { - return builder().put(measure1, value1).put(measure2, value2).put(measure3, value3) - .build(); - } - - /** - * Returns a {@link Builder} for the {@link MeasurementMap} class. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Returns the number of measures in this {@link MeasurementMap}. - */ - public int size() { - return measures.size(); - } - - /** - * Returns an {@link Iterator} over the measure/value mappings in this {@link MeasurementMap}. - * The {@code Iterator} does not support {@link Iterator#remove()}. - */ - @Override - public Iterator iterator() { - return new MeasurementMapIterator(); - } - - private final ArrayList measures; - - private MeasurementMap(ArrayList measures) { - this.measures = measures; - } - - /** - * Builder for the {@link MeasurementMap} class. - */ - public static class Builder { - /** - * Associates the {@link Measure} with the given value. Subsequent updates to the - * same {@link Measure} are ignored. - * - * @param measure the {@link Measure} - * @param value the value to be associated with {@code measure} - * @return this - */ - public Builder put(Measure measure, double value) { - measures.add(MeasurementValue.create(measure, value)); - return this; - } - - /** - * Constructs a {@link MeasurementMap} from the current measures. - */ - public MeasurementMap build() { - // Note: this makes adding measures quadratic but is fastest for the sizes of - // MeasurementMaps that we should see. We may want to go to a strategy of sort/eliminate - // for larger MeasurementMaps. - for (int i = 0; i < measures.size(); i++) { - String current = - measures.get(i).getMeasurement().getName(); - for (int j = i + 1; j < measures.size(); j++) { - if (current.equals(measures.get(j).getMeasurement().getName())) { - measures.remove(j); - j--; - } - } - } - return new MeasurementMap(measures); - } - - private final ArrayList measures = new ArrayList(); - - private Builder() { - } - } - - // Provides an unmodifiable Iterator over this instance's measures. - private final class MeasurementMapIterator implements Iterator { - @Override - public boolean hasNext() { - return position < length; - } - - @Override - public MeasurementValue next() { - if (position >= measures.size()) { - throw new NoSuchElementException(); - } - return measures.get(position++); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - private final int length = measures.size(); - private int position = 0; - } -} diff --git a/core/src/main/java/io/opencensus/stats/MeasurementValue.java b/core/src/main/java/io/opencensus/stats/MeasurementValue.java deleted file mode 100644 index efee6f3954..0000000000 --- a/core/src/main/java/io/opencensus/stats/MeasurementValue.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -/** - * Immutable representation of a MeasurementValue. - */ -public class MeasurementValue { - - /** - * Constructs a measured value. - */ - public static MeasurementValue create(Measure name, double value) { - return new MeasurementValue(name, value); - } - - /** - * Extracts the measured {@link Measure}. - */ - public Measure getMeasurement() { - return name; - } - - /** - * Extracts the associated value. - */ - public double getValue() { - return value; - } - - private final Measure name; - private final double value; - - private MeasurementValue(Measure name, double value) { - this.name = name; - this.value = value; - } -} diff --git a/core/src/main/java/io/opencensus/stats/StatsContext.java b/core/src/main/java/io/opencensus/stats/StatsContext.java index 1be9434452..b29675390b 100644 --- a/core/src/main/java/io/opencensus/stats/StatsContext.java +++ b/core/src/main/java/io/opencensus/stats/StatsContext.java @@ -49,7 +49,7 @@ public final StatsContext with( * @param measurements the measurements to record against the saved {@link StatsContext} * @return this */ - public abstract StatsContext record(MeasurementMap measurements); + public abstract StatsContext record(MeasureMap measurements); /** * Serializes the {@link StatsContext} into the on-the-wire representation. diff --git a/core/src/main/java/io/opencensus/stats/StatsRecorder.java b/core/src/main/java/io/opencensus/stats/StatsRecorder.java index fc183754bb..f93ad9ed2b 100644 --- a/core/src/main/java/io/opencensus/stats/StatsRecorder.java +++ b/core/src/main/java/io/opencensus/stats/StatsRecorder.java @@ -27,5 +27,5 @@ public abstract class StatsRecorder { * @param tags the tags associated with the measurements. * @param measurementValues the measurements to record. */ - abstract void record(StatsContext tags, MeasurementMap measurementValues); + abstract void record(StatsContext tags, MeasureMap measurementValues); } diff --git a/core/src/test/java/io/opencensus/stats/MeasureMapTest.java b/core/src/test/java/io/opencensus/stats/MeasureMapTest.java new file mode 100644 index 0000000000..ce71497db6 --- /dev/null +++ b/core/src/test/java/io/opencensus/stats/MeasureMapTest.java @@ -0,0 +1,123 @@ +/* + * Copyright 2016, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import io.opencensus.stats.Measure.DoubleMeasure; +import io.opencensus.stats.Measure.LongMeasure; +import java.util.ArrayList; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link MeasureMap} */ +@RunWith(JUnit4.class) +public class MeasureMapTest { + + @Test + public void testPutDouble() { + MeasureMap metrics = MeasureMap.builder().set(M1, 44.4).build(); + assertContains(metrics, Measurement.DoubleMeasurement.create(M1, 44.4)); + } + + @Test + public void testPutLong() { + MeasureMap metrics = MeasureMap.builder().set(M3, 9999L).set(M4, 8888L).build(); + assertContains(metrics, + Measurement.LongMeasurement.create(M3, 9999L), + Measurement.LongMeasurement.create(M4, 8888L)); + } + + @Test + public void testCombination() { + MeasureMap metrics = + MeasureMap.builder().set(M1, 44.4).set(M2, 66.6).set(M3, 9999L).set(M4, 8888L).build(); + assertContains(metrics, + Measurement.DoubleMeasurement.create(M1, 44.4), + Measurement.DoubleMeasurement.create(M2, 66.6), + Measurement.LongMeasurement.create(M3, 9999L), + Measurement.LongMeasurement.create(M4, 8888L)); + } + + @Test + public void testBuilderEmpty() { + MeasureMap metrics = MeasureMap.builder().build(); + assertContains(metrics); + } + + @Test + public void testBuilder() { + ArrayList expected = new ArrayList(10); + MeasureMap.Builder builder = MeasureMap.builder(); + for (int i = 1; i <= 10; i++) { + expected + .add(Measurement.DoubleMeasurement.create(makeSimpleDoubleMeasure("m" + i), i * 11.1)); + builder.set(makeSimpleDoubleMeasure("m" + i), i * 11.1); + assertContains(builder.build(), expected.toArray(new Measurement[i])); + } + } + + @Test + public void testDuplicateDoubleMeasures() { + assertContains(MeasureMap.builder().set(M1, 1.0).set(M1, 2.0).build(), MEASUREMENT_1); + assertContains(MeasureMap.builder().set(M1, 1.0).set(M1, 2.0).set(M1, 3.0).build(), MEASUREMENT_1); + assertContains(MeasureMap.builder().set(M1, 1.0).set(M2, 2.0).set(M1, 3.0).build(), MEASUREMENT_1, + MEASUREMENT_2); + assertContains(MeasureMap.builder().set(M1, 1.0).set(M1, 2.0).set(M2, 2.0).build(), MEASUREMENT_1, + MEASUREMENT_2); + } + + @Test + public void testDuplicateLongMeasures() { + assertContains(MeasureMap.builder().set(M3, 100L).set(M3, 100L).build(), MEASUREMENT_3); + assertContains(MeasureMap.builder().set(M3, 100L).set(M3, 200L).set(M3, 300L).build(), + MEASUREMENT_3); + assertContains(MeasureMap.builder().set(M3, 100L).set(M4, 200L).set(M3, 300L).build(), + MEASUREMENT_3, MEASUREMENT_4); + assertContains(MeasureMap.builder().set(M3, 100L).set(M3, 200L).set(M4, 200L).build(), + MEASUREMENT_3, MEASUREMENT_4); + } + + @Test + public void testDuplicateMeasures() { + assertContains(MeasureMap.builder().set(M3, 100L).set(M1, 1.0).set(M3, 300L).build(), + MEASUREMENT_3, MEASUREMENT_1); + assertContains(MeasureMap.builder().set(M2, 2.0).set(M3, 100L).set(M2, 3.0).build(), + MEASUREMENT_2, MEASUREMENT_3); + } + + private static final DoubleMeasure M1 = makeSimpleDoubleMeasure("m1"); + private static final DoubleMeasure M2 = makeSimpleDoubleMeasure("m2"); + private static final LongMeasure M3 = makeSimpleLongMeasure("m3"); + private static final LongMeasure M4 = makeSimpleLongMeasure("m4"); + + private static final Measurement MEASUREMENT_1 = Measurement.DoubleMeasurement.create(M1, 1.0); + private static final Measurement MEASUREMENT_2 = Measurement.DoubleMeasurement.create(M2, 2.0); + private static final Measurement MEASUREMENT_3 = Measurement.LongMeasurement.create(M3, 100L); + private static final Measurement MEASUREMENT_4 = Measurement.LongMeasurement.create(M4, 200L); + + private static DoubleMeasure makeSimpleDoubleMeasure(String measure) { + return Measure.DoubleMeasure.create(measure, measure + " description", "1"); + } + + private static LongMeasure makeSimpleLongMeasure(String measure) { + return Measure.LongMeasure.create(measure, measure + " description", "1"); + } + + private static void assertContains(MeasureMap metrics, Measurement... measurements) { + assertThat(Lists.newArrayList(metrics.iterator())).containsExactly((Object[]) measurements); + } +} diff --git a/core/src/test/java/io/opencensus/stats/MeasurementMapTest.java b/core/src/test/java/io/opencensus/stats/MeasurementMapTest.java deleted file mode 100644 index ad5af9ba63..0000000000 --- a/core/src/test/java/io/opencensus/stats/MeasurementMapTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.collect.ImmutableList; -import java.util.ArrayList; -import java.util.Iterator; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests for {@link MeasurementMap} - */ -@RunWith(JUnit4.class) -public class MeasurementMapTest { - @Test - public void testOf1() { - ImmutableList expected = ImmutableList.of(MeasurementValue.create(M1, 44.4)); - MeasurementMap metrics = MeasurementMap.of(M1, 44.4); - assertEquals(expected, metrics); - } - - @Test - public void testOf2() { - ImmutableList expected = ImmutableList.of( - MeasurementValue.create(M1, 44.4), MeasurementValue.create(M2, 66.6)); - MeasurementMap metrics = MeasurementMap.of(M1, 44.4, M2, 66.6); - assertEquals(expected, metrics); - } - - @Test - public void testOf3() { - ImmutableList expected = ImmutableList.of( - MeasurementValue.create(M1, 44.4), - MeasurementValue.create(M2, 66.6), - MeasurementValue.create(M3, 88.8)); - MeasurementMap metrics = MeasurementMap.of( - M1, 44.4, M2, 66.6, M3, 88.8); - assertEquals(expected, metrics); - } - - @Test - public void testBuilderEmpty() { - ImmutableList expected = ImmutableList.of(); - MeasurementMap metrics = MeasurementMap.builder().build(); - assertEquals(expected, metrics); - } - - @Test - public void testBuilder() { - ArrayList expected = new ArrayList(10); - MeasurementMap.Builder builder = MeasurementMap.builder(); - for (int i = 1; i <= 10; i++) { - expected.add(MeasurementValue.create(makeSimpleMeasure("m" + i), i * 11.1)); - builder.put(makeSimpleMeasure("m" + i), i * 11.1); - assertEquals(expected, builder.build()); - } - } - - @Test - public void testDuplicateMeasures() { - assertEquals(MeasurementMap.of(M1, 1.0, M1, 1.0), MeasurementMap.of(M1, 1.0)); - assertEquals(MeasurementMap.of(M1, 1.0, M1, 2.0), MeasurementMap.of(M1, 1.0)); - assertEquals(MeasurementMap.of(M1, 1.0, M1, 2.0, M1, 3.0), MeasurementMap.of(M1, 1.0)); - assertEquals(MeasurementMap.of(M1, 1.0, M2, 2.0, M1, 3.0), MeasurementMap.of(M1, 1.0, M2, 2.0)); - assertEquals(MeasurementMap.of(M1, 1.0, M1, 2.0, M2, 2.0), MeasurementMap.of(M1, 1.0, M2, 2.0)); - } - - @Test - public void testSize() { - MeasurementMap.Builder builder = MeasurementMap.builder(); - for (int i = 1; i <= 10; i++) { - builder.put(makeSimpleMeasure("m" + i), i * 11.1); - assertThat(builder.build()).hasSize(i); - } - } - - private static final Measure M1 = makeSimpleMeasure("m1"); - private static final Measure M2 = makeSimpleMeasure("m2"); - private static final Measure M3 = makeSimpleMeasure("m3"); - - private static final Measure makeSimpleMeasure(String measure) { - return Measure.DoubleMeasure.create( - measure, measure + " description", "1"); - } - - private static void assertEquals( - Iterable expected, Iterable actual) { - Iterator e = expected.iterator(); - Iterator a = actual.iterator(); - while (e.hasNext() && a.hasNext()) { - MeasurementValue expectedMeasurement = e.next(); - MeasurementValue actualMeasurement = a.next(); - assertThat(expectedMeasurement.getMeasurement().getName()) - .isEqualTo(actualMeasurement.getMeasurement().getName()); - assertThat(expectedMeasurement.getValue()) - .isWithin(0.00000001).of(actualMeasurement.getValue()); - } - assertThat(e.hasNext()).isFalse(); - assertThat(a.hasNext()).isFalse(); - } -} diff --git a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java index 128c1f52db..e4d89a91b9 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java +++ b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java @@ -17,12 +17,15 @@ import com.google.common.collect.Multimap; import io.opencensus.common.Clock; import io.opencensus.common.Function; +import io.opencensus.stats.Measurement.DoubleMeasurement; +import io.opencensus.stats.Measurement.LongMeasurement; import io.opencensus.stats.MutableView.MutableDistributionView; import io.opencensus.stats.MutableView.MutableIntervalView; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; @@ -90,18 +93,20 @@ synchronized void registerView(ViewDescriptor viewDescriptor, Clock clock) { } // Records stats with a set of tags. - synchronized void record(StatsContextImpl tags, MeasurementMap stats) { - for (MeasurementValue mv : stats) { - Collection views = - mutableMap.get(mv.getMeasurement().getName()); + synchronized void record(StatsContextImpl tags, MeasureMap stats) { + Iterator iterator = stats.iterator(); + while (iterator.hasNext()) { + Measurement measurement = iterator.next(); + Collection views = mutableMap.get(measurement.getMeasure().getName()); for (MutableView view : views) { - view.record(tags, mv.getValue()); + measurement.match(new RecordDoubleValueFunc(tags, view), new RecordLongValueFunc()); } } } private static final class CreateMutableDistributionViewFunction implements Function { + private final Clock clock; CreateMutableDistributionViewFunction(Clock clock) { @@ -116,10 +121,35 @@ public MutableView apply(DistributionViewDescriptor viewDescriptor) { private static final class CreateMutableIntervalViewFunction implements Function { + @Override public MutableView apply(IntervalViewDescriptor viewDescriptor) { // TODO(songya): Create Interval Aggregations from internal Distributions. return MutableIntervalView.create(viewDescriptor); } } + + private static final class RecordDoubleValueFunc implements Function { + @Override + public Void apply(DoubleMeasurement arg) { + view.record(tags, arg.getValue()); + return null; + } + + private final StatsContextImpl tags; + private final MutableView view; + + private RecordDoubleValueFunc(StatsContextImpl tags, MutableView view) { + this.tags = tags; + this.view = view; + } + } + + private static final class RecordLongValueFunc implements Function { + @Override + public Void apply(LongMeasurement arg) { + // TODO: determine if we want to support LongMeasure in v0.1 + throw new UnsupportedOperationException("Long measurements not supported."); + } + } } diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java b/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java index 59f4473b1a..155e91c4c3 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java @@ -38,7 +38,7 @@ public Builder builder() { } @Override - public StatsContextImpl record(MeasurementMap stats) { + public StatsContextImpl record(MeasureMap stats) { statsRecorder.record(this, stats); return this; } diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java index 7197826d25..cf0b6f6ad3 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java @@ -53,17 +53,17 @@ View getView(ViewDescriptor.Name viewName) { } } - void record(StatsContextImpl tags, MeasurementMap measurementValues) { + void record(StatsContextImpl tags, MeasureMap measurementValues) { queue.enqueue(new StatsEvent(this, tags, measurementValues)); } // An EventQueue entry that records the stats from one call to StatsManager.record(...). private static final class StatsEvent implements EventQueue.Entry { private final StatsContextImpl tags; - private final MeasurementMap stats; + private final MeasureMap stats; private final StatsManager viewManager; - StatsEvent(StatsManager viewManager, StatsContextImpl tags, MeasurementMap stats) { + StatsEvent(StatsManager viewManager, StatsContextImpl tags, MeasureMap stats) { this.viewManager = viewManager; this.tags = tags; this.stats = stats; diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java b/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java index 796f0b2367..3eca8b3926 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java @@ -22,7 +22,7 @@ final class StatsRecorderImpl extends StatsRecorder { } @Override - void record(StatsContext tags, MeasurementMap measurementValues) { + void record(StatsContext tags, MeasureMap measurementValues) { // TODO(sebright): Replace StatsContext with TagContext, and then this cast won't be necessary. statsManager.record((StatsContextImpl) tags, measurementValues); } diff --git a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java index 2d691e7fde..8f0461454c 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java @@ -49,8 +49,7 @@ public class MeasureToViewMapTest { @Test public void testRegisterAndGetDistributionView() { - MeasureToViewMap measureToViewMap = - new MeasureToViewMap(); + MeasureToViewMap measureToViewMap = new MeasureToViewMap(); TestClock clock = TestClock.create(Timestamp.create(10, 20)); measureToViewMap.registerView(VIEW_DESCRIPTOR, clock); clock.setTime(Timestamp.create(30, 40)); diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index 96b9ed3667..d6bb9f7472 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -21,6 +21,8 @@ import io.opencensus.common.Function; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.internal.VarInt; +import io.opencensus.stats.Measure.DoubleMeasure; +import io.opencensus.stats.Measure.LongMeasure; import io.opencensus.stats.View.DistributionView; import io.opencensus.stats.View.IntervalView; import io.opencensus.testing.common.TestClock; @@ -32,13 +34,21 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link StatsContext}. */ +/** + * Tests for {@link StatsContext}. + */ @RunWith(JUnit4.class) public class StatsContextTest { + + @Rule + public final ExpectedException thrown = ExpectedException.none(); + private static final double TOLERANCE = 1e-6; private final StatsComponentImplBase statsComponent = @@ -97,19 +107,19 @@ public void testWithComposed() { StatsContext context4 = context3.with(K3, V30, K4, V4); assertThat( - defaultStatsContext - .builder() - .set(K1, V100) - .set(K2, V20) - .set(K3, V30) - .set(K4, V4) - .build()) + defaultStatsContext + .builder() + .set(K1, V100) + .set(K2, V20) + .set(K3, V30) + .set(K4, V4) + .build()) .isEqualTo(context4); } - // The main tests for stats recording are in StatsManagerImplTest. + // The main tests for stats recording are in ViewManagerImplTest. @Test - public void testRecord() { + public void testRecordDouble() { viewManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); View beforeView = viewManager.getView( @@ -132,8 +142,9 @@ public Void apply(IntervalView view) { StatsContext context = defaultStatsContext.with( RpcMeasurementConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); - MeasurementMap measurements = - MeasurementMap.of(RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1); + MeasureMap measurements = + MeasureMap.builder() + .set((DoubleMeasure) RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); context.record(measurements); View afterView = viewManager.getView( @@ -162,6 +173,16 @@ public Void apply(IntervalView view) { }); } + @Test + public void testRecordLong() { + LongMeasure measure = LongMeasure.create("long measure", "description", "1"); + viewManager.registerView(ViewDescriptor.DistributionViewDescriptor + .create("name", "description", measure, DistributionAggregationDescriptor.create(), + Arrays.asList(K1))); + thrown.expect(UnsupportedOperationException.class); + defaultStatsContext.with(K1, V1).record(MeasureMap.builder().set(measure,1L).build()); + } + @Test public void testSerializeDefault() throws Exception { testSerialize(); diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index f784d98c8c..2fc23690b4 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -19,6 +19,7 @@ import io.opencensus.common.Duration; import io.opencensus.common.Timestamp; import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.stats.Measure.DoubleMeasure; import io.opencensus.stats.View.DistributionView; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; @@ -36,7 +37,8 @@ @RunWith(JUnit4.class) public class ViewManagerImplTest { - @Rule public final ExpectedException thrown = ExpectedException.none(); + @Rule + public final ExpectedException thrown = ExpectedException.none(); private static final TagKey KEY = TagKey.create("KEY"); @@ -51,7 +53,7 @@ public class ViewManagerImplTest { private static final String MEASUREMENT_DESCRIPTION = "measurement description"; - private static final Measure MEASUREMENT_DESCRIPTOR = + private static final DoubleMeasure MEASUREMENT_DESCRIPTOR = Measure.DoubleMeasure.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); private static final ViewDescriptor.Name VIEW_NAME = ViewDescriptor.Name.create("my view"); @@ -161,7 +163,7 @@ public void testRecord() { viewManager.registerView(viewDescr); StatsContextImpl tags = createContext(factory, KEY, VALUE); for (double val : Arrays.asList(10.0, 20.0, 30.0, 40.0)) { - statsRecorder.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, val)); + statsRecorder.record(tags, MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, val).build()); } clock.setTime(Timestamp.create(3, 4)); DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); @@ -188,7 +190,7 @@ public void getViewDoesNotClearStats() { clock.setTime(Timestamp.create(10, 0)); viewManager.registerView(viewDescr); StatsContextImpl tags = createContext(factory, KEY, VALUE); - statsRecorder.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.1)); + statsRecorder.record(tags, MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 0.1).build()); clock.setTime(Timestamp.create(11, 0)); DistributionView view1 = (DistributionView) viewManager.getView(VIEW_NAME); assertThat(view1.getStart()).isEqualTo(Timestamp.create(10, 0)); @@ -198,7 +200,7 @@ public void getViewDoesNotClearStats() { Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(0.1)))); - statsRecorder.record(tags, MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 0.2)); + statsRecorder.record(tags, MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 0.2).build()); clock.setTime(Timestamp.create(12, 0)); DistributionView view2 = (DistributionView) viewManager.getView(VIEW_NAME); @@ -224,11 +226,14 @@ public void testRecordMultipleTagValues() { DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); statsRecorder.record( - createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); + createContext(factory, KEY, VALUE), + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 10.0).build()); statsRecorder.record( - createContext(factory, KEY, VALUE_2), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 30.0)); + createContext(factory, KEY, VALUE_2), + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 30.0).build()); statsRecorder.record( - createContext(factory, KEY, VALUE_2), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 50.0)); + createContext(factory, KEY, VALUE_2), + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 50.0).build()); DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( view.getDistributionAggregations(), @@ -246,7 +251,8 @@ public void testRecordMultipleTagValues() { @Test public void allowRecordingWithoutRegisteringMatchingView() { statsRecorder.record( - createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10)); + createContext(factory, KEY, VALUE), + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 10).build()); } @Test @@ -258,7 +264,8 @@ public void testRecordWithEmptyStatsContext() { DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); // DEFAULT doesn't have tags, but the view has tag key "KEY". - statsRecorder.record(factory.getDefault(), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); + statsRecorder.record(factory.getDefault(), + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 10.0).build()); DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( view.getDistributionAggregations(), @@ -280,9 +287,10 @@ public void testRecordWithNonExistentMeasurementDescriptor() { Measure.DoubleMeasure.create(MEASUREMENT_NAME, "measurement", MEASUREMENT_UNIT), DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); - Measure measure2 = + DoubleMeasure measure2 = Measure.DoubleMeasure.create(MEASUREMENT_NAME_2, "measurement", MEASUREMENT_UNIT); - statsRecorder.record(createContext(factory, KEY, VALUE), MeasurementMap.of(measure2, 10.0)); + statsRecorder.record(createContext(factory, KEY, VALUE), + MeasureMap.builder().set(measure2, 10.0).build()); DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertThat(view.getDistributionAggregations()).isEmpty(); } @@ -297,10 +305,10 @@ public void testRecordWithTagsThatDoNotMatchView() { Arrays.asList(KEY))); statsRecorder.record( createContext(factory, TagKey.create("wrong key"), VALUE), - MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 10.0)); + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 10.0).build()); statsRecorder.record( createContext(factory, TagKey.create("another wrong key"), VALUE), - MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 50.0)); + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 50.0).build()); DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( view.getDistributionAggregations(), @@ -326,16 +334,16 @@ public void testViewWithMultipleTagKeys() { Arrays.asList(key1, key2))); statsRecorder.record( createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), - MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 1.1)); + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 1.1).build()); statsRecorder.record( createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v20")), - MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 2.2)); + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 2.2).build()); statsRecorder.record( createContext(factory, key1, TagValue.create("v2"), key2, TagValue.create("v10")), - MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 3.3)); + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 3.3).build()); statsRecorder.record( createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), - MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 4.4)); + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 4.4).build()); DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( view.getDistributionAggregations(), @@ -379,7 +387,8 @@ public void testMultipleViewsSameMeasure() { clock.setTime(Timestamp.create(2, 2)); viewManager.registerView(viewDescr2); statsRecorder.record( - createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 5.0)); + createContext(factory, KEY, VALUE), + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 5.0).build()); List expectedAggs = Arrays.asList( StatsTestUtil.createDistributionAggregation( @@ -398,9 +407,9 @@ public void testMultipleViewsSameMeasure() { @Test public void testMultipleViewsDifferentMeasures() { - Measure measureDescr1 = + DoubleMeasure measureDescr1 = Measure.DoubleMeasure.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); - Measure measureDescr2 = + DoubleMeasure measureDescr2 = Measure.DoubleMeasure.create(MEASUREMENT_NAME_2, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); ViewDescriptor viewDescr1 = createDistributionViewDescriptor( @@ -414,7 +423,7 @@ public void testMultipleViewsDifferentMeasures() { viewManager.registerView(viewDescr2); statsRecorder.record( createContext(factory, KEY, VALUE), - MeasurementMap.of(measureDescr1, 1.1, measureDescr2, 2.2)); + MeasureMap.builder().set(measureDescr1, 1.1).set(measureDescr2, 2.2).build()); clock.setTime(Timestamp.create(3, 0)); DistributionView view1 = (DistributionView) viewManager.getView(VIEW_NAME); clock.setTime(Timestamp.create(4, 0)); @@ -444,7 +453,8 @@ public void testGetDistributionViewWithoutBucketBoundaries() { clock.setTime(Timestamp.create(1, 0)); viewManager.registerView(viewDescr); statsRecorder.record( - createContext(factory, KEY, VALUE), MeasurementMap.of(MEASUREMENT_DESCRIPTOR, 1.1)); + createContext(factory, KEY, VALUE), + MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 1.1).build()); clock.setTime(Timestamp.create(3, 0)); DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); assertThat(view.getStart()).isEqualTo(Timestamp.create(1, 0)); diff --git a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java index d0107efbf6..c92cc1706d 100644 --- a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java +++ b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java @@ -14,16 +14,19 @@ package io.opencensus.examples.stats; import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.stats.Measure; -import io.opencensus.stats.MeasurementMap; +import io.opencensus.stats.Measure.DoubleMeasure; +import io.opencensus.stats.MeasureMap; import io.opencensus.stats.Stats; import io.opencensus.stats.StatsContext; import io.opencensus.stats.StatsContextFactory; import io.opencensus.stats.TagKey; import io.opencensus.stats.TagValue; -/** Simple program that uses Stats contexts. */ +/** + * Simple program that uses Stats contexts. + */ public class StatsRunner { + private static final TagKey K1 = TagKey.create("k1"); private static final TagKey K2 = TagKey.create("k2"); private static final TagKey K3 = TagKey.create("k3"); @@ -35,8 +38,10 @@ public class StatsRunner { private static final TagValue V4 = TagValue.create("v4"); private static final String UNIT = "1"; - private static final Measure M1 = Measure.DoubleMeasure.create("m1", "1st test metric", UNIT); - private static final Measure M2 = Measure.DoubleMeasure.create("m2", "2nd test metric", UNIT); + private static final DoubleMeasure M1 = + DoubleMeasure.create("m1", "1st test metric", UNIT); + private static final DoubleMeasure M2 = + DoubleMeasure.create("m2", "2nd test metric", UNIT); private static final StatsContextFactory factory = Stats.getStatsContextFactory(); private static final StatsContext DEFAULT = factory.getDefault(); @@ -61,7 +66,8 @@ public static void main(String[] args) { System.out.println( " Current == Default + tags1 + tags2: " + factory.getCurrentStatsContext().equals(tags2)); - factory.getCurrentStatsContext().record(MeasurementMap.of(M1, 0.2, M2, 0.4)); + factory.getCurrentStatsContext().record( + MeasureMap.builder().set(M1, 0.2).set(M2, 0.4).build()); } } System.out.println("Current == Default: " + factory.getCurrentStatsContext().equals(DEFAULT)); From e21fe9dab5847f91a1bf2a7d2dbac239636e4741 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 6 Jul 2017 11:28:04 -0700 Subject: [PATCH 0230/1581] Move ContextUtils to io.opencensus.trace.unsafe package. --- api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java | 1 + api/src/main/java/io/opencensus/trace/Tracer.java | 1 + .../java/io/opencensus/trace/{ => unsafe}/ContextUtils.java | 4 +++- api/src/test/java/io/opencensus/trace/ContextUtilsTest.java | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) rename api/src/main/java/io/opencensus/trace/{ => unsafe}/ContextUtils.java (96%) diff --git a/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java b/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java index 965c4d9864..93ff84548b 100644 --- a/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java +++ b/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java @@ -14,6 +14,7 @@ package io.opencensus.trace; import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.unsafe.ContextUtils; /** * Defines a scope of code where the given {@link Span} is in the current context. The scope is diff --git a/api/src/main/java/io/opencensus/trace/Tracer.java b/api/src/main/java/io/opencensus/trace/Tracer.java index 97cd0998a6..98e63672cf 100644 --- a/api/src/main/java/io/opencensus/trace/Tracer.java +++ b/api/src/main/java/io/opencensus/trace/Tracer.java @@ -17,6 +17,7 @@ import io.opencensus.common.NonThrowingCloseable; import io.opencensus.trace.SpanBuilder.NoopSpanBuilder; +import io.opencensus.trace.unsafe.ContextUtils; import javax.annotation.Nullable; /** diff --git a/api/src/main/java/io/opencensus/trace/ContextUtils.java b/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java similarity index 96% rename from api/src/main/java/io/opencensus/trace/ContextUtils.java rename to api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java index c5331563ae..9d885886dc 100644 --- a/api/src/main/java/io/opencensus/trace/ContextUtils.java +++ b/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java @@ -11,10 +11,12 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.trace.unsafe; import io.grpc.Context; import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.Span; +import io.opencensus.trace.Tracer; /** * Util methods/functionality to interact with the {@link io.grpc.Context}. diff --git a/api/src/test/java/io/opencensus/trace/ContextUtilsTest.java b/api/src/test/java/io/opencensus/trace/ContextUtilsTest.java index e4513d740d..fff71d07d9 100644 --- a/api/src/test/java/io/opencensus/trace/ContextUtilsTest.java +++ b/api/src/test/java/io/opencensus/trace/ContextUtilsTest.java @@ -17,6 +17,7 @@ import io.grpc.Context; import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.unsafe.ContextUtils; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; From 67582d5e4d7b693fe4dae3c13607eb017d534201 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Thu, 6 Jul 2017 12:06:04 -0700 Subject: [PATCH 0231/1581] Rename Measure and Measurement subclasses. (#414) --- .../java/io/opencensus/stats/Measure.java | 30 +++++----- .../java/io/opencensus/stats/MeasureMap.java | 24 ++++---- .../java/io/opencensus/stats/Measurement.java | 38 ++++++------ .../stats/RpcMeasurementConstants.java | 44 +++++++------- .../io/opencensus/stats/MeasureMapTest.java | 59 ++++++++++--------- .../java/io/opencensus/stats/MeasureTest.java | 32 +++++----- .../opencensus/stats/ViewDescriptorTest.java | 2 +- .../java/io/opencensus/stats/ViewTest.java | 2 +- .../io/opencensus/stats/MeasureToViewMap.java | 12 ++-- .../stats/MeasureToViewMapTest.java | 2 +- .../io/opencensus/stats/StatsContextTest.java | 8 +-- .../opencensus/stats/ViewManagerImplTest.java | 20 +++---- .../examples/stats/StatsRunner.java | 10 ++-- 13 files changed, 141 insertions(+), 142 deletions(-) diff --git a/core/src/main/java/io/opencensus/stats/Measure.java b/core/src/main/java/io/opencensus/stats/Measure.java index bb8c78b692..d4b8abc9d1 100644 --- a/core/src/main/java/io/opencensus/stats/Measure.java +++ b/core/src/main/java/io/opencensus/stats/Measure.java @@ -27,8 +27,8 @@ public abstract class Measure { * Applies the given match function to the underlying data type. */ public abstract T match( - Function p0, - Function p1); + Function p0, + Function p1); /** * Name of measure, as a {@code String}. @@ -59,22 +59,22 @@ private Measure() { @Immutable @AutoValue - public abstract static class DoubleMeasure extends Measure { + public abstract static class MeasureDouble extends Measure { - DoubleMeasure() { + MeasureDouble() { } /** - * Constructs a new {@link DoubleMeasure}. + * Constructs a new {@link MeasureDouble}. */ - public static DoubleMeasure create(String name, String description, String unit) { + public static MeasureDouble create(String name, String description, String unit) { // TODO(dpo): ensure that measure names are unique, and consider if there should be any // restricitons on name (e.g. size, characters). - return new AutoValue_Measure_DoubleMeasure(name, description, unit); + return new AutoValue_Measure_MeasureDouble(name, description, unit); } @Override - public T match(Function p0, Function p1) { + public T match(Function p0, Function p1) { return p0.apply(this); } @@ -90,23 +90,23 @@ public T match(Function p0, Function T match(Function p0, Function p1) { + public T match(Function p0, Function p1) { return p1.apply(this); } diff --git a/core/src/main/java/io/opencensus/stats/MeasureMap.java b/core/src/main/java/io/opencensus/stats/MeasureMap.java index 5c9bb61b6f..a84f4a48fc 100644 --- a/core/src/main/java/io/opencensus/stats/MeasureMap.java +++ b/core/src/main/java/io/opencensus/stats/MeasureMap.java @@ -13,8 +13,8 @@ package io.opencensus.stats; -import io.opencensus.stats.Measure.DoubleMeasure; -import io.opencensus.stats.Measure.LongMeasure; +import io.opencensus.stats.Measure.MeasureDouble; +import io.opencensus.stats.Measure.MeasureLong; import java.util.ArrayList; import java.util.Iterator; import java.util.NoSuchElementException; @@ -50,28 +50,28 @@ private MeasureMap(ArrayList measurements) { */ public static class Builder { /** - * Associates the {@link DoubleMeasure} with the given value. Subsequent updates to the - * same {@link DoubleMeasure} are ignored. + * Associates the {@link MeasureDouble} with the given value. Subsequent updates to the + * same {@link MeasureDouble} are ignored. * - * @param measure the {@link DoubleMeasure} + * @param measure the {@link MeasureDouble} * @param value the value to be associated with {@code measure} * @return this */ - public Builder set(DoubleMeasure measure, double value) { - measurements.add(Measurement.DoubleMeasurement.create(measure, value)); + public Builder set(MeasureDouble measure, double value) { + measurements.add(Measurement.MeasurementDouble.create(measure, value)); return this; } /** - * Associates the {@link LongMeasure} with the given value. Subsequent updates to the - * same {@link LongMeasure} are ignored. + * Associates the {@link MeasureLong} with the given value. Subsequent updates to the + * same {@link MeasureLong} are ignored. * - * @param measure the {@link LongMeasure} + * @param measure the {@link MeasureLong} * @param value the value to be associated with {@code measure} * @return this */ - public Builder set(LongMeasure measure, long value) { - measurements.add(Measurement.LongMeasurement.create(measure, value)); + public Builder set(MeasureLong measure, long value) { + measurements.add(Measurement.MeasurementLong.create(measure, value)); return this; } diff --git a/core/src/main/java/io/opencensus/stats/Measurement.java b/core/src/main/java/io/opencensus/stats/Measurement.java index eeaaa0a55e..22124636ca 100644 --- a/core/src/main/java/io/opencensus/stats/Measurement.java +++ b/core/src/main/java/io/opencensus/stats/Measurement.java @@ -15,8 +15,8 @@ import com.google.auto.value.AutoValue; import io.opencensus.common.Function; -import io.opencensus.stats.Measure.DoubleMeasure; -import io.opencensus.stats.Measure.LongMeasure; +import io.opencensus.stats.Measure.MeasureDouble; +import io.opencensus.stats.Measure.MeasureLong; import javax.annotation.concurrent.Immutable; /** Immutable representation of a Measurement. */ @@ -27,7 +27,7 @@ public abstract class Measurement { * Applies the given match function to the underlying data type. */ public abstract T match( - Function p0, Function p1); + Function p0, Function p1); /** * Extracts the measured {@link Measure}. @@ -40,52 +40,48 @@ private Measurement() { @Immutable @AutoValue - public abstract static class DoubleMeasurement extends Measurement { - - DoubleMeasurement() { - } + public abstract static class MeasurementDouble extends Measurement { + MeasurementDouble() {} /** - * Constructs a new {@link DoubleMeasurement}. + * Constructs a new {@link MeasurementDouble}. */ - public static DoubleMeasurement create(DoubleMeasure measure, double value) { - return new AutoValue_Measurement_DoubleMeasurement(measure, value); + public static MeasurementDouble create(MeasureDouble measure, double value) { + return new AutoValue_Measurement_MeasurementDouble(measure, value); } @Override - public abstract DoubleMeasure getMeasure(); + public abstract MeasureDouble getMeasure(); public abstract Double getValue(); @Override public T match( - Function p0, Function p1) { + Function p0, Function p1) { return p0.apply(this); } } @Immutable @AutoValue - public abstract static class LongMeasurement extends Measurement { - - LongMeasurement() { - } + public abstract static class MeasurementLong extends Measurement { + MeasurementLong() {} /** - * Constructs a new {@link LongMeasurement}. + * Constructs a new {@link MeasurementLong}. */ - public static LongMeasurement create(LongMeasure measure, long value) { - return new AutoValue_Measurement_LongMeasurement(measure, value); + public static MeasurementLong create(MeasureLong measure, long value) { + return new AutoValue_Measurement_MeasurementLong(measure, value); } @Override - public abstract LongMeasure getMeasure(); + public abstract MeasureLong getMeasure(); public abstract Long getValue(); @Override public T match( - Function p0, Function p1) { + Function p0, Function p1) { return p1.apply(this); } } diff --git a/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java b/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java index 415529a161..34205d91fe 100644 --- a/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java @@ -31,57 +31,57 @@ public final class RpcMeasurementConstants { // RPC client Measures. public static final Measure RPC_CLIENT_ERROR_COUNT = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/client/error_count", "RPC Errors", COUNT); public static final Measure RPC_CLIENT_REQUEST_BYTES = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/client/request_bytes", "Request bytes", BYTE); public static final Measure RPC_CLIENT_RESPONSE_BYTES = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/client/response_bytes", "Response bytes", BYTE); public static final Measure RPC_CLIENT_ROUNDTRIP_LATENCY = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/client/roundtrip_latency", "RPC roundtrip latency msec", MILLISECOND); public static final Measure RPC_CLIENT_SERVER_ELAPSED_TIME = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/client/server_elapsed_time", "Server elapsed time in msecs", MILLISECOND); public static final Measure RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/client/uncompressed_request_bytes", "Uncompressed Request bytes", BYTE); public static final Measure RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/client/uncompressed_response_bytes", "Uncompressed Response bytes", BYTE); public static final Measure RPC_CLIENT_STARTED_COUNT = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/client/started_count", "Number of client RPCs (streams) started", COUNT); public static final Measure RPC_CLIENT_FINISHED_COUNT = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/client/finished_count", "Number of client RPCs (streams) finished", COUNT); public static final Measure RPC_CLIENT_REQUEST_COUNT = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/client/request_count", "Number of client RPC request messages", COUNT); public static final Measure RPC_CLIENT_RESPONSE_COUNT = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/client/response_count", "Number of client RPC response messages", COUNT); @@ -89,57 +89,57 @@ public final class RpcMeasurementConstants { // RPC server Measures. public static final Measure RPC_SERVER_ERROR_COUNT = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/server/error_count", "RPC Errors", COUNT); public static final Measure RPC_SERVER_REQUEST_BYTES = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/server/request_bytes", "Request bytes", BYTE); public static final Measure RPC_SERVER_RESPONSE_BYTES = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/server/response_bytes", "Response bytes", BYTE); public static final Measure RPC_SERVER_SERVER_ELAPSED_TIME = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/server/server_elapsed_time", "Server elapsed time in msecs", MILLISECOND); public static final Measure RPC_SERVER_SERVER_LATENCY = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/server/server_latency", "Latency in msecs", MILLISECOND); public static final Measure RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/server/uncompressed_request_bytes", "Uncompressed Request bytes", BYTE); public static final Measure RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/server/uncompressed_response_bytes", "Uncompressed Response bytes", BYTE); public static final Measure RPC_SERVER_STARTED_COUNT = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/server/started_count", "Number of server RPCs (streams) started", COUNT); public static final Measure RPC_SERVER_FINISHED_COUNT = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/server/finished_count", "Number of server RPCs (streams) finished", COUNT); public static final Measure RPC_SERVER_REQUEST_COUNT = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/server/request_count", "Number of server RPC request messages", COUNT); public static final Measure RPC_SERVER_RESPONSE_COUNT = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "grpc.io/server/response_count", "Number of server RPC response messages", COUNT); diff --git a/core/src/test/java/io/opencensus/stats/MeasureMapTest.java b/core/src/test/java/io/opencensus/stats/MeasureMapTest.java index ce71497db6..0dcfc5ecfa 100644 --- a/core/src/test/java/io/opencensus/stats/MeasureMapTest.java +++ b/core/src/test/java/io/opencensus/stats/MeasureMapTest.java @@ -16,8 +16,8 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.Lists; -import io.opencensus.stats.Measure.DoubleMeasure; -import io.opencensus.stats.Measure.LongMeasure; +import io.opencensus.stats.Measure.MeasureDouble; +import io.opencensus.stats.Measure.MeasureLong; import java.util.ArrayList; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,15 +30,15 @@ public class MeasureMapTest { @Test public void testPutDouble() { MeasureMap metrics = MeasureMap.builder().set(M1, 44.4).build(); - assertContains(metrics, Measurement.DoubleMeasurement.create(M1, 44.4)); + assertContains(metrics, Measurement.MeasurementDouble.create(M1, 44.4)); } @Test public void testPutLong() { MeasureMap metrics = MeasureMap.builder().set(M3, 9999L).set(M4, 8888L).build(); assertContains(metrics, - Measurement.LongMeasurement.create(M3, 9999L), - Measurement.LongMeasurement.create(M4, 8888L)); + Measurement.MeasurementLong.create(M3, 9999L), + Measurement.MeasurementLong.create(M4, 8888L)); } @Test @@ -46,10 +46,10 @@ public void testCombination() { MeasureMap metrics = MeasureMap.builder().set(M1, 44.4).set(M2, 66.6).set(M3, 9999L).set(M4, 8888L).build(); assertContains(metrics, - Measurement.DoubleMeasurement.create(M1, 44.4), - Measurement.DoubleMeasurement.create(M2, 66.6), - Measurement.LongMeasurement.create(M3, 9999L), - Measurement.LongMeasurement.create(M4, 8888L)); + Measurement.MeasurementDouble.create(M1, 44.4), + Measurement.MeasurementDouble.create(M2, 66.6), + Measurement.MeasurementLong.create(M3, 9999L), + Measurement.MeasurementLong.create(M4, 8888L)); } @Test @@ -64,24 +64,27 @@ public void testBuilder() { MeasureMap.Builder builder = MeasureMap.builder(); for (int i = 1; i <= 10; i++) { expected - .add(Measurement.DoubleMeasurement.create(makeSimpleDoubleMeasure("m" + i), i * 11.1)); - builder.set(makeSimpleDoubleMeasure("m" + i), i * 11.1); + .add(Measurement.MeasurementDouble.create(makeSimpleMeasureDouble("m" + i), i * 11.1)); + builder.set(makeSimpleMeasureDouble("m" + i), i * 11.1); assertContains(builder.build(), expected.toArray(new Measurement[i])); } } @Test - public void testDuplicateDoubleMeasures() { + public void testDuplicateMeasureDoubles() { assertContains(MeasureMap.builder().set(M1, 1.0).set(M1, 2.0).build(), MEASUREMENT_1); - assertContains(MeasureMap.builder().set(M1, 1.0).set(M1, 2.0).set(M1, 3.0).build(), MEASUREMENT_1); - assertContains(MeasureMap.builder().set(M1, 1.0).set(M2, 2.0).set(M1, 3.0).build(), MEASUREMENT_1, + assertContains(MeasureMap.builder().set(M1, 1.0).set(M1, 2.0).set(M1, 3.0).build(), + MEASUREMENT_1); + assertContains(MeasureMap.builder().set(M1, 1.0).set(M2, 2.0).set(M1, 3.0).build(), + MEASUREMENT_1, MEASUREMENT_2); - assertContains(MeasureMap.builder().set(M1, 1.0).set(M1, 2.0).set(M2, 2.0).build(), MEASUREMENT_1, + assertContains(MeasureMap.builder().set(M1, 1.0).set(M1, 2.0).set(M2, 2.0).build(), + MEASUREMENT_1, MEASUREMENT_2); } @Test - public void testDuplicateLongMeasures() { + public void testDuplicateMeasureLongs() { assertContains(MeasureMap.builder().set(M3, 100L).set(M3, 100L).build(), MEASUREMENT_3); assertContains(MeasureMap.builder().set(M3, 100L).set(M3, 200L).set(M3, 300L).build(), MEASUREMENT_3); @@ -99,22 +102,22 @@ public void testDuplicateMeasures() { MEASUREMENT_2, MEASUREMENT_3); } - private static final DoubleMeasure M1 = makeSimpleDoubleMeasure("m1"); - private static final DoubleMeasure M2 = makeSimpleDoubleMeasure("m2"); - private static final LongMeasure M3 = makeSimpleLongMeasure("m3"); - private static final LongMeasure M4 = makeSimpleLongMeasure("m4"); + private static final MeasureDouble M1 = makeSimpleMeasureDouble("m1"); + private static final MeasureDouble M2 = makeSimpleMeasureDouble("m2"); + private static final MeasureLong M3 = makeSimpleMeasureLong("m3"); + private static final MeasureLong M4 = makeSimpleMeasureLong("m4"); - private static final Measurement MEASUREMENT_1 = Measurement.DoubleMeasurement.create(M1, 1.0); - private static final Measurement MEASUREMENT_2 = Measurement.DoubleMeasurement.create(M2, 2.0); - private static final Measurement MEASUREMENT_3 = Measurement.LongMeasurement.create(M3, 100L); - private static final Measurement MEASUREMENT_4 = Measurement.LongMeasurement.create(M4, 200L); + private static final Measurement MEASUREMENT_1 = Measurement.MeasurementDouble.create(M1, 1.0); + private static final Measurement MEASUREMENT_2 = Measurement.MeasurementDouble.create(M2, 2.0); + private static final Measurement MEASUREMENT_3 = Measurement.MeasurementLong.create(M3, 100L); + private static final Measurement MEASUREMENT_4 = Measurement.MeasurementLong.create(M4, 200L); - private static DoubleMeasure makeSimpleDoubleMeasure(String measure) { - return Measure.DoubleMeasure.create(measure, measure + " description", "1"); + private static MeasureDouble makeSimpleMeasureDouble(String measure) { + return Measure.MeasureDouble.create(measure, measure + " description", "1"); } - private static LongMeasure makeSimpleLongMeasure(String measure) { - return Measure.LongMeasure.create(measure, measure + " description", "1"); + private static MeasureLong makeSimpleMeasureLong(String measure) { + return Measure.MeasureLong.create(measure, measure + " description", "1"); } private static void assertContains(MeasureMap metrics, Measurement... measurements) { diff --git a/core/src/test/java/io/opencensus/stats/MeasureTest.java b/core/src/test/java/io/opencensus/stats/MeasureTest.java index a5774c87cc..e3b35608d4 100644 --- a/core/src/test/java/io/opencensus/stats/MeasureTest.java +++ b/core/src/test/java/io/opencensus/stats/MeasureTest.java @@ -49,8 +49,8 @@ public void testNameBadChar() { } @Test - public void testDoubleMeasureComponents() { - Measure measurement = Measure.DoubleMeasure.create( + public void testMeasureDoubleComponents() { + Measure measurement = Measure.MeasureDouble.create( "Foo", "The description of Foo", "Mbit/s"); @@ -60,8 +60,8 @@ public void testDoubleMeasureComponents() { } @Test - public void testLongMeasureComponents() { - Measure measurement = Measure.LongMeasure.create( + public void testMeasureLongComponents() { + Measure measurement = Measure.MeasureLong.create( "Bar", "The description of Bar", "1"); @@ -71,19 +71,19 @@ public void testLongMeasureComponents() { } @Test - public void testDoubleMeasureEquals() { + public void testMeasureDoubleEquals() { new EqualsTester() .addEqualityGroup( - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "name", "description", "bit/s"), - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "name", "description", "bit/s")) .addEqualityGroup( - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "name", "description 2", "bit/s")) @@ -91,19 +91,19 @@ public void testDoubleMeasureEquals() { } @Test - public void testLongMeasureEquals() { + public void testMeasureLongEquals() { new EqualsTester() .addEqualityGroup( - Measure.LongMeasure.create( + Measure.MeasureLong.create( "name", "description", "bit/s"), - Measure.LongMeasure.create( + Measure.MeasureLong.create( "name", "description", "bit/s")) .addEqualityGroup( - Measure.LongMeasure.create( + Measure.MeasureLong.create( "name", "description 2", "bit/s")) @@ -111,12 +111,12 @@ public void testLongMeasureEquals() { } @Test - public void testDoubleMeasureIsNotEqualToLongMeasure() { - assertThat(Measure.DoubleMeasure.create("name", "description", "bit/s")) - .isNotEqualTo(Measure.LongMeasure.create("name", "description", "bit/s")); + public void testMeasureDoubleIsNotEqualToMeasureLong() { + assertThat(Measure.MeasureDouble.create("name", "description", "bit/s")) + .isNotEqualTo(Measure.MeasureLong.create("name", "description", "bit/s")); } private static final Measure makeSimpleMeasure(String name) { - return Measure.DoubleMeasure.create(name, name + " description", "1"); + return Measure.MeasureDouble.create(name, name + " description", "1"); } } diff --git a/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java b/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java index e8c5cd803b..5abed72382 100644 --- a/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java @@ -173,7 +173,7 @@ public void testViewDescriptorNameEquals() { private final ViewDescriptor.Name name = ViewDescriptor.Name.create("test-view-name"); private final String description = "test-view-name description"; - private final Measure measure = Measure.DoubleMeasure.create( + private final Measure measure = Measure.MeasureDouble.create( "measurement", "measurement description", "1"); diff --git a/core/src/test/java/io/opencensus/stats/ViewTest.java b/core/src/test/java/io/opencensus/stats/ViewTest.java index 6a42c01ac7..6d73d03443 100644 --- a/core/src/test/java/io/opencensus/stats/ViewTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewTest.java @@ -173,7 +173,7 @@ public void testViewEquals() { // description private final String description = "test-view-descriptor description"; // measurement descriptor - private final Measure measure = Measure.DoubleMeasure.create( + private final Measure measure = Measure.MeasureDouble.create( "measurement-descriptor", "measurement-descriptor description", "1"); diff --git a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java index e4d89a91b9..f2a483c6f9 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java +++ b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java @@ -17,8 +17,8 @@ import com.google.common.collect.Multimap; import io.opencensus.common.Clock; import io.opencensus.common.Function; -import io.opencensus.stats.Measurement.DoubleMeasurement; -import io.opencensus.stats.Measurement.LongMeasurement; +import io.opencensus.stats.Measurement.MeasurementDouble; +import io.opencensus.stats.Measurement.MeasurementLong; import io.opencensus.stats.MutableView.MutableDistributionView; import io.opencensus.stats.MutableView.MutableIntervalView; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; @@ -129,9 +129,9 @@ public MutableView apply(IntervalViewDescriptor viewDescriptor) { } } - private static final class RecordDoubleValueFunc implements Function { + private static final class RecordDoubleValueFunc implements Function { @Override - public Void apply(DoubleMeasurement arg) { + public Void apply(MeasurementDouble arg) { view.record(tags, arg.getValue()); return null; } @@ -145,9 +145,9 @@ private RecordDoubleValueFunc(StatsContextImpl tags, MutableView view) { } } - private static final class RecordLongValueFunc implements Function { + private static final class RecordLongValueFunc implements Function { @Override - public Void apply(LongMeasurement arg) { + public Void apply(MeasurementLong arg) { // TODO: determine if we want to support LongMeasure in v0.1 throw new UnsupportedOperationException("Long measurements not supported."); } diff --git a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java index 8f0461454c..89b0b3c411 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java @@ -32,7 +32,7 @@ public class MeasureToViewMapTest { private static final Measure MEASUREMENT_DESCRIPTOR = - Measure.DoubleMeasure.create( + Measure.MeasureDouble.create( "my measurement", "measurement description", "By"); diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index d6bb9f7472..aa85036147 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -21,8 +21,8 @@ import io.opencensus.common.Function; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.internal.VarInt; -import io.opencensus.stats.Measure.DoubleMeasure; -import io.opencensus.stats.Measure.LongMeasure; +import io.opencensus.stats.Measure.MeasureDouble; +import io.opencensus.stats.Measure.MeasureLong; import io.opencensus.stats.View.DistributionView; import io.opencensus.stats.View.IntervalView; import io.opencensus.testing.common.TestClock; @@ -144,7 +144,7 @@ public Void apply(IntervalView view) { RpcMeasurementConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); MeasureMap measurements = MeasureMap.builder() - .set((DoubleMeasure) RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); + .set((MeasureDouble) RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); context.record(measurements); View afterView = viewManager.getView( @@ -175,7 +175,7 @@ public Void apply(IntervalView view) { @Test public void testRecordLong() { - LongMeasure measure = LongMeasure.create("long measure", "description", "1"); + MeasureLong measure = MeasureLong.create("long measure", "description", "1"); viewManager.registerView(ViewDescriptor.DistributionViewDescriptor .create("name", "description", measure, DistributionAggregationDescriptor.create(), Arrays.asList(K1))); diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index 2fc23690b4..955e1f63fd 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -19,7 +19,7 @@ import io.opencensus.common.Duration; import io.opencensus.common.Timestamp; import io.opencensus.internal.SimpleEventQueue; -import io.opencensus.stats.Measure.DoubleMeasure; +import io.opencensus.stats.Measure.MeasureDouble; import io.opencensus.stats.View.DistributionView; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; @@ -53,8 +53,8 @@ public class ViewManagerImplTest { private static final String MEASUREMENT_DESCRIPTION = "measurement description"; - private static final DoubleMeasure MEASUREMENT_DESCRIPTOR = - Measure.DoubleMeasure.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); + private static final MeasureDouble MEASUREMENT_DESCRIPTOR = + Measure.MeasureDouble.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); private static final ViewDescriptor.Name VIEW_NAME = ViewDescriptor.Name.create("my view"); private static final ViewDescriptor.Name VIEW_NAME_2 = ViewDescriptor.Name.create("my view 2"); @@ -284,11 +284,11 @@ public void testRecordWithNonExistentMeasurementDescriptor() { viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, - Measure.DoubleMeasure.create(MEASUREMENT_NAME, "measurement", MEASUREMENT_UNIT), + Measure.MeasureDouble.create(MEASUREMENT_NAME, "measurement", MEASUREMENT_UNIT), DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); - DoubleMeasure measure2 = - Measure.DoubleMeasure.create(MEASUREMENT_NAME_2, "measurement", MEASUREMENT_UNIT); + MeasureDouble measure2 = + Measure.MeasureDouble.create(MEASUREMENT_NAME_2, "measurement", MEASUREMENT_UNIT); statsRecorder.record(createContext(factory, KEY, VALUE), MeasureMap.builder().set(measure2, 10.0).build()); DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); @@ -407,10 +407,10 @@ public void testMultipleViewsSameMeasure() { @Test public void testMultipleViewsDifferentMeasures() { - DoubleMeasure measureDescr1 = - Measure.DoubleMeasure.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); - DoubleMeasure measureDescr2 = - Measure.DoubleMeasure.create(MEASUREMENT_NAME_2, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); + MeasureDouble measureDescr1 = + Measure.MeasureDouble.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); + MeasureDouble measureDescr2 = + Measure.MeasureDouble.create(MEASUREMENT_NAME_2, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); ViewDescriptor viewDescr1 = createDistributionViewDescriptor( VIEW_NAME, measureDescr1, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); diff --git a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java index c92cc1706d..307f254d60 100644 --- a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java +++ b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java @@ -14,7 +14,7 @@ package io.opencensus.examples.stats; import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.stats.Measure.DoubleMeasure; +import io.opencensus.stats.Measure.MeasureDouble; import io.opencensus.stats.MeasureMap; import io.opencensus.stats.Stats; import io.opencensus.stats.StatsContext; @@ -38,10 +38,10 @@ public class StatsRunner { private static final TagValue V4 = TagValue.create("v4"); private static final String UNIT = "1"; - private static final DoubleMeasure M1 = - DoubleMeasure.create("m1", "1st test metric", UNIT); - private static final DoubleMeasure M2 = - DoubleMeasure.create("m2", "2nd test metric", UNIT); + private static final MeasureDouble M1 = + MeasureDouble.create("m1", "1st test metric", UNIT); + private static final MeasureDouble M2 = + MeasureDouble.create("m2", "2nd test metric", UNIT); private static final StatsContextFactory factory = Stats.getStatsContextFactory(); private static final StatsContext DEFAULT = factory.getDefault(); From d31ce61746bdeb5890852de6ba0c8e51ecaef268 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 6 Jul 2017 11:52:58 -0700 Subject: [PATCH 0232/1581] Put CONTEXT_SPAN_KEY in a separate class, to avoid exposing methods in ContextUtils. After this commit, ContextUtils is split into two classes, io.opencensus.trace.unsafe.ContextUtils and io.opencensus.trace.CurrentSpanUtils. ContextUtils has one public member, CONTEXT_SPAN_KEY. CurrentSpanUtils has internal methods for working with the current Span, and it is package-private. --- .../io/opencensus/trace/CurrentSpanUtils.java | 70 +++++++++++++++++++ .../io/opencensus/trace/ScopedSpanHandle.java | 3 +- .../main/java/io/opencensus/trace/Tracer.java | 7 +- .../opencensus/trace/unsafe/ContextUtils.java | 49 +------------ ...ilsTest.java => CurrentSpanUtilsTest.java} | 28 ++++---- 5 files changed, 90 insertions(+), 67 deletions(-) create mode 100644 api/src/main/java/io/opencensus/trace/CurrentSpanUtils.java rename api/src/test/java/io/opencensus/trace/{ContextUtilsTest.java => CurrentSpanUtilsTest.java} (69%) diff --git a/api/src/main/java/io/opencensus/trace/CurrentSpanUtils.java b/api/src/main/java/io/opencensus/trace/CurrentSpanUtils.java new file mode 100644 index 0000000000..884fd636ad --- /dev/null +++ b/api/src/main/java/io/opencensus/trace/CurrentSpanUtils.java @@ -0,0 +1,70 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.trace; + +import io.grpc.Context; +import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.trace.unsafe.ContextUtils; + +/** + * Util methods/functionality to interact with the {@link Span} in the {@link io.grpc.Context}. + */ +final class CurrentSpanUtils { + // No instance of this class. + private CurrentSpanUtils() {} + + /** + * Returns The {@link Span} from the current context. + * + * @return The {@code Span} from the current context. + */ + static Span getCurrentSpan() { + return ContextUtils.CONTEXT_SPAN_KEY.get(Context.current()); + } + + /** + * Enters the scope of code where the given {@link Span} is in the current context, and returns an + * object that represents that scope. The scope is exited when the returned object is closed. + * + *

            Supports try-with-resource idiom. + * + * @param span The {@code Span} to be set to the current context. + * @return An object that defines a scope where the given {@code Span} is set to the current + * context. + */ + static NonThrowingCloseable withSpan(Span span) { + return new WithSpan(span, ContextUtils.CONTEXT_SPAN_KEY); + } + + // Defines an arbitrary scope of code as a traceable operation. Supports try-with-resources idiom. + private static final class WithSpan implements NonThrowingCloseable { + private final Context origContext; + + /** + * Constructs a new {@link WithSpan}. + * + * @param span is the {@code Span} to be added to the current {@code io.grpc.Context}. + * @param contextKey is the {@code Context.Key} used to set/get {@code Span} from the {@code + * Context}. + */ + WithSpan(Span span, Context.Key contextKey) { + origContext = Context.current().withValue(contextKey, span).attach(); + } + + @Override + public void close() { + Context.current().detach(origContext); + } + } +} diff --git a/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java b/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java index 93ff84548b..e2cf1710e9 100644 --- a/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java +++ b/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java @@ -14,7 +14,6 @@ package io.opencensus.trace; import io.opencensus.common.NonThrowingCloseable; -import io.opencensus.trace.unsafe.ContextUtils; /** * Defines a scope of code where the given {@link Span} is in the current context. The scope is @@ -34,7 +33,7 @@ final class ScopedSpanHandle implements NonThrowingCloseable { */ ScopedSpanHandle(Span span) { this.span = span; - this.withSpan = ContextUtils.withSpan(span); + this.withSpan = CurrentSpanUtils.withSpan(span); } /** diff --git a/api/src/main/java/io/opencensus/trace/Tracer.java b/api/src/main/java/io/opencensus/trace/Tracer.java index 98e63672cf..b9f7b67b53 100644 --- a/api/src/main/java/io/opencensus/trace/Tracer.java +++ b/api/src/main/java/io/opencensus/trace/Tracer.java @@ -17,7 +17,6 @@ import io.opencensus.common.NonThrowingCloseable; import io.opencensus.trace.SpanBuilder.NoopSpanBuilder; -import io.opencensus.trace.unsafe.ContextUtils; import javax.annotation.Nullable; /** @@ -89,7 +88,7 @@ static Tracer getNoopTracer() { * from the Context. */ public final Span getCurrentSpan() { - Span currentSpan = ContextUtils.getCurrentSpan(); + Span currentSpan = CurrentSpanUtils.getCurrentSpan(); return currentSpan != null ? currentSpan : BlankSpan.INSTANCE; } @@ -143,7 +142,7 @@ public final Span getCurrentSpan() { * @throws NullPointerException if {@code span} is {@code null}. */ public final NonThrowingCloseable withSpan(Span span) { - return ContextUtils.withSpan(checkNotNull(span, "span")); + return CurrentSpanUtils.withSpan(checkNotNull(span, "span")); } /** @@ -166,7 +165,7 @@ public final NonThrowingCloseable withSpan(Span span) { * @throws NullPointerException if {@code spanName} is {@code null}. */ public final SpanBuilder spanBuilder(String spanName) { - return spanBuilderWithExplicitParent(spanName, ContextUtils.getCurrentSpan()); + return spanBuilderWithExplicitParent(spanName, CurrentSpanUtils.getCurrentSpan()); } /** diff --git a/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java b/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java index 9d885886dc..26ff5c2c43 100644 --- a/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java +++ b/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java @@ -14,7 +14,6 @@ package io.opencensus.trace.unsafe; import io.grpc.Context; -import io.opencensus.common.NonThrowingCloseable; import io.opencensus.trace.Span; import io.opencensus.trace.Tracer; @@ -25,53 +24,9 @@ * usages of the {@link #CONTEXT_SPAN_KEY} directly. */ public final class ContextUtils { - /** The {@link io.grpc.Context.Key} used to interact with {@link io.grpc.Context}. */ - public static final Context.Key CONTEXT_SPAN_KEY = Context.key("instrumentation-trace-key"); - // No instance of this class. private ContextUtils() {} - /** - * Returns The {@link Span} from the current context. - * - * @return The {@code Span} from the current context. - */ - static Span getCurrentSpan() { - return CONTEXT_SPAN_KEY.get(Context.current()); - } - - /** - * Enters the scope of code where the given {@link Span} is in the current context, and returns an - * object that represents that scope. The scope is exited when the returned object is closed. - * - *

            Supports try-with-resource idiom. - * - * @param span The {@code Span} to be set to the current context. - * @return An object that defines a scope where the given {@code Span} is set to the current - * context. - */ - static NonThrowingCloseable withSpan(Span span) { - return new WithSpan(span, CONTEXT_SPAN_KEY); - } - - // Defines an arbitrary scope of code as a traceable operation. Supports try-with-resources idiom. - private static final class WithSpan implements NonThrowingCloseable { - private final Context origContext; - - /** - * Constructs a new {@link WithSpan}. - * - * @param span is the {@code Span} to be added to the current {@code io.grpc.Context}. - * @param contextKey is the {@code Context.Key} used to set/get {@code Span} from the {@code - * Context}. - */ - WithSpan(Span span, Context.Key contextKey) { - origContext = Context.current().withValue(contextKey, span).attach(); - } - - @Override - public void close() { - Context.current().detach(origContext); - } - } + /** The {@link io.grpc.Context.Key} used to interact with {@link io.grpc.Context}. */ + public static final Context.Key CONTEXT_SPAN_KEY = Context.key("instrumentation-trace-key"); } diff --git a/api/src/test/java/io/opencensus/trace/ContextUtilsTest.java b/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java similarity index 69% rename from api/src/test/java/io/opencensus/trace/ContextUtilsTest.java rename to api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java index fff71d07d9..22b351a80d 100644 --- a/api/src/test/java/io/opencensus/trace/ContextUtilsTest.java +++ b/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java @@ -25,9 +25,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -/** Unit tests for {@link ContextUtils}. */ +/** Unit tests for {@link CurrentSpanUtils}. */ @RunWith(JUnit4.class) -public class ContextUtilsTest { +public class CurrentSpanUtilsTest { @Mock private Span span; @Before @@ -37,54 +37,54 @@ public void setUp() { @Test public void getCurrentSpan_WhenNoContext() { - assertThat(ContextUtils.getCurrentSpan()).isNull(); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); } @Test public void getCurrentSpan() { - assertThat(ContextUtils.getCurrentSpan()).isNull(); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); Context origContext = Context.current().withValue(ContextUtils.CONTEXT_SPAN_KEY, span).attach(); // Make sure context is detached even if test fails. try { - assertThat(ContextUtils.getCurrentSpan()).isSameAs(span); + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); } finally { Context.current().detach(origContext); } - assertThat(ContextUtils.getCurrentSpan()).isNull(); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); } @Test public void withSpan() { - assertThat(ContextUtils.getCurrentSpan()).isNull(); - NonThrowingCloseable ws = ContextUtils.withSpan(span); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + NonThrowingCloseable ws = CurrentSpanUtils.withSpan(span); try { - assertThat(ContextUtils.getCurrentSpan()).isSameAs(span); + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); } finally { ws.close(); } - assertThat(ContextUtils.getCurrentSpan()).isNull(); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); ; } @Test public void propagationViaRunnable() { Runnable runnable = null; - NonThrowingCloseable ws = ContextUtils.withSpan(span); + NonThrowingCloseable ws = CurrentSpanUtils.withSpan(span); try { - assertThat(ContextUtils.getCurrentSpan()).isSameAs(span); + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); runnable = Context.current() .wrap( new Runnable() { @Override public void run() { - assertThat(ContextUtils.getCurrentSpan()).isSameAs(span); + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); } }); } finally { ws.close(); } - assertThat(ContextUtils.getCurrentSpan()).isNotSameAs(span); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNotSameAs(span); // When we run the runnable we will have the span in the current Context. runnable.run(); } From 17e9f4e174391f68d3ca05f39ef48437903f9d14 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 6 Jul 2017 12:16:53 -0700 Subject: [PATCH 0233/1581] Avoid importing Tracer for Javadoc reference. --- .../main/java/io/opencensus/trace/unsafe/ContextUtils.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java b/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java index 26ff5c2c43..c8bf0eb4d4 100644 --- a/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java +++ b/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java @@ -15,13 +15,12 @@ import io.grpc.Context; import io.opencensus.trace.Span; -import io.opencensus.trace.Tracer; /** * Util methods/functionality to interact with the {@link io.grpc.Context}. * - *

            Users must interact with the current Context via the public APIs in {@link Tracer} and avoid - * usages of the {@link #CONTEXT_SPAN_KEY} directly. + *

            Users must interact with the current Context via the public APIs in {@link + * io.opencensus.trace.Tracer} and avoid usages of the {@link #CONTEXT_SPAN_KEY} directly. */ public final class ContextUtils { // No instance of this class. From 83bc424dcc72ea3dc3f1641233d1eaeed923fe2b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 6 Jul 2017 12:17:06 -0700 Subject: [PATCH 0234/1581] Delete extra semicolon. --- api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java b/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java index 22b351a80d..9d82bd2c3c 100644 --- a/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java +++ b/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java @@ -63,7 +63,6 @@ public void withSpan() { ws.close(); } assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); - ; } @Test From 1b3a5d60a50914f9574f4dd12a7dd7a187e932d1 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 6 Jul 2017 12:26:21 -0700 Subject: [PATCH 0235/1581] Rename trace io.grpc.Context key to opencensus-trace-span-key. --- api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java b/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java index c8bf0eb4d4..b18f663f93 100644 --- a/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java +++ b/api/src/main/java/io/opencensus/trace/unsafe/ContextUtils.java @@ -27,5 +27,5 @@ public final class ContextUtils { private ContextUtils() {} /** The {@link io.grpc.Context.Key} used to interact with {@link io.grpc.Context}. */ - public static final Context.Key CONTEXT_SPAN_KEY = Context.key("instrumentation-trace-key"); + public static final Context.Key CONTEXT_SPAN_KEY = Context.key("opencensus-trace-span-key"); } From 4a9d0c860324034f0b8e0858df1c28d85b46d1a7 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Thu, 6 Jul 2017 12:51:00 -0700 Subject: [PATCH 0236/1581] Rename RpcMeasureConstants, declare constants as MeasureDouble. (#415) --- ...onstants.java => RpcMeasureConstants.java} | 50 ++++++++------- .../io/opencensus/stats/RpcViewConstants.java | 50 +++++++-------- .../stats/RpcMeasureConstantsTest.java | 64 +++++++++++++++++++ .../stats/RpcMeasurementConstantsTest.java | 64 ------------------- .../io/opencensus/stats/StatsContextTest.java | 7 +- 5 files changed, 118 insertions(+), 117 deletions(-) rename core/src/main/java/io/opencensus/stats/{RpcMeasurementConstants.java => RpcMeasureConstants.java} (73%) create mode 100644 core/src/test/java/io/opencensus/stats/RpcMeasureConstantsTest.java delete mode 100644 core/src/test/java/io/opencensus/stats/RpcMeasurementConstantsTest.java diff --git a/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java b/core/src/main/java/io/opencensus/stats/RpcMeasureConstants.java similarity index 73% rename from core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java rename to core/src/main/java/io/opencensus/stats/RpcMeasureConstants.java index 34205d91fe..77a42e537b 100644 --- a/core/src/main/java/io/opencensus/stats/RpcMeasurementConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcMeasureConstants.java @@ -13,11 +13,13 @@ package io.opencensus.stats; +import io.opencensus.stats.Measure.MeasureDouble; + /** * Constants for collecting rpc stats. */ // TODO(songya): change *_COUNT constants to LongMeasure if it's supported in v0.1. -public final class RpcMeasurementConstants { +public final class RpcMeasureConstants { // Rpc tag keys. public static final TagKey RPC_STATUS = TagKey.create("canonical_status"); @@ -30,57 +32,57 @@ public final class RpcMeasurementConstants { private static final String MILLISECOND = "ms"; // RPC client Measures. - public static final Measure RPC_CLIENT_ERROR_COUNT = + public static final MeasureDouble RPC_CLIENT_ERROR_COUNT = Measure.MeasureDouble.create( "grpc.io/client/error_count", "RPC Errors", COUNT); - public static final Measure RPC_CLIENT_REQUEST_BYTES = + public static final MeasureDouble RPC_CLIENT_REQUEST_BYTES = Measure.MeasureDouble.create( "grpc.io/client/request_bytes", "Request bytes", BYTE); - public static final Measure RPC_CLIENT_RESPONSE_BYTES = + public static final MeasureDouble RPC_CLIENT_RESPONSE_BYTES = Measure.MeasureDouble.create( "grpc.io/client/response_bytes", "Response bytes", BYTE); - public static final Measure RPC_CLIENT_ROUNDTRIP_LATENCY = + public static final MeasureDouble RPC_CLIENT_ROUNDTRIP_LATENCY = Measure.MeasureDouble.create( "grpc.io/client/roundtrip_latency", "RPC roundtrip latency msec", MILLISECOND); - public static final Measure RPC_CLIENT_SERVER_ELAPSED_TIME = + public static final MeasureDouble RPC_CLIENT_SERVER_ELAPSED_TIME = Measure.MeasureDouble.create( "grpc.io/client/server_elapsed_time", "Server elapsed time in msecs", MILLISECOND); - public static final Measure RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES = + public static final MeasureDouble RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES = Measure.MeasureDouble.create( "grpc.io/client/uncompressed_request_bytes", "Uncompressed Request bytes", BYTE); - public static final Measure RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES = + public static final MeasureDouble RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES = Measure.MeasureDouble.create( "grpc.io/client/uncompressed_response_bytes", "Uncompressed Response bytes", BYTE); - public static final Measure RPC_CLIENT_STARTED_COUNT = + public static final MeasureDouble RPC_CLIENT_STARTED_COUNT = Measure.MeasureDouble.create( "grpc.io/client/started_count", "Number of client RPCs (streams) started", COUNT); - public static final Measure RPC_CLIENT_FINISHED_COUNT = + public static final MeasureDouble RPC_CLIENT_FINISHED_COUNT = Measure.MeasureDouble.create( "grpc.io/client/finished_count", "Number of client RPCs (streams) finished", COUNT); - public static final Measure RPC_CLIENT_REQUEST_COUNT = + public static final MeasureDouble RPC_CLIENT_REQUEST_COUNT = Measure.MeasureDouble.create( "grpc.io/client/request_count", "Number of client RPC request messages", COUNT); - public static final Measure RPC_CLIENT_RESPONSE_COUNT = + public static final MeasureDouble RPC_CLIENT_RESPONSE_COUNT = Measure.MeasureDouble.create( "grpc.io/client/response_count", "Number of client RPC response messages", @@ -88,64 +90,64 @@ public final class RpcMeasurementConstants { // RPC server Measures. - public static final Measure RPC_SERVER_ERROR_COUNT = + public static final MeasureDouble RPC_SERVER_ERROR_COUNT = Measure.MeasureDouble.create( "grpc.io/server/error_count", "RPC Errors", COUNT); - public static final Measure RPC_SERVER_REQUEST_BYTES = + public static final MeasureDouble RPC_SERVER_REQUEST_BYTES = Measure.MeasureDouble.create( "grpc.io/server/request_bytes", "Request bytes", BYTE); - public static final Measure RPC_SERVER_RESPONSE_BYTES = + public static final MeasureDouble RPC_SERVER_RESPONSE_BYTES = Measure.MeasureDouble.create( "grpc.io/server/response_bytes", "Response bytes", BYTE); - public static final Measure RPC_SERVER_SERVER_ELAPSED_TIME = + public static final MeasureDouble RPC_SERVER_SERVER_ELAPSED_TIME = Measure.MeasureDouble.create( "grpc.io/server/server_elapsed_time", "Server elapsed time in msecs", MILLISECOND); - public static final Measure RPC_SERVER_SERVER_LATENCY = + public static final MeasureDouble RPC_SERVER_SERVER_LATENCY = Measure.MeasureDouble.create( "grpc.io/server/server_latency", "Latency in msecs", MILLISECOND); - public static final Measure RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES = + public static final MeasureDouble RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES = Measure.MeasureDouble.create( "grpc.io/server/uncompressed_request_bytes", "Uncompressed Request bytes", BYTE); - public static final Measure RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES = + public static final MeasureDouble RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES = Measure.MeasureDouble.create( "grpc.io/server/uncompressed_response_bytes", "Uncompressed Response bytes", BYTE); - public static final Measure RPC_SERVER_STARTED_COUNT = + public static final MeasureDouble RPC_SERVER_STARTED_COUNT = Measure.MeasureDouble.create( "grpc.io/server/started_count", "Number of server RPCs (streams) started", COUNT); - public static final Measure RPC_SERVER_FINISHED_COUNT = + public static final MeasureDouble RPC_SERVER_FINISHED_COUNT = Measure.MeasureDouble.create( "grpc.io/server/finished_count", "Number of server RPCs (streams) finished", COUNT); - public static final Measure RPC_SERVER_REQUEST_COUNT = + public static final MeasureDouble RPC_SERVER_REQUEST_COUNT = Measure.MeasureDouble.create( "grpc.io/server/request_count", "Number of server RPC request messages", COUNT); - public static final Measure RPC_SERVER_RESPONSE_COUNT = + public static final MeasureDouble RPC_SERVER_RESPONSE_COUNT = Measure.MeasureDouble.create( "grpc.io/server/response_count", "Number of server RPC response messages", COUNT); // Visible for testing. - RpcMeasurementConstants() { + RpcMeasureConstants() { throw new AssertionError(); } } diff --git a/core/src/main/java/io/opencensus/stats/RpcViewConstants.java b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java index 79d743b56e..812629a5d5 100644 --- a/core/src/main/java/io/opencensus/stats/RpcViewConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java @@ -13,31 +13,31 @@ package io.opencensus.stats; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_ERROR_COUNT; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_FINISHED_COUNT; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_METHOD; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_REQUEST_BYTES; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_REQUEST_COUNT; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_RESPONSE_BYTES; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_RESPONSE_COUNT; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_SERVER_ELAPSED_TIME; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_STARTED_COUNT; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_ERROR_COUNT; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_FINISHED_COUNT; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_METHOD; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_REQUEST_BYTES; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_REQUEST_COUNT; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_RESPONSE_BYTES; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_RESPONSE_COUNT; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_SERVER_ELAPSED_TIME; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_SERVER_LATENCY; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_STARTED_COUNT; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES; -import static io.opencensus.stats.RpcMeasurementConstants.RPC_STATUS; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_ERROR_COUNT; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_FINISHED_COUNT; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_METHOD; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_REQUEST_BYTES; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_REQUEST_COUNT; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_RESPONSE_BYTES; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_RESPONSE_COUNT; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_SERVER_ELAPSED_TIME; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_STARTED_COUNT; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES; +import static io.opencensus.stats.RpcMeasureConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_ERROR_COUNT; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_FINISHED_COUNT; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_METHOD; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_REQUEST_BYTES; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_REQUEST_COUNT; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_RESPONSE_BYTES; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_RESPONSE_COUNT; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_SERVER_ELAPSED_TIME; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_SERVER_LATENCY; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_STARTED_COUNT; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES; +import static io.opencensus.stats.RpcMeasureConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES; +import static io.opencensus.stats.RpcMeasureConstants.RPC_STATUS; import io.opencensus.common.Duration; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; diff --git a/core/src/test/java/io/opencensus/stats/RpcMeasureConstantsTest.java b/core/src/test/java/io/opencensus/stats/RpcMeasureConstantsTest.java new file mode 100644 index 0000000000..a05473889f --- /dev/null +++ b/core/src/test/java/io/opencensus/stats/RpcMeasureConstantsTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test for {@link RpcMeasureConstants}. + */ +@RunWith(JUnit4.class) +public class RpcMeasureConstantsTest { + + @Test + public void testConstants() { + assertThat(RpcMeasureConstants.RPC_STATUS).isNotNull(); + assertThat(RpcMeasureConstants.RPC_CLIENT_METHOD).isNotNull(); + assertThat(RpcMeasureConstants.RPC_SERVER_METHOD).isNotNull(); + + // Test client measurement descriptors. + assertThat(RpcMeasureConstants.RPC_CLIENT_ERROR_COUNT).isNotNull(); + assertThat(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY).isNotNull(); + assertThat(RpcMeasureConstants.RPC_CLIENT_REQUEST_BYTES).isNotNull(); + assertThat(RpcMeasureConstants.RPC_CLIENT_RESPONSE_BYTES).isNotNull(); + assertThat(RpcMeasureConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES).isNotNull(); + assertThat(RpcMeasureConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES).isNotNull(); + assertThat(RpcMeasureConstants.RPC_CLIENT_REQUEST_COUNT).isNotNull(); + assertThat(RpcMeasureConstants.RPC_CLIENT_RESPONSE_COUNT).isNotNull(); + assertThat(RpcMeasureConstants.RPC_CLIENT_STARTED_COUNT).isNotNull(); + assertThat(RpcMeasureConstants.RPC_CLIENT_FINISHED_COUNT).isNotNull(); + assertThat(RpcMeasureConstants.RPC_CLIENT_SERVER_ELAPSED_TIME).isNotNull(); + + // Test server measurement descriptors. + assertThat(RpcMeasureConstants.RPC_SERVER_ERROR_COUNT).isNotNull(); + assertThat(RpcMeasureConstants.RPC_SERVER_REQUEST_BYTES).isNotNull(); + assertThat(RpcMeasureConstants.RPC_SERVER_RESPONSE_BYTES).isNotNull(); + assertThat(RpcMeasureConstants.RPC_SERVER_SERVER_LATENCY).isNotNull(); + assertThat(RpcMeasureConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES).isNotNull(); + assertThat(RpcMeasureConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES).isNotNull(); + assertThat(RpcMeasureConstants.RPC_SERVER_REQUEST_COUNT).isNotNull(); + assertThat(RpcMeasureConstants.RPC_SERVER_RESPONSE_COUNT).isNotNull(); + assertThat(RpcMeasureConstants.RPC_SERVER_STARTED_COUNT).isNotNull(); + assertThat(RpcMeasureConstants.RPC_SERVER_FINISHED_COUNT).isNotNull(); + } + + @Test(expected = AssertionError.class) + public void testConstructor() { + new RpcMeasureConstants(); + } +} diff --git a/core/src/test/java/io/opencensus/stats/RpcMeasurementConstantsTest.java b/core/src/test/java/io/opencensus/stats/RpcMeasurementConstantsTest.java deleted file mode 100644 index e15ffc2f6d..0000000000 --- a/core/src/test/java/io/opencensus/stats/RpcMeasurementConstantsTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Test for {@link RpcMeasurementConstants}. - */ -@RunWith(JUnit4.class) -public class RpcMeasurementConstantsTest { - - @Test - public void testConstants() { - assertThat(RpcMeasurementConstants.RPC_STATUS).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_CLIENT_METHOD).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_SERVER_METHOD).isNotNull(); - - // Test client measurement descriptors. - assertThat(RpcMeasurementConstants.RPC_CLIENT_ERROR_COUNT).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_CLIENT_REQUEST_BYTES).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_CLIENT_RESPONSE_BYTES).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_CLIENT_REQUEST_COUNT).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_CLIENT_RESPONSE_COUNT).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_CLIENT_STARTED_COUNT).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_CLIENT_FINISHED_COUNT).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_CLIENT_SERVER_ELAPSED_TIME).isNotNull(); - - // Test server measurement descriptors. - assertThat(RpcMeasurementConstants.RPC_SERVER_ERROR_COUNT).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_SERVER_REQUEST_BYTES).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_SERVER_RESPONSE_BYTES).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_SERVER_SERVER_LATENCY).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_SERVER_REQUEST_COUNT).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_SERVER_RESPONSE_COUNT).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_SERVER_STARTED_COUNT).isNotNull(); - assertThat(RpcMeasurementConstants.RPC_SERVER_FINISHED_COUNT).isNotNull(); - } - - @Test(expected = AssertionError.class) - public void testConstructor() { - new RpcMeasurementConstants(); - } -} diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index aa85036147..7953327386 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -21,7 +21,6 @@ import io.opencensus.common.Function; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.internal.VarInt; -import io.opencensus.stats.Measure.MeasureDouble; import io.opencensus.stats.Measure.MeasureLong; import io.opencensus.stats.View.DistributionView; import io.opencensus.stats.View.IntervalView; @@ -141,10 +140,10 @@ public Void apply(IntervalView view) { }); StatsContext context = defaultStatsContext.with( - RpcMeasurementConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); + RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); MeasureMap measurements = MeasureMap.builder() - .set((MeasureDouble) RpcMeasurementConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); + .set(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); context.record(measurements); View afterView = viewManager.getView( @@ -158,7 +157,7 @@ public Void apply(DistributionView view) { assertThat(agg.getTags()) .containsExactly( Tag.create( - RpcMeasurementConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod"))); + RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod"))); assertThat(agg.getCount()).isEqualTo(1); assertThat(agg.getMean()).isWithin(TOLERANCE).of(5.1); return null; From 50e3c586da0ae4f4a4333c9b9e5ceab701c44e3e Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 6 Jul 2017 13:45:46 -0700 Subject: [PATCH 0237/1581] Add convenience functions for handling default case in "match" methods. --- .../java/io/opencensus/common/Functions.java | 75 +++++++++++++++++++ .../io/opencensus/common/FunctionsTest.java | 42 +++++++++++ 2 files changed, 117 insertions(+) create mode 100644 api/src/main/java/io/opencensus/common/Functions.java create mode 100644 api/src/test/java/io/opencensus/common/FunctionsTest.java diff --git a/api/src/main/java/io/opencensus/common/Functions.java b/api/src/main/java/io/opencensus/common/Functions.java new file mode 100644 index 0000000000..60bb888554 --- /dev/null +++ b/api/src/main/java/io/opencensus/common/Functions.java @@ -0,0 +1,75 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.common; + +/** Commonly used {@link Function} instances. */ +public final class Functions { + private Functions() {} + + private static final Function RETURN_NULL = + new Function() { + @Override + public Void apply(Object ignored) { + return null; + } + }; + + private static final Function THROW_ILLEGAL_ARGUMENT_EXCEPTION = + new Function() { + @Override + public Void apply(Object ignored) { + throw new IllegalArgumentException(); + } + }; + + /** + * A {@code Function} that always ignores its argument and returns {@code null}. + * + * @return a {@code Function} that always ignores its argument and returns {@code null}. + */ + public static Function returnNull() { + // It is safe to cast a producer of Void to anything, because Void is always null. + @SuppressWarnings("unchecked") + Function function = (Function) RETURN_NULL; + return function; + } + + /** + * A {@code Function} that always ignores its argument and returns a constant value. + * + * @return a {@code Function} that always ignores its argument and returns a constant value. + */ + public static Function returnConstant(final T constant) { + return new Function() { + @Override + public T apply(Object ignored) { + return constant; + } + }; + } + + /** + * A {@code Function} that always ignores its argument and throws an {@link + * IllegalArgumentException}. + * + * @return a {@code Function} that always ignores its argument and throws an {@link + * IllegalArgumentException}. + */ + public static Function throwIllegalArgumentException() { + // It is safe to cast a producer of Void to anything, because Void is always null. + @SuppressWarnings("unchecked") + Function function = (Function) THROW_ILLEGAL_ARGUMENT_EXCEPTION; + return function; + } +} diff --git a/api/src/test/java/io/opencensus/common/FunctionsTest.java b/api/src/test/java/io/opencensus/common/FunctionsTest.java new file mode 100644 index 0000000000..1c8df81998 --- /dev/null +++ b/api/src/test/java/io/opencensus/common/FunctionsTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.common; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +/** Tests for {@link Functions}. */ +public class FunctionsTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testReturnNull() { + assertThat(Functions.returnNull().apply("ignored")).isNull(); + } + + @Test + public void testReturnConstant() { + assertThat(Functions.returnConstant(123).apply("ignored")).isEqualTo(123); + } + + @Test + public void testThrowIllegalArgumentException() { + Function f = Functions.throwIllegalArgumentException(); + thrown.expect(IllegalArgumentException.class); + f.apply("ignored"); + } +} From 72c82e53c4c1e93ab5216402dea56dffaee467a8 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 6 Jul 2017 13:47:30 -0700 Subject: [PATCH 0238/1581] Refactor AttributeValue to use a "match" method. AttributeValue.match takes four function arguments: functions for handling String, Long, and Boolean values, and a function for handling any new types that could be added in the future. --- .../java/io/opencensus/common/Function.java | 5 +- .../io/opencensus/trace/AttributeValue.java | 115 +++++++++++++----- .../opencensus/trace/AttributeValueTest.java | 78 ++++++++++-- 3 files changed, 157 insertions(+), 41 deletions(-) diff --git a/api/src/main/java/io/opencensus/common/Function.java b/api/src/main/java/io/opencensus/common/Function.java index 6105c3e674..035a236308 100644 --- a/api/src/main/java/io/opencensus/common/Function.java +++ b/api/src/main/java/io/opencensus/common/Function.java @@ -14,13 +14,12 @@ package io.opencensus.common; /** - * Used to specify matching functions for use encoding tagged unions (i.e. sum types) in Java. + * Used to specify matching functions for use encoding tagged unions (i.e. sum types) in Java. See + * {@link io.opencensus.trace.AttributeValue#match} for an example of its use. * *

            Note: This class is based on the java.util.Function class added in Java 1.8. We cannot use the * Function from Java 1.8 because this library is Java 1.6 compatible. */ -// TODO(bdrutu): Add back "See {@link io.opencensus.stats.ViewDescriptor} for an example of its -// use." public interface Function { B apply(A arg); } diff --git a/api/src/main/java/io/opencensus/trace/AttributeValue.java b/api/src/main/java/io/opencensus/trace/AttributeValue.java index f66fd42597..ed314583be 100644 --- a/api/src/main/java/io/opencensus/trace/AttributeValue.java +++ b/api/src/main/java/io/opencensus/trace/AttributeValue.java @@ -16,7 +16,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.auto.value.AutoValue; -import javax.annotation.Nullable; +import io.opencensus.common.Function; import javax.annotation.concurrent.Immutable; /** @@ -24,7 +24,6 @@ * of values: {@code String}, {@code Boolean} or {@code Long}. */ @Immutable -@AutoValue public abstract class AttributeValue { /** * Returns an {@code AttributeValue} with a string value. @@ -34,7 +33,7 @@ public abstract class AttributeValue { * @throws NullPointerException if {@code stringValue} is {@code null}. */ public static AttributeValue stringAttributeValue(String stringValue) { - return new AutoValue_AttributeValue(checkNotNull(stringValue, "stringValue"), null, null); + return AttributeValueString.create(stringValue); } /** @@ -44,7 +43,7 @@ public static AttributeValue stringAttributeValue(String stringValue) { * @return an {@code AttributeValue} with a boolean value. */ public static AttributeValue booleanAttributeValue(boolean booleanValue) { - return new AutoValue_AttributeValue(null, booleanValue, null); + return AttributeValueBoolean.create(booleanValue); } /** @@ -54,38 +53,96 @@ public static AttributeValue booleanAttributeValue(boolean booleanValue) { * @return an {@code AttributeValue} with a long value. */ public static AttributeValue longAttributeValue(long longValue) { - return new AutoValue_AttributeValue(null, null, longValue); + return AttributeValueLong.create(longValue); } AttributeValue() {} /** - * Returns the {@code String} value if this is a string {@code AttributeValue}, otherwise {@code - * null}. + * Applies a function to the underlying value. The function that is called depends on the value's + * type, which can be {@code String}, {@code Long}, or {@code Boolean}. * - * @return the {@code String} value if this is a string {@code AttributeValue}, otherwise {@code - * null}. + * @param stringFunction the function that should be applied if the value has type {@code String}. + * @param longFunction the function that should be applied if the value has type {@code Long}. + * @param booleanFunction the function that should be applied if the value has type {@code + * Boolean}. + * @param defaultFunction the function that should be applied if the value has a type that was + * added after this {@code match} method was added to the API. See {@link + * io.opencensus.common.Functions} for some common functions for handling unknown types. + * @return the result of the function applied to the underlying value. */ - @Nullable - public abstract String getStringValue(); + public abstract T match( + Function stringFunction, + Function booleanFunction, + Function longFunction, + Function defaultFunction); - /** - * Returns the {@code Boolean} value if this is a boolean {@code AttributeValue}, otherwise {@code - * null}. - * - * @return the {@code Boolean} value if this is a boolean {@code AttributeValue}, otherwise {@code - * null}. - */ - @Nullable - public abstract Boolean getBooleanValue(); + @Immutable + @AutoValue + abstract static class AttributeValueString extends AttributeValue { - /** - * Returns the {@code Long} value if this is a long {@code AttributeValue}, otherwise {@code - * null}. - * - * @return the {@code Long} value if this is a long {@code AttributeValue}, otherwise {@code - * null}. - */ - @Nullable - public abstract Long getLongValue(); + AttributeValueString() {} + + static AttributeValue create(String stringValue) { + return new AutoValue_AttributeValue_AttributeValueString( + checkNotNull(stringValue, "stringValue")); + } + + @Override + public final T match( + Function stringFunction, + Function booleanFunction, + Function longFunction, + Function defaultFunction) { + return stringFunction.apply(getStringValue()); + } + + abstract String getStringValue(); + } + + @Immutable + @AutoValue + abstract static class AttributeValueBoolean extends AttributeValue { + + AttributeValueBoolean() {} + + static AttributeValue create(Boolean stringValue) { + return new AutoValue_AttributeValue_AttributeValueBoolean( + checkNotNull(stringValue, "stringValue")); + } + + @Override + public final T match( + Function stringFunction, + Function booleanFunction, + Function longFunction, + Function defaultFunction) { + return booleanFunction.apply(getBooleanValue()); + } + + abstract Boolean getBooleanValue(); + } + + @Immutable + @AutoValue + abstract static class AttributeValueLong extends AttributeValue { + + AttributeValueLong() {} + + static AttributeValue create(Long stringValue) { + return new AutoValue_AttributeValue_AttributeValueLong( + checkNotNull(stringValue, "stringValue")); + } + + @Override + public final T match( + Function stringFunction, + Function booleanFunction, + Function longFunction, + Function defaultFunction) { + return longFunction.apply(getLongValue()); + } + + abstract Long getLongValue(); + } } diff --git a/api/src/test/java/io/opencensus/trace/AttributeValueTest.java b/api/src/test/java/io/opencensus/trace/AttributeValueTest.java index 7a999604e4..e078c4efe7 100644 --- a/api/src/test/java/io/opencensus/trace/AttributeValueTest.java +++ b/api/src/test/java/io/opencensus/trace/AttributeValueTest.java @@ -14,8 +14,11 @@ package io.opencensus.trace; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; import com.google.common.testing.EqualsTester; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -26,25 +29,82 @@ public class AttributeValueTest { @Test public void stringAttributeValue() { AttributeValue attribute = AttributeValue.stringAttributeValue("MyStringAttributeValue"); - assertThat(attribute.getStringValue()).isEqualTo("MyStringAttributeValue"); - assertThat(attribute.getBooleanValue()).isNull(); - assertThat(attribute.getLongValue()).isNull(); + attribute.match( + new Function() { + @Override + public Object apply(String stringValue) { + assertThat(stringValue).isEqualTo("MyStringAttributeValue"); + return null; + } + }, + new Function() { + @Override + public Object apply(Boolean booleanValue) { + fail("Expected a String"); + return null; + } + }, + new Function() { + @Override + public Object apply(Long longValue) { + fail("Expected a String"); + return null; + } + }, Functions.throwIllegalArgumentException()); } @Test public void booleanAttributeValue() { AttributeValue attribute = AttributeValue.booleanAttributeValue(true); - assertThat(attribute.getStringValue()).isNull(); - assertThat(attribute.getBooleanValue()).isTrue(); - assertThat(attribute.getLongValue()).isNull(); + attribute.match( + new Function() { + @Override + public Object apply(String stringValue) { + fail("Expected a Boolean"); + return null; + } + }, + new Function() { + @Override + public Object apply(Boolean booleanValue) { + assertThat(booleanValue).isTrue(); + return null; + } + }, + new Function() { + @Override + public Object apply(Long longValue) { + fail("Expected a Boolean"); + return null; + } + }, Functions.throwIllegalArgumentException()); } @Test public void longAttributeValue() { AttributeValue attribute = AttributeValue.longAttributeValue(123456L); - assertThat(attribute.getStringValue()).isNull(); - assertThat(attribute.getBooleanValue()).isNull(); - assertThat(attribute.getLongValue()).isEqualTo(123456L); + attribute.match( + new Function() { + @Override + public Object apply(String stringValue) { + fail("Expected a Long"); + return null; + } + }, + new Function() { + @Override + public Object apply(Boolean booleanValue) { + fail("Expected a Long"); + return null; + } + }, + new Function() { + @Override + public Object apply(Long longValue) { + assertThat(longValue).isEqualTo(123456L); + return null; + } + }, Functions.throwIllegalArgumentException()); } @Test From 02e9a6a8671653a246c31cbe8bb46f0b83945705 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Thu, 6 Jul 2017 15:13:05 -0700 Subject: [PATCH 0239/1581] Rename View to ViewData. (#418) --- .../stats/{View.java => ViewData.java} | 46 ++-- .../java/io/opencensus/stats/ViewManager.java | 7 +- .../{ViewTest.java => ViewDataTest.java} | 92 ++++--- .../io/opencensus/stats/MeasureToViewMap.java | 82 +++--- ...{MutableView.java => MutableViewData.java} | 56 ++-- .../io/opencensus/stats/StatsManager.java | 15 +- .../io/opencensus/stats/ViewManagerImpl.java | 12 +- .../stats/MeasureToViewMapTest.java | 24 +- ...ViewTest.java => MutableViewDataTest.java} | 6 +- .../io/opencensus/stats/StatsContextTest.java | 35 ++- .../opencensus/stats/ViewManagerImplTest.java | 239 +++++++++--------- 11 files changed, 305 insertions(+), 309 deletions(-) rename core/src/main/java/io/opencensus/stats/{View.java => ViewData.java} (73%) rename core/src/test/java/io/opencensus/stats/{ViewTest.java => ViewDataTest.java} (69%) rename core_impl/src/main/java/io/opencensus/stats/{MutableView.java => MutableViewData.java} (75%) rename core_impl/src/test/java/io/opencensus/stats/{MutableViewTest.java => MutableViewDataTest.java} (83%) diff --git a/core/src/main/java/io/opencensus/stats/View.java b/core/src/main/java/io/opencensus/stats/ViewData.java similarity index 73% rename from core/src/main/java/io/opencensus/stats/View.java rename to core/src/main/java/io/opencensus/stats/ViewData.java index ed8841fbd5..686e8914bc 100644 --- a/core/src/main/java/io/opencensus/stats/View.java +++ b/core/src/main/java/io/opencensus/stats/ViewData.java @@ -27,9 +27,9 @@ * The aggregated data for a particular {@link ViewDescriptor}. */ @Immutable -public abstract class View { +public abstract class ViewData { /** - * The {@link ViewDescriptor} associated with this {@link View}. + * The {@link ViewDescriptor} associated with this {@link ViewData}. */ public abstract ViewDescriptor getViewDescriptor(); @@ -37,26 +37,26 @@ public abstract class View { * Applies the given match function to the underlying data type. */ public abstract T match( - Function p0, - Function p1); + Function p0, + Function p1); // Prevents this class from being subclassed anywhere else. - private View() { + private ViewData() { } /** - * A {@link View} for distribution-based aggregations. + * A {@link ViewData} for distribution-based aggregations. */ @Immutable @AutoValue - public abstract static class DistributionView extends View { + public abstract static class DistributionViewData extends ViewData { /** - * Constructs a new {@link DistributionView}. + * Constructs a new {@link DistributionViewData}. */ - public static DistributionView create(DistributionViewDescriptor distributionViewDescriptor, + public static DistributionViewData create(DistributionViewDescriptor distributionView, List distributionAggregations, Timestamp start, Timestamp end) { - return new AutoValue_View_DistributionView( - distributionViewDescriptor, + return new AutoValue_ViewData_DistributionViewData( + distributionView, Collections.unmodifiableList( new ArrayList(distributionAggregations)), start, @@ -67,7 +67,7 @@ public static DistributionView create(DistributionViewDescriptor distributionVie public abstract DistributionViewDescriptor getViewDescriptor(); /** - * The {@link DistributionAggregation}s associated with this {@link DistributionView}. + * The {@link DistributionAggregation}s associated with this {@link DistributionViewData}. * *

            Note: The returned list is unmodifiable, attempts to update it will throw an * UnsupportedOperationException. @@ -86,25 +86,25 @@ public static DistributionView create(DistributionViewDescriptor distributionVie @Override public final T match( - Function p0, - Function p1) { + Function p0, + Function p1) { return p0.apply(this); } } /** - * A {@link View} for interval-base aggregations. + * A {@link ViewData} for interval-base aggregations. */ @Immutable @AutoValue - public abstract static class IntervalView extends View { + public abstract static class IntervalViewData extends ViewData { /** - * Constructs a new {@link IntervalView}. + * Constructs a new {@link IntervalViewData}. */ - public static IntervalView create(IntervalViewDescriptor intervalViewDescriptor, + public static IntervalViewData create(IntervalViewDescriptor intervalView, List intervalAggregations) { - return new AutoValue_View_IntervalView( - intervalViewDescriptor, + return new AutoValue_ViewData_IntervalViewData( + intervalView, Collections.unmodifiableList(new ArrayList(intervalAggregations))); } @@ -112,7 +112,7 @@ public static IntervalView create(IntervalViewDescriptor intervalViewDescriptor, public abstract IntervalViewDescriptor getViewDescriptor(); /** - * The {@link IntervalAggregation}s associated with this {@link IntervalView}. + * The {@link IntervalAggregation}s associated with this {@link IntervalViewData}. * *

            Note: The returned list is unmodifiable, attempts to update it will throw an * UnsupportedOperationException. @@ -121,8 +121,8 @@ public static IntervalView create(IntervalViewDescriptor intervalViewDescriptor, @Override public final T match( - Function p0, - Function p1) { + Function p0, + Function p1) { return p1.apply(this); } } diff --git a/core/src/main/java/io/opencensus/stats/ViewManager.java b/core/src/main/java/io/opencensus/stats/ViewManager.java index 78400ee5f8..9d723b1847 100644 --- a/core/src/main/java/io/opencensus/stats/ViewManager.java +++ b/core/src/main/java/io/opencensus/stats/ViewManager.java @@ -15,7 +15,7 @@ /** * Provides facilities to register {@link ViewDescriptor}s for collecting stats and retrieving - * stats data as a {@link View}. + * stats data as a {@link ViewData}. */ public abstract class ViewManager { /** @@ -25,7 +25,8 @@ public abstract class ViewManager { public abstract void registerView(ViewDescriptor viewDescriptor); /** - * Returns the current stats data, {@link View}, associated with the given {@link ViewDescriptor}. + * Returns the current stats data, {@link ViewData}, associated with the given + * {@link ViewDescriptor}. */ - public abstract View getView(ViewDescriptor viewDescriptor); + public abstract ViewData getView(ViewDescriptor viewDescriptor); } diff --git a/core/src/test/java/io/opencensus/stats/ViewTest.java b/core/src/test/java/io/opencensus/stats/ViewDataTest.java similarity index 69% rename from core/src/test/java/io/opencensus/stats/ViewTest.java rename to core/src/test/java/io/opencensus/stats/ViewDataTest.java index 6d73d03443..4b283cf20d 100644 --- a/core/src/test/java/io/opencensus/stats/ViewTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewDataTest.java @@ -22,8 +22,8 @@ import io.opencensus.common.Timestamp; import io.opencensus.stats.DistributionAggregation.Range; import io.opencensus.stats.IntervalAggregation.Interval; -import io.opencensus.stats.View.DistributionView; -import io.opencensus.stats.View.IntervalView; +import io.opencensus.stats.ViewData.DistributionViewData; +import io.opencensus.stats.ViewData.IntervalViewData; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Arrays; @@ -33,16 +33,14 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for class {@link View}. - */ +/** Tests for class {@link ViewData}. */ @RunWith(JUnit4.class) -public final class ViewTest { +public final class ViewDataTest { @Test - public void testDistributionView() { + public void testDistributionViewData() { DistributionAggregationDescriptor aggregationDescriptor = DistributionAggregationDescriptor.create(Arrays.asList(10.0, 20.0, 30.0, 40.0)); - final DistributionViewDescriptor viewDescriptor = + final DistributionViewDescriptor view = DistributionViewDescriptor.create( name, description, measure, aggregationDescriptor, tagKeys); final List aggregations = Arrays.asList( @@ -52,31 +50,31 @@ public void testDistributionView() { Arrays.asList(2L, 2L, 2L, 2L, 2L))); final Timestamp start = Timestamp.fromMillis(1000); final Timestamp end = Timestamp.fromMillis(2000); - final View view = DistributionView.create(viewDescriptor, aggregations, start, end); + final ViewData viewData = DistributionViewData.create(view, aggregations, start, end); - assertThat(view.getViewDescriptor()).isEqualTo(viewDescriptor); - assertTrue(view.match( - new Function () { - @Override public Boolean apply(DistributionView dView) { - return dView == view - && dView.getViewDescriptor().equals(viewDescriptor) - && shallowListEquals(dView.getDistributionAggregations(), aggregations) - && dView.getStart().equals(start) - && dView.getEnd().equals(end); + assertThat(viewData.getViewDescriptor()).isEqualTo(view); + assertTrue(viewData.match( + new Function () { + @Override public Boolean apply(DistributionViewData dViewData) { + return dViewData == viewData + && dViewData.getViewDescriptor().equals(view) + && shallowListEquals(dViewData.getDistributionAggregations(), aggregations) + && dViewData.getStart().equals(start) + && dViewData.getEnd().equals(end); } }, - new Function () { - @Override public Boolean apply(IntervalView iView) { + new Function () { + @Override public Boolean apply(IntervalViewData iViewData) { return false; } })); } @Test - public void testIntervalView() { + public void testIntervalViewData() { IntervalAggregationDescriptor aggregationDescriptor = IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(111))); - final IntervalViewDescriptor viewDescriptor = + final IntervalViewDescriptor view = IntervalViewDescriptor.create( name, description, measure, aggregationDescriptor, tagKeys); final List aggregations = Arrays.asList( @@ -85,26 +83,26 @@ public void testIntervalView() { IntervalAggregation.create(tags2, Arrays.asList( Interval.create(Duration.fromMillis(111), 10, 100)))); - final View view = IntervalView.create(viewDescriptor, aggregations); - assertThat(view.getViewDescriptor()).isEqualTo(viewDescriptor); - assertTrue(view.match( - new Function () { - @Override public Boolean apply(DistributionView dView) { + final ViewData viewData = IntervalViewData.create(view, aggregations); + assertThat(viewData.getViewDescriptor()).isEqualTo(view); + assertTrue(viewData.match( + new Function () { + @Override public Boolean apply(DistributionViewData dViewData) { return false; } }, - new Function () { - @Override public Boolean apply(IntervalView iView) { - return iView == view - && iView.getViewDescriptor().equals(viewDescriptor) - && shallowListEquals(iView.getIntervalAggregations(), aggregations); + new Function () { + @Override public Boolean apply(IntervalViewData iViewData) { + return iViewData == viewData + && iViewData.getViewDescriptor().equals(view) + && shallowListEquals(iViewData.getIntervalAggregations(), aggregations); } })); } @Test - public void testViewEquals() { - DistributionViewDescriptor dViewDescriptor = + public void testViewDataEquals() { + DistributionViewDescriptor dView = DistributionViewDescriptor.create( name, description, @@ -115,7 +113,7 @@ public void testViewEquals() { Arrays.asList( DistributionAggregation.create( 5, 5.0, 15.0, Range.create(1.0, 5.0), tags1, Arrays.asList(1L))); - IntervalViewDescriptor iViewDescriptor = + IntervalViewDescriptor iView = IntervalViewDescriptor.create( name, description, @@ -129,27 +127,27 @@ public void testViewEquals() { new EqualsTester() .addEqualityGroup( - DistributionView.create( - dViewDescriptor, + DistributionViewData.create( + dView, dAggregations, Timestamp.fromMillis(1000), Timestamp.fromMillis(2000)), - DistributionView.create( - dViewDescriptor, + DistributionViewData.create( + dView, dAggregations, Timestamp.fromMillis(1000), Timestamp.fromMillis(2000))) .addEqualityGroup( - DistributionView.create( - dViewDescriptor, + DistributionViewData.create( + dView, dAggregations, Timestamp.fromMillis(1000), Timestamp.fromMillis(3000))) .addEqualityGroup( - IntervalView.create(iViewDescriptor, iAggregations), - IntervalView.create(iViewDescriptor, iAggregations)) + IntervalViewData.create(iView, iAggregations), + IntervalViewData.create(iView, iAggregations)) .addEqualityGroup( - IntervalView.create(iViewDescriptor, Collections.emptyList())) + IntervalViewData.create(iView, Collections.emptyList())) .testEquals(); } @@ -169,13 +167,13 @@ public void testViewEquals() { List tags2 = Arrays.asList(Tag.create(K1, V10), Tag.create(K2, V20)); // name - private final String name = "test-view-descriptor"; + private final String name = "test-view"; // description private final String description = "test-view-descriptor description"; // measurement descriptor private final Measure measure = Measure.MeasureDouble.create( - "measurement-descriptor", - "measurement-descriptor description", + "measure", + "measure description", "1"); private static final boolean shallowListEquals(List l1, List l2) { diff --git a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java index f2a483c6f9..9ab4b4df9c 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java +++ b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java @@ -19,8 +19,8 @@ import io.opencensus.common.Function; import io.opencensus.stats.Measurement.MeasurementDouble; import io.opencensus.stats.Measurement.MeasurementLong; -import io.opencensus.stats.MutableView.MutableDistributionView; -import io.opencensus.stats.MutableView.MutableIntervalView; +import io.opencensus.stats.MutableViewData.MutableDistributionViewData; +import io.opencensus.stats.MutableViewData.MutableIntervalViewData; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.Collection; @@ -32,39 +32,39 @@ /** * A class that stores a singleton map from {@code MeasureName}s to {@link - * MutableView}s. + * MutableViewData}s. */ final class MeasureToViewMap { /* * A synchronized singleton map that stores the one-to-many mapping from Measures - * to MutableViews. + * to MutableViewDatas. */ @GuardedBy("this") - private final Multimap mutableMap = - HashMultimap.create(); + private final Multimap mutableMap = + HashMultimap.create(); @GuardedBy("this") private final Map registeredViews = new HashMap(); - /** Returns a {@link View} corresponding to the given {@link ViewDescriptor.Name}. */ - synchronized View getView(ViewDescriptor.Name viewName, Clock clock) { - MutableView view = getMutableView(viewName); - return view == null ? null : view.toView(clock); + /** Returns a {@link ViewData} corresponding to the given {@link ViewDescriptor.Name}. */ + synchronized ViewData getView(ViewDescriptor.Name viewName, Clock clock) { + MutableViewData view = getMutableViewData(viewName); + return view == null ? null : view.toViewData(clock); } @Nullable - private synchronized MutableView getMutableView(ViewDescriptor.Name viewName) { - ViewDescriptor viewDescriptor = registeredViews.get(viewName); - if (viewDescriptor == null) { + private synchronized MutableViewData getMutableViewData(ViewDescriptor.Name viewName) { + ViewDescriptor view = registeredViews.get(viewName); + if (view == null) { return null; } - Collection views = - mutableMap.get(viewDescriptor.getMeasure().getName()); - for (MutableView view : views) { - if (view.getViewDescriptor().getViewDescriptorName().equals(viewName)) { - return view; + Collection views = + mutableMap.get(view.getMeasure().getName()); + for (MutableViewData viewData : views) { + if (viewData.getViewDescriptor().getViewDescriptorName().equals(viewName)) { + return viewData; } } throw new AssertionError("Internal error: Not recording stats for view: \"" + viewName @@ -72,10 +72,10 @@ private synchronized MutableView getMutableView(ViewDescriptor.Name viewName) { } /** Enable stats collection for the given {@link ViewDescriptor}. */ - synchronized void registerView(ViewDescriptor viewDescriptor, Clock clock) { - ViewDescriptor existing = registeredViews.get(viewDescriptor.getViewDescriptorName()); + synchronized void registerView(ViewDescriptor view, Clock clock) { + ViewDescriptor existing = registeredViews.get(view.getViewDescriptorName()); if (existing != null) { - if (existing.equals(viewDescriptor)) { + if (existing.equals(view)) { // Ignore views that are already registered. return; } else { @@ -83,13 +83,13 @@ synchronized void registerView(ViewDescriptor viewDescriptor, Clock clock) { "A different view with the same name is already registered: " + existing); } } - registeredViews.put(viewDescriptor.getViewDescriptorName(), viewDescriptor); - MutableView mutableView = - viewDescriptor.match( - new CreateMutableDistributionViewFunction(clock), - new CreateMutableIntervalViewFunction()); + registeredViews.put(view.getViewDescriptorName(), view); + MutableViewData mutableViewData = + view.match( + new CreateMutableDistributionViewDataFunction(clock), + new CreateMutableIntervalViewDataFunction()); mutableMap.put( - viewDescriptor.getMeasure().getName(), mutableView); + view.getMeasure().getName(), mutableViewData); } // Records stats with a set of tags. @@ -97,35 +97,33 @@ synchronized void record(StatsContextImpl tags, MeasureMap stats) { Iterator iterator = stats.iterator(); while (iterator.hasNext()) { Measurement measurement = iterator.next(); - Collection views = mutableMap.get(measurement.getMeasure().getName()); - for (MutableView view : views) { + Collection views = mutableMap.get(measurement.getMeasure().getName()); + for (MutableViewData view : views) { measurement.match(new RecordDoubleValueFunc(tags, view), new RecordLongValueFunc()); } } } - private static final class CreateMutableDistributionViewFunction - implements Function { - + private static final class CreateMutableDistributionViewDataFunction + implements Function { private final Clock clock; - CreateMutableDistributionViewFunction(Clock clock) { + CreateMutableDistributionViewDataFunction(Clock clock) { this.clock = clock; } @Override - public MutableView apply(DistributionViewDescriptor viewDescriptor) { - return MutableDistributionView.create(viewDescriptor, clock.now()); + public MutableViewData apply(DistributionViewDescriptor view) { + return MutableDistributionViewData.create(view, clock.now()); } } - private static final class CreateMutableIntervalViewFunction - implements Function { - + private static final class CreateMutableIntervalViewDataFunction + implements Function { @Override - public MutableView apply(IntervalViewDescriptor viewDescriptor) { + public MutableViewData apply(IntervalViewDescriptor view) { // TODO(songya): Create Interval Aggregations from internal Distributions. - return MutableIntervalView.create(viewDescriptor); + return MutableIntervalViewData.create(view); } } @@ -137,9 +135,9 @@ public Void apply(MeasurementDouble arg) { } private final StatsContextImpl tags; - private final MutableView view; + private final MutableViewData view; - private RecordDoubleValueFunc(StatsContextImpl tags, MutableView view) { + private RecordDoubleValueFunc(StatsContextImpl tags, MutableViewData view) { this.tags = tags; this.view = view; } diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableView.java b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java similarity index 75% rename from core_impl/src/main/java/io/opencensus/stats/MutableView.java rename to core_impl/src/main/java/io/opencensus/stats/MutableViewData.java index 688991cb00..95ee2a2e51 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableView.java +++ b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java @@ -16,7 +16,7 @@ import com.google.common.annotations.VisibleForTesting; import io.opencensus.common.Clock; import io.opencensus.common.Timestamp; -import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.ViewData.DistributionViewData; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.ArrayList; @@ -26,16 +26,16 @@ import java.util.Map.Entry; /** - * A mutable version of {@link View}, used for recording stats and start/end time. + * A mutable version of {@link ViewData}, used for recording stats and start/end time. */ -abstract class MutableView { +abstract class MutableViewData { // TODO(songya): might want to update the default tag value later. @VisibleForTesting static final TagValue UNKNOWN_TAG_VALUE = TagValue.create("unknown/not set"); /** - * The {@link ViewDescriptor} associated with this {@link View}. + * The {@link ViewDescriptor} associated with this {@link ViewData}. */ abstract ViewDescriptor getViewDescriptor(); @@ -45,36 +45,36 @@ abstract class MutableView { abstract void record(StatsContextImpl tags, double value); /** - * Convert this {@link MutableView} to {@link View}. + * Convert this {@link MutableViewData} to {@link ViewData}. */ - abstract View toView(Clock clock); + abstract ViewData toViewData(Clock clock); - private MutableView() { + private MutableViewData() { } /** - * A {@link MutableView} for recording stats on distribution-based aggregations. + * A {@link MutableViewData} for recording stats on distribution-based aggregations. */ - static final class MutableDistributionView extends MutableView { + static final class MutableDistributionViewData extends MutableViewData { /** - * Constructs a new {@link MutableDistributionView}. + * Constructs a new {@link MutableDistributionViewData}. */ - static MutableDistributionView create( - DistributionViewDescriptor distributionViewDescriptor, Timestamp start) { - return new MutableDistributionView(distributionViewDescriptor, start); + static MutableDistributionViewData create( + DistributionViewDescriptor distributionView, Timestamp start) { + return new MutableDistributionViewData(distributionView, start); } @Override ViewDescriptor getViewDescriptor() { - return distributionViewDescriptor; + return distributionView; } @Override void record(StatsContextImpl context, double value) { Map tags = context.tags; // TagKeys need to be unique within one view descriptor. - final List tagKeys = this.distributionViewDescriptor.getTagKeys(); + final List tagKeys = this.distributionView.getTagKeys(); final List tagValues = new ArrayList(tagKeys.size()); // Record all the measures in a "Greedy" way. @@ -91,7 +91,7 @@ void record(StatsContextImpl context, double value) { if (!tagValueDistributionMap.containsKey(tagValues)) { final List bucketBoundaries = - this.distributionViewDescriptor.getDistributionAggregationDescriptor() + this.distributionView.getDistributionAggregationDescriptor() .getBucketBoundaries(); final MutableDistribution distribution = bucketBoundaries == null ? MutableDistribution.create() @@ -102,7 +102,7 @@ void record(StatsContextImpl context, double value) { } @Override - final View toView(Clock clock) { + final ViewData toViewData(Clock clock) { final List distributionAggregations = new ArrayList(); for (Entry, MutableDistribution> entry : tagValueDistributionMap.entrySet()) { @@ -116,7 +116,7 @@ final View toView(Clock clock) { generateTags(entry.getKey()), distribution.getBucketCounts()); distributionAggregations.add(distributionAggregation); } - return DistributionView.create(distributionViewDescriptor, distributionAggregations, start, + return DistributionViewData.create(distributionView, distributionAggregations, start, clock.now()); } @@ -127,21 +127,21 @@ Timestamp getStart() { return start; } - private final DistributionViewDescriptor distributionViewDescriptor; + private final DistributionViewDescriptor distributionView; private final Map, MutableDistribution> tagValueDistributionMap = new HashMap, MutableDistribution>(); private final Timestamp start; - private MutableDistributionView( - DistributionViewDescriptor distributionViewDescriptor, Timestamp start) { - this.distributionViewDescriptor = distributionViewDescriptor; + private MutableDistributionViewData( + DistributionViewDescriptor distributionView, Timestamp start) { + this.distributionView = distributionView; this.start = start; } private final List generateTags(List tagValues) { final List tags = new ArrayList(tagValues.size()); int i = 0; - for (TagKey tagKey : this.distributionViewDescriptor.getTagKeys()) { + for (TagKey tagKey : this.distributionView.getTagKeys()) { tags.add(Tag.create(tagKey, tagValues.get(i))); ++i; } @@ -156,14 +156,14 @@ private static final DistributionAggregation.Range convertRange( } /** - * A {@link MutableView} for recording stats on interval-based aggregations. + * A {@link MutableViewData} for recording stats on interval-based aggregations. */ - static final class MutableIntervalView extends MutableView { + static final class MutableIntervalViewData extends MutableViewData { /** - * Constructs a new {@link MutableIntervalView}. + * Constructs a new {@link MutableIntervalViewData}. */ - static MutableIntervalView create(IntervalViewDescriptor viewDescriptor) { + static MutableIntervalViewData create(IntervalViewDescriptor view) { throw new UnsupportedOperationException("Not implemented."); } @@ -178,7 +178,7 @@ void record(StatsContextImpl tags, double value) { } @Override - final View toView(Clock clock) { + final ViewData toViewData(Clock clock) { throw new UnsupportedOperationException("Not implemented."); } } diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java index cf0b6f6ad3..45f779d20b 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java @@ -25,29 +25,28 @@ final class StatsManager { // clock used throughout the stats implementation private final Clock clock; - private final MeasureToViewMap measureToViewMap = - new MeasureToViewMap(); + private final MeasureToViewMap measureToViewMap = new MeasureToViewMap(); StatsManager(EventQueue queue, Clock clock) { this.queue = queue; this.clock = clock; } - void registerView(ViewDescriptor viewDescriptor) { + void registerView(ViewDescriptor view) { // Only DistributionViews are supported currently. // TODO(sebright): Remove this once all views are supported. - if (!(viewDescriptor instanceof DistributionViewDescriptor)) { + if (!(view instanceof DistributionViewDescriptor)) { throw new UnsupportedOperationException( "The prototype will only support distribution views."); } - measureToViewMap.registerView(viewDescriptor, clock); + measureToViewMap.registerView(view, clock); } - View getView(ViewDescriptor.Name viewName) { - View view = measureToViewMap.getView(viewName, clock); + ViewData getView(ViewDescriptor.Name viewName) { + ViewData view = measureToViewMap.getView(viewName, clock); if (view == null) { throw new IllegalArgumentException( - "View for view descriptor " + viewName + " not found."); + "ViewData for view " + viewName + " not found."); } else { return view; } diff --git a/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java b/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java index 4bc17e297b..132ff6d413 100644 --- a/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java +++ b/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java @@ -22,18 +22,18 @@ final class ViewManagerImpl extends ViewManager { } @Override - public void registerView(ViewDescriptor viewDescriptor) { - statsManager.registerView(viewDescriptor); + public void registerView(ViewDescriptor view) { + statsManager.registerView(view); } // TODO(sebright): Expose this method. - View getView(ViewDescriptor.Name viewName) { + ViewData getView(ViewDescriptor.Name viewName) { return statsManager.getView(viewName); } - // TODO(sebright): Replace this method with the ViewDescriptor.Name version. + // TODO(sebright): Replace this method with the View.Name version. @Override - public View getView(ViewDescriptor viewDescr) { - return statsManager.getView(viewDescr.getViewDescriptorName()); + public ViewData getView(ViewDescriptor view) { + return statsManager.getView(view.getViewDescriptorName()); } } diff --git a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java index 89b0b3c411..cca7676c27 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java @@ -18,8 +18,8 @@ import io.opencensus.common.Function; import io.opencensus.common.Timestamp; -import io.opencensus.stats.View.DistributionView; -import io.opencensus.stats.View.IntervalView; +import io.opencensus.stats.ViewData.DistributionViewData; +import io.opencensus.stats.ViewData.IntervalViewData; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.testing.common.TestClock; import java.util.Arrays; @@ -31,7 +31,7 @@ @RunWith(JUnit4.class) public class MeasureToViewMapTest { - private static final Measure MEASUREMENT_DESCRIPTOR = + private static final Measure MEASURE = Measure.MeasureDouble.create( "my measurement", "measurement description", @@ -39,11 +39,11 @@ public class MeasureToViewMapTest { private static final ViewDescriptor.Name VIEW_NAME = ViewDescriptor.Name.create("my view"); - private static final ViewDescriptor VIEW_DESCRIPTOR = + private static final ViewDescriptor VIEW = DistributionViewDescriptor.create( VIEW_NAME, "view description", - MEASUREMENT_DESCRIPTOR, + MEASURE, DistributionAggregationDescriptor.create(), Arrays.asList(TagKey.create("my key"))); @@ -51,23 +51,23 @@ public class MeasureToViewMapTest { public void testRegisterAndGetDistributionView() { MeasureToViewMap measureToViewMap = new MeasureToViewMap(); TestClock clock = TestClock.create(Timestamp.create(10, 20)); - measureToViewMap.registerView(VIEW_DESCRIPTOR, clock); + measureToViewMap.registerView(VIEW, clock); clock.setTime(Timestamp.create(30, 40)); - View actual = measureToViewMap.getView(VIEW_NAME, clock); + ViewData actual = measureToViewMap.getView(VIEW_NAME, clock); actual.match( - new Function() { + new Function() { @Override - public Void apply(DistributionView view) { - assertThat(view.getViewDescriptor()).isEqualTo(VIEW_DESCRIPTOR); + public Void apply(DistributionViewData view) { + assertThat(view.getViewDescriptor()).isEqualTo(VIEW); assertThat(view.getStart()).isEqualTo(Timestamp.create(10, 20)); assertThat(view.getEnd()).isEqualTo(Timestamp.create(30, 40)); assertThat(view.getDistributionAggregations()).isEmpty(); return null; } }, - new Function() { + new Function() { @Override - public Void apply(IntervalView view) { + public Void apply(IntervalViewData view) { fail("Wrong view type."); return null; } diff --git a/core_impl/src/test/java/io/opencensus/stats/MutableViewTest.java b/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java similarity index 83% rename from core_impl/src/test/java/io/opencensus/stats/MutableViewTest.java rename to core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java index 51265d7cc8..460cf44ab8 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MutableViewTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java @@ -20,14 +20,14 @@ import org.junit.runners.JUnit4; /** - * Tests for {@link MutableView}. + * Tests for {@link MutableViewData}. */ @RunWith(JUnit4.class) -public class MutableViewTest { +public class MutableViewDataTest { @Test public void testConstants() { - assertThat(MutableView.UNKNOWN_TAG_VALUE.asString()).isEqualTo("unknown/not set"); + assertThat(MutableViewData.UNKNOWN_TAG_VALUE.asString()).isEqualTo("unknown/not set"); } } diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index 7953327386..93ae0a0df0 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -22,8 +22,8 @@ import io.opencensus.internal.SimpleEventQueue; import io.opencensus.internal.VarInt; import io.opencensus.stats.Measure.MeasureLong; -import io.opencensus.stats.View.DistributionView; -import io.opencensus.stats.View.IntervalView; +import io.opencensus.stats.ViewData.DistributionViewData; +import io.opencensus.stats.ViewData.IntervalViewData; import io.opencensus.testing.common.TestClock; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -120,21 +120,20 @@ public void testWithComposed() { @Test public void testRecordDouble() { viewManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - View beforeView = - viewManager.getView( - RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - beforeView.match( - new Function() { + ViewData beforeViewData = + viewManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + beforeViewData.match( + new Function() { @Override - public Void apply(DistributionView view) { + public Void apply(DistributionViewData view) { assertThat(view.getDistributionAggregations()).isEmpty(); return null; } }, - new Function() { + new Function() { @Override - public Void apply(IntervalView view) { - fail("Expected a DistributionView"); + public Void apply(IntervalViewData view) { + fail("Expected a DistributionViewData"); return null; } }); @@ -145,13 +144,13 @@ public Void apply(IntervalView view) { MeasureMap.builder() .set(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); context.record(measurements); - View afterView = + ViewData afterViewData = viewManager.getView( RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - afterView.match( - new Function() { + afterViewData.match( + new Function() { @Override - public Void apply(DistributionView view) { + public Void apply(DistributionViewData view) { assertThat(view.getDistributionAggregations()).hasSize(1); DistributionAggregation agg = view.getDistributionAggregations().get(0); assertThat(agg.getTags()) @@ -163,10 +162,10 @@ public Void apply(DistributionView view) { return null; } }, - new Function() { + new Function() { @Override - public Void apply(IntervalView view) { - fail("Expected a DistributionView"); + public Void apply(IntervalViewData view) { + fail("Expected a DistributionViewData"); return null; } }); diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index 955e1f63fd..fa6325d5da 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -20,7 +20,7 @@ import io.opencensus.common.Timestamp; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.stats.Measure.MeasureDouble; -import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.ViewData.DistributionViewData; import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import io.opencensus.testing.common.TestClock; @@ -45,16 +45,17 @@ public class ViewManagerImplTest { private static final TagValue VALUE = TagValue.create("VALUE"); private static final TagValue VALUE_2 = TagValue.create("VALUE_2"); - private static final String MEASUREMENT_NAME = "my measurement"; + private static final String MEASURE_NAME = "my measurement"; - private static final String MEASUREMENT_NAME_2 = "my measurement 2"; + private static final String MEASURE_NAME_2 = "my measurement 2"; - private static final String MEASUREMENT_UNIT = "us"; + private static final String MEASURE_UNIT = "us"; - private static final String MEASUREMENT_DESCRIPTION = "measurement description"; + private static final String MEASURE_DESCRIPTION = "measure description"; - private static final MeasureDouble MEASUREMENT_DESCRIPTOR = - Measure.MeasureDouble.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); + + private static final MeasureDouble MEASURE = + Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); private static final ViewDescriptor.Name VIEW_NAME = ViewDescriptor.Name.create("my view"); private static final ViewDescriptor.Name VIEW_NAME_2 = ViewDescriptor.Name.create("my view 2"); @@ -80,22 +81,22 @@ public class ViewManagerImplTest { private static DistributionViewDescriptor createDistributionViewDescriptor() { return createDistributionViewDescriptor( - VIEW_NAME, MEASUREMENT_DESCRIPTOR, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); + VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); } private static DistributionViewDescriptor createDistributionViewDescriptor( ViewDescriptor.Name name, - Measure measureDescr, + Measure measure, DistributionAggregationDescriptor aggDescr, List keys) { - return DistributionViewDescriptor.create(name, VIEW_DESCRIPTION, measureDescr, aggDescr, keys); + return DistributionViewDescriptor.create(name, VIEW_DESCRIPTION, measure, aggDescr, keys); } @Test public void testRegisterAndGetView() { - DistributionViewDescriptor viewDescr = createDistributionViewDescriptor(); - viewManager.registerView(viewDescr); - assertThat(viewManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(viewDescr); + DistributionViewDescriptor view = createDistributionViewDescriptor(); + viewManager.registerView(view); + assertThat(viewManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(view); } @Test @@ -104,7 +105,7 @@ public void preventRegisteringIntervalView() { IntervalViewDescriptor.create( VIEW_NAME, VIEW_DESCRIPTION, - MEASUREMENT_DESCRIPTOR, + MEASURE, IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(1000))), Arrays.asList(KEY)); thrown.expect(UnsupportedOperationException.class); @@ -112,20 +113,20 @@ public void preventRegisteringIntervalView() { } @Test - public void allowRegisteringSameViewDescriptorTwice() { - DistributionViewDescriptor viewDescr = createDistributionViewDescriptor(); - viewManager.registerView(viewDescr); - viewManager.registerView(viewDescr); - assertThat(viewManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(viewDescr); + public void allowRegisteringSameViewTwice() { + DistributionViewDescriptor view = createDistributionViewDescriptor(); + viewManager.registerView(view); + viewManager.registerView(view); + assertThat(viewManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(view); } @Test - public void preventRegisteringDifferentViewDescriptorWithSameName() { + public void preventRegisteringDifferentViewWithSameName() { ViewDescriptor view1 = DistributionViewDescriptor.create( VIEW_NAME, "View description.", - MEASUREMENT_DESCRIPTOR, + MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); viewManager.registerView(view1); @@ -133,7 +134,7 @@ public void preventRegisteringDifferentViewDescriptorWithSameName() { DistributionViewDescriptor.create( VIEW_NAME, "This is a different description.", - MEASUREMENT_DESCRIPTOR, + MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); try { @@ -146,32 +147,32 @@ public void preventRegisteringDifferentViewDescriptorWithSameName() { } @Test - public void disallowGettingNonexistentView() { + public void disallowGettingNonexistentViewData() { thrown.expect(IllegalArgumentException.class); viewManager.getView(VIEW_NAME); } @Test public void testRecord() { - DistributionViewDescriptor viewDescr = + DistributionViewDescriptor view = createDistributionViewDescriptor( VIEW_NAME, - MEASUREMENT_DESCRIPTOR, + MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 2)); - viewManager.registerView(viewDescr); + viewManager.registerView(view); StatsContextImpl tags = createContext(factory, KEY, VALUE); for (double val : Arrays.asList(10.0, 20.0, 30.0, 40.0)) { - statsRecorder.record(tags, MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, val).build()); + statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, val).build()); } clock.setTime(Timestamp.create(3, 4)); - DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); - assertThat(view.getViewDescriptor()).isEqualTo(viewDescr); - assertThat(view.getStart()).isEqualTo(Timestamp.create(1, 2)); - assertThat(view.getEnd()).isEqualTo(Timestamp.create(3, 4)); + DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); + assertThat(viewData.getViewDescriptor()).isEqualTo(view); + assertThat(viewData.getStart()).isEqualTo(Timestamp.create(1, 2)); + assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(3, 4)); assertDistributionAggregationsEquivalent( - view.getDistributionAggregations(), + viewData.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), @@ -181,35 +182,35 @@ public void testRecord() { @Test public void getViewDoesNotClearStats() { - DistributionViewDescriptor viewDescr = + DistributionViewDescriptor view = createDistributionViewDescriptor( VIEW_NAME, - MEASUREMENT_DESCRIPTOR, + MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(10, 0)); - viewManager.registerView(viewDescr); + viewManager.registerView(view); StatsContextImpl tags = createContext(factory, KEY, VALUE); - statsRecorder.record(tags, MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 0.1).build()); + statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.1).build()); clock.setTime(Timestamp.create(11, 0)); - DistributionView view1 = (DistributionView) viewManager.getView(VIEW_NAME); - assertThat(view1.getStart()).isEqualTo(Timestamp.create(10, 0)); - assertThat(view1.getEnd()).isEqualTo(Timestamp.create(11, 0)); + DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); + assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(10, 0)); + assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(11, 0)); assertDistributionAggregationsEquivalent( - view1.getDistributionAggregations(), + viewData1.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(0.1)))); - statsRecorder.record(tags, MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 0.2).build()); + statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.2).build()); clock.setTime(Timestamp.create(12, 0)); - DistributionView view2 = (DistributionView) viewManager.getView(VIEW_NAME); + DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME); // The second view should have the same start time as the first view, and it should include both // recorded values: - assertThat(view2.getStart()).isEqualTo(Timestamp.create(10, 0)); - assertThat(view2.getEnd()).isEqualTo(Timestamp.create(12, 0)); + assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(10, 0)); + assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(12, 0)); assertDistributionAggregationsEquivalent( - view2.getDistributionAggregations(), + viewData2.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), @@ -222,21 +223,21 @@ public void testRecordMultipleTagValues() { viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, - MEASUREMENT_DESCRIPTOR, + MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); statsRecorder.record( createContext(factory, KEY, VALUE), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 10.0).build()); + MeasureMap.builder().set(MEASURE, 10.0).build()); statsRecorder.record( createContext(factory, KEY, VALUE_2), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 30.0).build()); + MeasureMap.builder().set(MEASURE, 30.0).build()); statsRecorder.record( createContext(factory, KEY, VALUE_2), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 50.0).build()); - DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); + MeasureMap.builder().set(MEASURE, 50.0).build()); + DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( - view.getDistributionAggregations(), + viewData.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(10.0)), @@ -249,10 +250,10 @@ public void testRecordMultipleTagValues() { // This test checks that StatsRecorder.record(...) does not throw an exception when no views are // registered. @Test - public void allowRecordingWithoutRegisteringMatchingView() { + public void allowRecordingWithoutRegisteringMatchingViewData() { statsRecorder.record( createContext(factory, KEY, VALUE), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 10).build()); + MeasureMap.builder().set(MEASURE, 10).build()); } @Test @@ -260,20 +261,20 @@ public void testRecordWithEmptyStatsContext() { viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, - MEASUREMENT_DESCRIPTOR, + MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); // DEFAULT doesn't have tags, but the view has tag key "KEY". statsRecorder.record(factory.getDefault(), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 10.0).build()); - DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); + MeasureMap.builder().set(MEASURE, 10.0).build()); + DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( - view.getDistributionAggregations(), + viewData.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( - // Tag is missing for associated measurementValues, should use default tag value + // Tag is missing for associated measureValues, should use default tag value // "unknown/not set" - Arrays.asList(Tag.create(KEY, MutableView.UNKNOWN_TAG_VALUE)), + Arrays.asList(Tag.create(KEY, MutableViewData.UNKNOWN_TAG_VALUE)), BUCKET_BOUNDARIES, // Should record stats with default tag value: "KEY" : "unknown/not set". Arrays.asList(10.0)))); @@ -284,67 +285,67 @@ public void testRecordWithNonExistentMeasurementDescriptor() { viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, - Measure.MeasureDouble.create(MEASUREMENT_NAME, "measurement", MEASUREMENT_UNIT), + Measure.MeasureDouble.create(MEASURE_NAME, "measure", MEASURE_UNIT), DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); MeasureDouble measure2 = - Measure.MeasureDouble.create(MEASUREMENT_NAME_2, "measurement", MEASUREMENT_UNIT); + Measure.MeasureDouble.create(MEASURE_NAME_2, "measure", MEASURE_UNIT); statsRecorder.record(createContext(factory, KEY, VALUE), MeasureMap.builder().set(measure2, 10.0).build()); - DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); + DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); assertThat(view.getDistributionAggregations()).isEmpty(); } @Test - public void testRecordWithTagsThatDoNotMatchView() { + public void testRecordWithTagsThatDoNotMatchViewData() { viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, - MEASUREMENT_DESCRIPTOR, + MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY))); statsRecorder.record( createContext(factory, TagKey.create("wrong key"), VALUE), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 10.0).build()); + MeasureMap.builder().set(MEASURE, 10.0).build()); statsRecorder.record( createContext(factory, TagKey.create("another wrong key"), VALUE), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 50.0).build()); - DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); + MeasureMap.builder().set(MEASURE, 50.0).build()); + DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( view.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( // Won't record the unregistered tag key, will use default tag instead: // "KEY" : "unknown/not set". - Arrays.asList(Tag.create(KEY, MutableView.UNKNOWN_TAG_VALUE)), + Arrays.asList(Tag.create(KEY, MutableViewData.UNKNOWN_TAG_VALUE)), BUCKET_BOUNDARIES, // Should record stats with default tag value: "KEY" : "unknown/not set". Arrays.asList(10.0, 50.0)))); } @Test - public void testViewWithMultipleTagKeys() { + public void testViewDataWithMultipleTagKeys() { TagKey key1 = TagKey.create("Key-1"); TagKey key2 = TagKey.create("Key-2"); viewManager.registerView( createDistributionViewDescriptor( VIEW_NAME, - MEASUREMENT_DESCRIPTOR, + MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(key1, key2))); statsRecorder.record( createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 1.1).build()); + MeasureMap.builder().set(MEASURE, 1.1).build()); statsRecorder.record( createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v20")), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 2.2).build()); + MeasureMap.builder().set(MEASURE, 2.2).build()); statsRecorder.record( createContext(factory, key1, TagValue.create("v2"), key2, TagValue.create("v10")), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 3.3).build()); + MeasureMap.builder().set(MEASURE, 3.3).build()); statsRecorder.record( createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 4.4).build()); - DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); + MeasureMap.builder().set(MEASURE, 4.4).build()); + DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); assertDistributionAggregationsEquivalent( view.getDistributionAggregations(), Arrays.asList( @@ -369,98 +370,98 @@ public void testViewWithMultipleTagKeys() { } @Test - public void testMultipleViewsSameMeasure() { - ViewDescriptor viewDescr1 = + public void testMultipleViewDatasSameMeasure() { + ViewDescriptor view1 = createDistributionViewDescriptor( VIEW_NAME, - MEASUREMENT_DESCRIPTOR, + MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); - ViewDescriptor viewDescr2 = + ViewDescriptor view2 = createDistributionViewDescriptor( VIEW_NAME_2, - MEASUREMENT_DESCRIPTOR, + MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 1)); - viewManager.registerView(viewDescr1); + viewManager.registerView(view1); clock.setTime(Timestamp.create(2, 2)); - viewManager.registerView(viewDescr2); + viewManager.registerView(view2); statsRecorder.record( createContext(factory, KEY, VALUE), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 5.0).build()); + MeasureMap.builder().set(MEASURE, 5.0).build()); List expectedAggs = Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(5.0))); clock.setTime(Timestamp.create(3, 3)); - DistributionView view1 = (DistributionView) viewManager.getView(VIEW_NAME); + DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); clock.setTime(Timestamp.create(4, 4)); - DistributionView view2 = (DistributionView) viewManager.getView(VIEW_NAME_2); - assertThat(view1.getStart()).isEqualTo(Timestamp.create(1, 1)); - assertThat(view1.getEnd()).isEqualTo(Timestamp.create(3, 3)); - assertDistributionAggregationsEquivalent(view1.getDistributionAggregations(), expectedAggs); - assertThat(view2.getStart()).isEqualTo(Timestamp.create(2, 2)); - assertThat(view2.getEnd()).isEqualTo(Timestamp.create(4, 4)); - assertDistributionAggregationsEquivalent(view2.getDistributionAggregations(), expectedAggs); + DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME_2); + assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(1, 1)); + assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(3, 3)); + assertDistributionAggregationsEquivalent(viewData1.getDistributionAggregations(), expectedAggs); + assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(2, 2)); + assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(4, 4)); + assertDistributionAggregationsEquivalent(viewData2.getDistributionAggregations(), expectedAggs); } @Test public void testMultipleViewsDifferentMeasures() { - MeasureDouble measureDescr1 = - Measure.MeasureDouble.create(MEASUREMENT_NAME, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); - MeasureDouble measureDescr2 = - Measure.MeasureDouble.create(MEASUREMENT_NAME_2, MEASUREMENT_DESCRIPTION, MEASUREMENT_UNIT); - ViewDescriptor viewDescr1 = + MeasureDouble measure1 = + Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); + MeasureDouble measure2 = + Measure.MeasureDouble.create(MEASURE_NAME_2, MEASURE_DESCRIPTION, MEASURE_UNIT); + ViewDescriptor view1 = createDistributionViewDescriptor( - VIEW_NAME, measureDescr1, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); - ViewDescriptor viewDescr2 = + VIEW_NAME, measure1, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); + ViewDescriptor view2 = createDistributionViewDescriptor( - VIEW_NAME_2, measureDescr2, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); + VIEW_NAME_2, measure2, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); - viewManager.registerView(viewDescr1); + viewManager.registerView(view1); clock.setTime(Timestamp.create(2, 0)); - viewManager.registerView(viewDescr2); + viewManager.registerView(view2); statsRecorder.record( createContext(factory, KEY, VALUE), - MeasureMap.builder().set(measureDescr1, 1.1).set(measureDescr2, 2.2).build()); + MeasureMap.builder().set(measure1, 1.1).set(measure2, 2.2).build()); clock.setTime(Timestamp.create(3, 0)); - DistributionView view1 = (DistributionView) viewManager.getView(VIEW_NAME); + DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); clock.setTime(Timestamp.create(4, 0)); - DistributionView view2 = (DistributionView) viewManager.getView(VIEW_NAME_2); - assertThat(view1.getStart()).isEqualTo(Timestamp.create(1, 0)); - assertThat(view1.getEnd()).isEqualTo(Timestamp.create(3, 0)); + DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME_2); + assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(1, 0)); + assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(3, 0)); assertDistributionAggregationsEquivalent( - view1.getDistributionAggregations(), + viewData1.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(1.1)))); - assertThat(view2.getStart()).isEqualTo(Timestamp.create(2, 0)); - assertThat(view2.getEnd()).isEqualTo(Timestamp.create(4, 0)); + assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(2, 0)); + assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(4, 0)); assertDistributionAggregationsEquivalent( - view2.getDistributionAggregations(), + viewData2.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(2.2)))); } @Test - public void testGetDistributionViewWithoutBucketBoundaries() { - ViewDescriptor viewDescr = + public void testGetDistributionViewDataWithoutBucketBoundaries() { + ViewDescriptor view = createDistributionViewDescriptor( - VIEW_NAME, MEASUREMENT_DESCRIPTOR, DistributionAggregationDescriptor.create(), + VIEW_NAME, MEASURE, DistributionAggregationDescriptor.create(), Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); - viewManager.registerView(viewDescr); + viewManager.registerView(view); statsRecorder.record( createContext(factory, KEY, VALUE), - MeasureMap.builder().set(MEASUREMENT_DESCRIPTOR, 1.1).build()); + MeasureMap.builder().set(MEASURE, 1.1).build()); clock.setTime(Timestamp.create(3, 0)); - DistributionView view = (DistributionView) viewManager.getView(VIEW_NAME); - assertThat(view.getStart()).isEqualTo(Timestamp.create(1, 0)); - assertThat(view.getEnd()).isEqualTo(Timestamp.create(3, 0)); + DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); + assertThat(viewData.getStart()).isEqualTo(Timestamp.create(1, 0)); + assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(3, 0)); assertDistributionAggregationsEquivalent( - view.getDistributionAggregations(), + viewData.getDistributionAggregations(), Arrays.asList( StatsTestUtil.createDistributionAggregation( Arrays.asList(Tag.create(KEY, VALUE)), Arrays.asList(1.1)))); From 37d9bd8f9a46666b19533e11e706a64316e7ca8e Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 6 Jul 2017 15:23:41 -0700 Subject: [PATCH 0240/1581] Change SpanData to use span name instead of display name. (#423) --- .../io/opencensus/trace/export/SpanData.java | 12 +++++----- .../opencensus/trace/export/SpanDataTest.java | 24 +++++++++---------- .../opencensus/trace/SpanBuilderImplTest.java | 2 +- .../io/opencensus/trace/SpanImplTest.java | 4 ++-- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/export/SpanData.java b/api/src/main/java/io/opencensus/trace/export/SpanData.java index 762335af32..3bcf9e72b1 100644 --- a/api/src/main/java/io/opencensus/trace/export/SpanData.java +++ b/api/src/main/java/io/opencensus/trace/export/SpanData.java @@ -45,7 +45,7 @@ public abstract class SpanData { * @param parentSpanId the parent {@code SpanId} of the {@code Span}. {@code null} if the {@code * Span} is a root. * @param hasRemoteParent {@code true} if the parent is on a different process. - * @param displayName the name of the {@code Span}. + * @param name the name of the {@code Span}. * @param startTimestamp the start {@code Timestamp} of the {@code Span}. * @param attributes the attributes associated with the {@code Span}. * @param annotations the annotations associated with the {@code Span}. @@ -61,7 +61,7 @@ public static SpanData create( SpanContext context, @Nullable SpanId parentSpanId, boolean hasRemoteParent, - String displayName, + String name, Timestamp startTimestamp, Attributes attributes, TimedEvents annotations, @@ -73,7 +73,7 @@ public static SpanData create( context, parentSpanId, hasRemoteParent, - displayName, + name, startTimestamp, attributes, annotations, @@ -106,11 +106,11 @@ public static SpanData create( public abstract boolean getHasRemoteParent(); /** - * Returns the display name of this {@code Span}. + * Returns the name of this {@code Span}. * - * @return the display name of this {@code Span}. + * @return the name of this {@code Span}. */ - public abstract String getDisplayName(); + public abstract String getName(); /** * Returns the start {@code Timestamp} of this {@code Span}. diff --git a/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java index aeb99abfd4..9af4644616 100644 --- a/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java +++ b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java @@ -50,7 +50,7 @@ public class SpanDataTest { private static final Timestamp eventTimestamp2 = Timestamp.create(123, 458); private static final Timestamp eventTimestamp3 = Timestamp.create(123, 459); private static final Timestamp endTimestamp = Timestamp.create(123, 460); - private static final String DISPLAY_NAME = "MySpanDisplayName"; + private static final String SPAN_NAME = "MySpanName"; private static final String ANNOTATION_TEXT = "MyAnnotationText"; private static final Annotation annotation = Annotation.fromDescription(ANNOTATION_TEXT); private static final NetworkEvent recvNetworkEvent = @@ -96,7 +96,7 @@ public void spanData_AllValues() { spanContext, parentSpanId, true, - DISPLAY_NAME, + SPAN_NAME, startTimestamp, attributes, annotations, @@ -107,7 +107,7 @@ public void spanData_AllValues() { assertThat(spanData.getContext()).isEqualTo(spanContext); assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); assertThat(spanData.getHasRemoteParent()).isTrue(); - assertThat(spanData.getDisplayName()).isEqualTo(DISPLAY_NAME); + assertThat(spanData.getName()).isEqualTo(SPAN_NAME); assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); assertThat(spanData.getAttributes()).isEqualTo(attributes); assertThat(spanData.getAnnotations()).isEqualTo(annotations); @@ -124,7 +124,7 @@ public void spanData_RootActiveSpan() { spanContext, null, false, - DISPLAY_NAME, + SPAN_NAME, startTimestamp, attributes, annotations, @@ -135,7 +135,7 @@ public void spanData_RootActiveSpan() { assertThat(spanData.getContext()).isEqualTo(spanContext); assertThat(spanData.getParentSpanId()).isNull(); assertThat(spanData.getHasRemoteParent()).isFalse(); - assertThat(spanData.getDisplayName()).isEqualTo(DISPLAY_NAME); + assertThat(spanData.getName()).isEqualTo(SPAN_NAME); assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); assertThat(spanData.getAttributes()).isEqualTo(attributes); assertThat(spanData.getAnnotations()).isEqualTo(annotations); @@ -152,7 +152,7 @@ public void spanData_AllDataEmpty() { spanContext, parentSpanId, false, - DISPLAY_NAME, + SPAN_NAME, startTimestamp, Attributes.create(Collections.emptyMap(), 0), TimedEvents.create(Collections.>emptyList(), 0), @@ -163,7 +163,7 @@ public void spanData_AllDataEmpty() { assertThat(spanData.getContext()).isEqualTo(spanContext); assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); assertThat(spanData.getHasRemoteParent()).isFalse(); - assertThat(spanData.getDisplayName()).isEqualTo(DISPLAY_NAME); + assertThat(spanData.getName()).isEqualTo(SPAN_NAME); assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); assertThat(spanData.getAttributes().getAttributeMap().isEmpty()).isTrue(); assertThat(spanData.getAnnotations().getEvents().isEmpty()).isTrue(); @@ -180,7 +180,7 @@ public void spanDataEquals() { spanContext, parentSpanId, false, - DISPLAY_NAME, + SPAN_NAME, startTimestamp, attributes, annotations, @@ -193,7 +193,7 @@ public void spanDataEquals() { spanContext, parentSpanId, false, - DISPLAY_NAME, + SPAN_NAME, startTimestamp, attributes, annotations, @@ -206,7 +206,7 @@ public void spanDataEquals() { spanContext, parentSpanId, false, - DISPLAY_NAME, + SPAN_NAME, startTimestamp, Attributes.create(Collections.emptyMap(), 0), TimedEvents.create(Collections.>emptyList(), 0), @@ -227,7 +227,7 @@ public void spanData_ToString() { spanContext, parentSpanId, false, - DISPLAY_NAME, + SPAN_NAME, startTimestamp, attributes, annotations, @@ -238,7 +238,7 @@ public void spanData_ToString() { .toString(); assertThat(spanDataString).contains(spanContext.toString()); assertThat(spanDataString).contains(parentSpanId.toString()); - assertThat(spanDataString).contains(DISPLAY_NAME); + assertThat(spanDataString).contains(SPAN_NAME); assertThat(spanDataString).contains(startTimestamp.toString()); assertThat(spanDataString).contains(attributes.toString()); assertThat(spanDataString).contains(annotations.toString()); diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java index 5088e0e535..76d3dd751c 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java @@ -63,7 +63,7 @@ public void startSpanNullParent() { assertThat(spanData.getParentSpanId()).isNull(); assertThat(spanData.getHasRemoteParent()).isFalse(); assertThat(spanData.getStartTimestamp()).isEqualTo(testClock.now()); - assertThat(spanData.getDisplayName()).isEqualTo(SPAN_NAME); + assertThat(spanData.getName()).isEqualTo(SPAN_NAME); } @Test diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java index 6b74e5d19a..8651b35af5 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java @@ -148,7 +148,7 @@ public void toSpanData_ActiveSpan() { span.addLink(link); SpanData spanData = span.toSpanData(); assertThat(spanData.getContext()).isEqualTo(spanContext); - assertThat(spanData.getDisplayName()).isEqualTo(SPAN_NAME); + assertThat(spanData.getName()).isEqualTo(SPAN_NAME); assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); assertThat(spanData.getHasRemoteParent()).isTrue(); assertThat(spanData.getAttributes().getDroppedAttributesCount()).isEqualTo(0); @@ -206,7 +206,7 @@ public void toSpanData_EndedSpan() { Mockito.verify(startEndHandler, Mockito.times(1)).onEnd(span); SpanData spanData = span.toSpanData(); assertThat(spanData.getContext()).isEqualTo(spanContext); - assertThat(spanData.getDisplayName()).isEqualTo(SPAN_NAME); + assertThat(spanData.getName()).isEqualTo(SPAN_NAME); assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); assertThat(spanData.getHasRemoteParent()).isFalse(); assertThat(spanData.getAttributes().getDroppedAttributesCount()).isEqualTo(0); From 7b804712286908bf61f35e82da33dda17e01483f Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 6 Jul 2017 16:26:22 -0700 Subject: [PATCH 0241/1581] Add attributes to the Link to match with the data model. (#425) --- .../main/java/io/opencensus/trace/Link.java | 31 +++++++++++++- .../java/io/opencensus/trace/LinkTest.java | 40 +++++++++++++++++-- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/Link.java b/api/src/main/java/io/opencensus/trace/Link.java index 058bd8a961..deea40c1e8 100644 --- a/api/src/main/java/io/opencensus/trace/Link.java +++ b/api/src/main/java/io/opencensus/trace/Link.java @@ -14,6 +14,9 @@ package io.opencensus.trace; import com.google.auto.value.AutoValue; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import javax.annotation.concurrent.Immutable; /** @@ -28,6 +31,8 @@ @Immutable @AutoValue public abstract class Link { + private static final Map EMPTY_ATTRIBUTES = Collections.emptyMap(); + /** The relationship with the linked {@code Span} relative to the current {@code Span}. */ public enum Type { /** When the linked {@code Span} is a child of the current {@code Span}. */ @@ -44,7 +49,24 @@ public enum Type { * @return a new {@code Link}. */ public static Link fromSpanContext(SpanContext context, Type type) { - return new AutoValue_Link(context.getTraceId(), context.getSpanId(), type); + return new AutoValue_Link(context.getTraceId(), context.getSpanId(), type, EMPTY_ATTRIBUTES); + } + + /** + * Returns a new {@code Link}. + * + * @param context the context of the linked {@code Span}. + * @param type the type of the relationship with the linked {@code Span}. + * @param attributes the attributes of the {@code Link}. + * @return a new {@code Link}. + */ + public static Link fromSpanContext( + SpanContext context, Type type, Map attributes) { + return new AutoValue_Link( + context.getTraceId(), + context.getSpanId(), + type, + Collections.unmodifiableMap(new HashMap(attributes))); } /** @@ -68,5 +90,12 @@ public static Link fromSpanContext(SpanContext context, Type type) { */ public abstract Type getType(); + /** + * Returns the set of attributes. + * + * @return the set of attributes. + */ + public abstract Map getAttributes(); + Link() {} } diff --git a/api/src/test/java/io/opencensus/trace/LinkTest.java b/api/src/test/java/io/opencensus/trace/LinkTest.java index e6b4afe57b..d0d7a1477b 100644 --- a/api/src/test/java/io/opencensus/trace/LinkTest.java +++ b/api/src/test/java/io/opencensus/trace/LinkTest.java @@ -17,7 +17,10 @@ import com.google.common.testing.EqualsTester; import io.opencensus.trace.Link.Type; +import java.util.HashMap; +import java.util.Map; import java.util.Random; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -25,11 +28,19 @@ /** Unit tests for {@link Link}. */ @RunWith(JUnit4.class) public class LinkTest { + private final Map attributesMap = new HashMap(); private final Random random = new Random(1234); private final SpanContext spanContext = SpanContext.create( TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); + @Before + public void setUp() { + attributesMap.put("MyAttributeKey0", AttributeValue.stringAttributeValue("MyStringAttribute")); + attributesMap.put("MyAttributeKey1", AttributeValue.longAttributeValue(10)); + attributesMap.put("MyAttributeKey2", AttributeValue.booleanAttributeValue(true)); + } + @Test public void fromSpanContext_ChildLink() { Link link = Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN); @@ -38,6 +49,15 @@ public void fromSpanContext_ChildLink() { assertThat(link.getType()).isEqualTo(Type.CHILD_LINKED_SPAN); } + @Test + public void fromSpanContext_ChildLink_WithAttributes() { + Link link = Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN, attributesMap); + assertThat(link.getTraceId()).isEqualTo(spanContext.getTraceId()); + assertThat(link.getSpanId()).isEqualTo(spanContext.getSpanId()); + assertThat(link.getType()).isEqualTo(Type.CHILD_LINKED_SPAN); + assertThat(link.getAttributes()).isEqualTo(attributesMap); + } + @Test public void fromSpanContext_ParentLink() { Link link = Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN); @@ -46,6 +66,15 @@ public void fromSpanContext_ParentLink() { assertThat(link.getType()).isEqualTo(Type.PARENT_LINKED_SPAN); } + @Test + public void fromSpanContext_ParentLink_WithAttributes() { + Link link = Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN, attributesMap); + assertThat(link.getTraceId()).isEqualTo(spanContext.getTraceId()); + assertThat(link.getSpanId()).isEqualTo(spanContext.getSpanId()); + assertThat(link.getType()).isEqualTo(Type.PARENT_LINKED_SPAN); + assertThat(link.getAttributes()).isEqualTo(attributesMap); + } + @Test public void link_EqualsAndHashCode() { EqualsTester tester = new EqualsTester(); @@ -57,19 +86,24 @@ public void link_EqualsAndHashCode() { Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN), Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN)) .addEqualityGroup(Link.fromSpanContext(SpanContext.INVALID, Type.CHILD_LINKED_SPAN)) - .addEqualityGroup(Link.fromSpanContext(SpanContext.INVALID, Type.PARENT_LINKED_SPAN)); + .addEqualityGroup(Link.fromSpanContext(SpanContext.INVALID, Type.PARENT_LINKED_SPAN)) + .addEqualityGroup( + Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN, attributesMap), + Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN, attributesMap)); tester.testEquals(); } @Test public void link_ToString() { - Link link = Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN); + Link link = Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN, attributesMap); assertThat(link.toString()).contains(spanContext.getTraceId().toString()); assertThat(link.toString()).contains(spanContext.getSpanId().toString()); assertThat(link.toString()).contains("CHILD_LINKED_SPAN"); - link = Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN); + assertThat(link.toString()).contains(attributesMap.toString()); + link = Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN, attributesMap); assertThat(link.toString()).contains(spanContext.getTraceId().toString()); assertThat(link.toString()).contains(spanContext.getSpanId().toString()); assertThat(link.toString()).contains("PARENT_LINKED_SPAN"); + assertThat(link.toString()).contains(attributesMap.toString()); } } From 185230ae8051ee82b0ee273a53d065980e7ba341 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 6 Jul 2017 18:02:35 -0700 Subject: [PATCH 0242/1581] Add an optional number of child spans that were generated while this span was running. (#426) --- .../java/io/opencensus/trace/export/SpanData.java | 14 ++++++++++++++ .../io/opencensus/trace/export/SpanDataTest.java | 13 ++++++++++++- .../main/java/io/opencensus/trace/SpanImpl.java | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/io/opencensus/trace/export/SpanData.java b/api/src/main/java/io/opencensus/trace/export/SpanData.java index 3bcf9e72b1..b4d5d5c70b 100644 --- a/api/src/main/java/io/opencensus/trace/export/SpanData.java +++ b/api/src/main/java/io/opencensus/trace/export/SpanData.java @@ -51,6 +51,7 @@ public abstract class SpanData { * @param annotations the annotations associated with the {@code Span}. * @param networkEvents the network events associated with the {@code Span}. * @param links the links associated with the {@code Span}. + * @param childSpanCount the number of child spans that were generated while the span was active. * @param status the {@code Status} of the {@code Span}. {@code null} if the {@code Span} is still * active. * @param endTimestamp the end {@code Timestamp} of the {@code Span}. {@code null} if the {@code @@ -67,6 +68,7 @@ public static SpanData create( TimedEvents annotations, TimedEvents networkEvents, Links links, + @Nullable Integer childSpanCount, @Nullable Status status, @Nullable Timestamp endTimestamp) { return new AutoValue_SpanData( @@ -79,6 +81,7 @@ public static SpanData create( annotations, networkEvents, links, + childSpanCount, status, endTimestamp); } @@ -147,6 +150,17 @@ public static SpanData create( */ public abstract Links getLinks(); + /** + * Returns the number of child spans that were generated while the {@code Span} was running. If + * not {@code null} allows service implementations to detect missing child spans. + * + *

            This information is not always available. + * + * @return the number of child spans that were generated while the {@code Span} was running. + */ + @Nullable + public abstract Integer getChildSpanCount(); + /** * Returns the {@code Status} or {@code null} if {@code Span} is still active. * diff --git a/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java index 9af4644616..8212d4b9a5 100644 --- a/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java +++ b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java @@ -58,6 +58,7 @@ public class SpanDataTest { private static final NetworkEvent sentNetworkEvent = NetworkEvent.builder(NetworkEvent.Type.SENT, 1).build(); private static final Status status = Status.DEADLINE_EXCEEDED.withDescription("TooSlow"); + private static final int CHILD_SPAN_COUNT = 13; private final Random random = new Random(1234); private final SpanContext spanContext = SpanContext.create( @@ -102,6 +103,7 @@ public void spanData_AllValues() { annotations, networkEvents, links, + CHILD_SPAN_COUNT, status, endTimestamp); assertThat(spanData.getContext()).isEqualTo(spanContext); @@ -113,6 +115,7 @@ public void spanData_AllValues() { assertThat(spanData.getAnnotations()).isEqualTo(annotations); assertThat(spanData.getNetworkEvents()).isEqualTo(networkEvents); assertThat(spanData.getLinks()).isEqualTo(links); + assertThat(spanData.getChildSpanCount()).isEqualTo(CHILD_SPAN_COUNT); assertThat(spanData.getStatus()).isEqualTo(status); assertThat(spanData.getEndTimestamp()).isEqualTo(endTimestamp); } @@ -131,6 +134,7 @@ public void spanData_RootActiveSpan() { networkEvents, links, null, + null, null); assertThat(spanData.getContext()).isEqualTo(spanContext); assertThat(spanData.getParentSpanId()).isNull(); @@ -141,6 +145,7 @@ public void spanData_RootActiveSpan() { assertThat(spanData.getAnnotations()).isEqualTo(annotations); assertThat(spanData.getNetworkEvents()).isEqualTo(networkEvents); assertThat(spanData.getLinks()).isEqualTo(links); + assertThat(spanData.getChildSpanCount()).isNull(); assertThat(spanData.getStatus()).isNull(); assertThat(spanData.getEndTimestamp()).isNull(); } @@ -158,6 +163,7 @@ public void spanData_AllDataEmpty() { TimedEvents.create(Collections.>emptyList(), 0), TimedEvents.create(Collections.>emptyList(), 0), Links.create(Collections.emptyList(), 0), + 0, status, endTimestamp); assertThat(spanData.getContext()).isEqualTo(spanContext); @@ -169,6 +175,7 @@ public void spanData_AllDataEmpty() { assertThat(spanData.getAnnotations().getEvents().isEmpty()).isTrue(); assertThat(spanData.getNetworkEvents().getEvents().isEmpty()).isTrue(); assertThat(spanData.getLinks().getLinks().isEmpty()).isTrue(); + assertThat(spanData.getChildSpanCount()).isEqualTo(0); assertThat(spanData.getStatus()).isEqualTo(status); assertThat(spanData.getEndTimestamp()).isEqualTo(endTimestamp); } @@ -186,6 +193,7 @@ public void spanDataEquals() { annotations, networkEvents, links, + CHILD_SPAN_COUNT, status, endTimestamp); SpanData allSpanData2 = @@ -199,6 +207,7 @@ public void spanDataEquals() { annotations, networkEvents, links, + CHILD_SPAN_COUNT, status, endTimestamp); SpanData emptySpanData = @@ -212,6 +221,7 @@ public void spanDataEquals() { TimedEvents.create(Collections.>emptyList(), 0), TimedEvents.create(Collections.>emptyList(), 0), Links.create(Collections.emptyList(), 0), + 0, status, endTimestamp); new EqualsTester() @@ -227,12 +237,13 @@ public void spanData_ToString() { spanContext, parentSpanId, false, - SPAN_NAME, + SPAN_NAME, startTimestamp, attributes, annotations, networkEvents, links, + CHILD_SPAN_COUNT, status, endTimestamp) .toString(); diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java index c2c6489def..e32f0c90a4 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java @@ -220,6 +220,7 @@ public SpanData toSpanData() { annotationsSpanData, networkEventsSpanData, linksSpanData, + null, // Not supported yet. hasBeenEnded ? status : null, hasBeenEnded ? timestampConverter.convertNanoTime(endNanoTime) : null); } From 0ff88c033b29a14e4d828ccdd5611e240a13c393 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Thu, 6 Jul 2017 18:16:57 -0700 Subject: [PATCH 0243/1581] Refactor ViewDescriptor. (#424) --- .../io/opencensus/stats/RpcViewConstants.java | 176 +++++++++--------- .../stats/{ViewDescriptor.java => View.java} | 72 +++---- .../java/io/opencensus/stats/ViewData.java | 18 +- .../java/io/opencensus/stats/ViewManager.java | 12 +- .../io/opencensus/stats/ViewDataTest.java | 28 +-- ...{ViewDescriptorTest.java => ViewTest.java} | 123 ++++++------ .../io/opencensus/stats/MeasureToViewMap.java | 34 ++-- .../io/opencensus/stats/MutableViewData.java | 24 +-- .../io/opencensus/stats/StatsManager.java | 8 +- .../io/opencensus/stats/ViewManagerImpl.java | 8 +- .../stats/MeasureToViewMapTest.java | 10 +- .../io/opencensus/stats/StatsContextTest.java | 2 +- .../opencensus/stats/ViewManagerImplTest.java | 80 ++++---- 13 files changed, 295 insertions(+), 300 deletions(-) rename core/src/main/java/io/opencensus/stats/{ViewDescriptor.java => View.java} (66%) rename core/src/test/java/io/opencensus/stats/{ViewDescriptorTest.java => ViewTest.java} (50%) diff --git a/core/src/main/java/io/opencensus/stats/RpcViewConstants.java b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java index 812629a5d5..db518c1e6e 100644 --- a/core/src/main/java/io/opencensus/stats/RpcViewConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java @@ -40,8 +40,8 @@ import static io.opencensus.stats.RpcMeasureConstants.RPC_STATUS; import io.opencensus.common.Duration; -import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; -import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.View.IntervalView; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -51,76 +51,76 @@ */ public final class RpcViewConstants { - // Common histogram bucket boundaries for bytes received/sets DistributionViewDescriptors. + // Common histogram bucket boundaries for bytes received/sets DistributionViews. static final List RPC_BYTES_BUCKET_BOUNDARIES = Collections.unmodifiableList( Arrays.asList(0.0, 1024.0, 2048.0, 4096.0, 16384.0, 65536.0, 262144.0, 1048576.0, 4194304.0, 16777216.0, 67108864.0, 268435456.0, 1073741824.0, 4294967296.0)); - // Common histogram bucket boundaries for latency and elapsed-time DistributionViewDescriptors. + // Common histogram bucket boundaries for latency and elapsed-time DistributionViews. static final List RPC_MILLIS_BUCKET_BOUNDARIES = Collections.unmodifiableList( Arrays.asList(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 13.0, 16.0, 20.0, 25.0, 30.0, 40.0, 50.0, 65.0, 80.0, 100.0, 130.0, 160.0, 200.0, 250.0, 300.0, 400.0, 500.0, 650.0, 800.0, 1000.0, 2000.0, 5000.0, 10000.0, 20000.0, 50000.0, 100000.0)); - // Rpc client {@link ViewDescriptor}s. - public static final DistributionViewDescriptor RPC_CLIENT_ERROR_COUNT_VIEW = - DistributionViewDescriptor.create( + // Rpc client {@link View}s. + public static final DistributionView RPC_CLIENT_ERROR_COUNT_VIEW = + DistributionView.create( "grpc.io/client/error_count/distribution_cumulative", "RPC Errors", RPC_CLIENT_ERROR_COUNT, DistributionAggregationDescriptor.create(), Arrays.asList(RPC_STATUS, RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW = + DistributionView.create( "grpc.io/client/roundtrip_latency/distribution_cumulative", "Latency in msecs", RPC_CLIENT_ROUNDTRIP_LATENCY, DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_SERVER_ELAPSED_TIME_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_CLIENT_SERVER_ELAPSED_TIME_VIEW = + DistributionView.create( "grpc.io/client/server_elapsed_time/distribution_cumulative", "Server elapsed time in msecs", RPC_CLIENT_SERVER_ELAPSED_TIME, DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_REQUEST_BYTES_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_CLIENT_REQUEST_BYTES_VIEW = + DistributionView.create( "grpc.io/client/request_bytes/distribution_cumulative", "Request bytes", RPC_CLIENT_REQUEST_BYTES, DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_RESPONSE_BYTES_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_CLIENT_RESPONSE_BYTES_VIEW = + DistributionView.create( "grpc.io/client/response_bytes/distribution_cumulative", "Response bytes", RPC_CLIENT_RESPONSE_BYTES, DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_VIEW = + DistributionView.create( "grpc.io/client/uncompressed_request_bytes/distribution_cumulative", "Uncompressed Request bytes", RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_VIEW = + DistributionView.create( "grpc.io/client/uncompressed_response_bytes/distribution_cumulative", "Uncompressed Response bytes", RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_REQUEST_COUNT_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_CLIENT_REQUEST_COUNT_VIEW = + DistributionView.create( "grpc.io/client/request_count/distribution_cumulative", "Count of request messages per client RPC", RPC_CLIENT_REQUEST_COUNT, DistributionAggregationDescriptor.create(), Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionViewDescriptor RPC_CLIENT_RESPONSE_COUNT_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_CLIENT_RESPONSE_COUNT_VIEW = + DistributionView.create( "grpc.io/client/response_count/distribution_cumulative", "Count of response messages per client RPC", RPC_CLIENT_RESPONSE_COUNT, @@ -128,65 +128,65 @@ public final class RpcViewConstants { Arrays.asList(RPC_CLIENT_METHOD)); - // Rpc server {@link ViewDescriptor}s. - public static final DistributionViewDescriptor RPC_SERVER_ERROR_COUNT_VIEW = - DistributionViewDescriptor.create( + // Rpc server {@link View}s. + public static final DistributionView RPC_SERVER_ERROR_COUNT_VIEW = + DistributionView.create( "grpc.io/server/error_count/distribution_cumulative", "RPC Errors", RPC_SERVER_ERROR_COUNT, DistributionAggregationDescriptor.create(), Arrays.asList(RPC_STATUS, RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_SERVER_LATENCY_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_SERVER_SERVER_LATENCY_VIEW = + DistributionView.create( "grpc.io/server/server_latency/distribution_cumulative", "Latency in msecs", RPC_SERVER_SERVER_LATENCY, DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_SERVER_ELAPSED_TIME_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_SERVER_SERVER_ELAPSED_TIME_VIEW = + DistributionView.create( "grpc.io/server/elapsed_time/distribution_cumulative", "Server elapsed time in msecs", RPC_SERVER_SERVER_ELAPSED_TIME, DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_REQUEST_BYTES_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_SERVER_REQUEST_BYTES_VIEW = + DistributionView.create( "grpc.io/server/request_bytes/distribution_cumulative", "Request bytes", RPC_SERVER_REQUEST_BYTES, DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_RESPONSE_BYTES_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_SERVER_RESPONSE_BYTES_VIEW = + DistributionView.create( "grpc.io/server/response_bytes/distribution_cumulative", "Response bytes", RPC_SERVER_RESPONSE_BYTES, DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_VIEW = + DistributionView.create( "grpc.io/server/uncompressed_request_bytes/distribution_cumulative", "Uncompressed Request bytes", RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_VIEW = + DistributionView.create( "grpc.io/server/uncompressed_response_bytes/distribution_cumulative", "Uncompressed Response bytes", RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_REQUEST_COUNT_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_SERVER_REQUEST_COUNT_VIEW = + DistributionView.create( "grpc.io/server/request_count/distribution_cumulative", "Count of request messages per server RPC", RPC_SERVER_REQUEST_COUNT, DistributionAggregationDescriptor.create(), Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionViewDescriptor RPC_SERVER_RESPONSE_COUNT_VIEW = - DistributionViewDescriptor.create( + public static final DistributionView RPC_SERVER_RESPONSE_COUNT_VIEW = + DistributionView.create( "grpc.io/server/response_count/distribution_cumulative", "Count of response messages per server RPC", RPC_SERVER_RESPONSE_COUNT, @@ -197,178 +197,178 @@ public final class RpcViewConstants { static final Duration MINUTE = Duration.create(60, 0); static final Duration HOUR = Duration.create(60 * 60, 0); - // RPC client {@link IntervalViewDescriptor}s. - public static final IntervalViewDescriptor RPC_CLIENT_ROUNDTRIP_LATENCY_INTERVAL_VIEW = - IntervalViewDescriptor.create( + // RPC client {@link IntervalView}s. + public static final IntervalView RPC_CLIENT_ROUNDTRIP_LATENCY_INTERVAL_VIEW = + IntervalView.create( "grpc.io/client/roundtrip_latency/interval", "Minute and Hour stats for latency in msecs", RPC_CLIENT_ROUNDTRIP_LATENCY, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); - public static final IntervalViewDescriptor RPC_CLIENT_REQUEST_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_CLIENT_REQUEST_BYTES_INTERVAL_VIEW = + IntervalView.create( "grpc.io/client/request_bytes/interval", "Minute and Hour stats for request size in bytes", RPC_CLIENT_REQUEST_BYTES, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); - public static final IntervalViewDescriptor RPC_CLIENT_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_CLIENT_RESPONSE_BYTES_INTERVAL_VIEW = + IntervalView.create( "grpc.io/client/response_bytes/interval", "Minute and Hour stats for response size in bytes", RPC_CLIENT_RESPONSE_BYTES, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); - public static final IntervalViewDescriptor RPC_CLIENT_ERROR_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_CLIENT_ERROR_COUNT_INTERVAL_VIEW = + IntervalView.create( "grpc.io/client/error_count/interval", "Minute and Hour stats for rpc errors", RPC_CLIENT_ERROR_COUNT, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); - public static final IntervalViewDescriptor RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = + IntervalView.create( "grpc.io/client/uncompressed_request_bytes/interval", "Minute and Hour stats for uncompressed request size in bytes", RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); - public static final IntervalViewDescriptor RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = + IntervalView.create( "grpc.io/client/uncompressed_response_bytes/interval", "Minute and Hour stats for uncompressed response size in bytes", RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); - public static final IntervalViewDescriptor RPC_CLIENT_SERVER_ELAPSED_TIME_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_CLIENT_SERVER_ELAPSED_TIME_INTERVAL_VIEW = + IntervalView.create( "grpc.io/client/server_elapsed_time/interval", "Minute and Hour stats for server elapsed time in msecs", RPC_CLIENT_SERVER_ELAPSED_TIME, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); - public static final IntervalViewDescriptor RPC_CLIENT_STARTED_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_CLIENT_STARTED_COUNT_INTERVAL_VIEW = + IntervalView.create( "grpc.io/client/started_count/interval", "Minute and Hour stats on the number of client RPCs started", RPC_CLIENT_STARTED_COUNT, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); - public static final IntervalViewDescriptor RPC_CLIENT_FINISHED_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_CLIENT_FINISHED_COUNT_INTERVAL_VIEW = + IntervalView.create( "grpc.io/client/finished_count/interval", "Minute and Hour stats on the number of client RPCs finished", RPC_CLIENT_FINISHED_COUNT, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); - public static final IntervalViewDescriptor RPC_CLIENT_REQUEST_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_CLIENT_REQUEST_COUNT_INTERVAL_VIEW = + IntervalView.create( "grpc.io/client/request_count/interval", "Minute and Hour stats on the count of request messages per client RPC", RPC_CLIENT_REQUEST_COUNT, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); - public static final IntervalViewDescriptor RPC_CLIENT_RESPONSE_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_CLIENT_RESPONSE_COUNT_INTERVAL_VIEW = + IntervalView.create( "grpc.io/client/response_count/interval", "Minute and Hour stats on the count of response messages per client RPC", RPC_CLIENT_RESPONSE_COUNT, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); - // RPC server {@link IntervalViewDescriptor}s. - public static final IntervalViewDescriptor RPC_SERVER_SERVER_LATENCY_INTERVAL_VIEW = - IntervalViewDescriptor.create( + // RPC server {@link IntervalView}s. + public static final IntervalView RPC_SERVER_SERVER_LATENCY_INTERVAL_VIEW = + IntervalView.create( "grpc.io/server/server_latency/interval", "Minute and Hour stats for server latency in msecs", RPC_SERVER_SERVER_LATENCY, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); - public static final IntervalViewDescriptor RPC_SERVER_REQUEST_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_SERVER_REQUEST_BYTES_INTERVAL_VIEW = + IntervalView.create( "grpc.io/server/request_bytes/interval", "Minute and Hour stats for request size in bytes", RPC_SERVER_REQUEST_BYTES, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); - public static final IntervalViewDescriptor RPC_SERVER_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_SERVER_RESPONSE_BYTES_INTERVAL_VIEW = + IntervalView.create( "grpc.io/server/response_bytes/interval", "Minute and Hour stats for response size in bytes", RPC_SERVER_RESPONSE_BYTES, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); - public static final IntervalViewDescriptor RPC_SERVER_ERROR_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_SERVER_ERROR_COUNT_INTERVAL_VIEW = + IntervalView.create( "grpc.io/server/error_count/interval", "Minute and Hour stats for rpc errors", RPC_SERVER_ERROR_COUNT, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); - public static final IntervalViewDescriptor RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = + IntervalView.create( "grpc.io/server/uncompressed_request_bytes/interval", "Minute and Hour stats for uncompressed request size in bytes", RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); - public static final IntervalViewDescriptor RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = + IntervalView.create( "grpc.io/server/uncompressed_response_bytes/interval", "Minute and Hour stats for uncompressed response size in bytes", RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); - public static final IntervalViewDescriptor RPC_SERVER_SERVER_ELAPSED_TIME_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_SERVER_SERVER_ELAPSED_TIME_INTERVAL_VIEW = + IntervalView.create( "grpc.io/server/server_elapsed_time/interval", "Minute and Hour stats for server elapsed time in msecs", RPC_SERVER_SERVER_ELAPSED_TIME, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); - public static final IntervalViewDescriptor RPC_SERVER_STARTED_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_SERVER_STARTED_COUNT_INTERVAL_VIEW = + IntervalView.create( "grpc.io/server/started_count/interval", "Minute and Hour stats on the number of server RPCs started", RPC_SERVER_STARTED_COUNT, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); - public static final IntervalViewDescriptor RPC_SERVER_FINISHED_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_SERVER_FINISHED_COUNT_INTERVAL_VIEW = + IntervalView.create( "grpc.io/server/finished_count/interval", "Minute and Hour stats on the number of server RPCs finished", RPC_SERVER_FINISHED_COUNT, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); - public static final IntervalViewDescriptor RPC_SERVER_REQUEST_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_SERVER_REQUEST_COUNT_INTERVAL_VIEW = + IntervalView.create( "grpc.io/server/request_count/interval", "Minute and Hour stats on the count of request messages per server RPC", RPC_SERVER_REQUEST_COUNT, IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); - public static final IntervalViewDescriptor RPC_SERVER_RESPONSE_COUNT_INTERVAL_VIEW = - IntervalViewDescriptor.create( + public static final IntervalView RPC_SERVER_RESPONSE_COUNT_INTERVAL_VIEW = + IntervalView.create( "grpc.io/server/response_count/interval", "Minute and Hour stats on the count of response messages per server RPC", RPC_SERVER_RESPONSE_COUNT, diff --git a/core/src/main/java/io/opencensus/stats/ViewDescriptor.java b/core/src/main/java/io/opencensus/stats/View.java similarity index 66% rename from core/src/main/java/io/opencensus/stats/ViewDescriptor.java rename to core/src/main/java/io/opencensus/stats/View.java index 22859ce6f1..1a431ac13b 100644 --- a/core/src/main/java/io/opencensus/stats/ViewDescriptor.java +++ b/core/src/main/java/io/opencensus/stats/View.java @@ -21,21 +21,21 @@ import javax.annotation.concurrent.Immutable; /** - * A ViewDescriptor specifies an aggregation and a set of tag keys. The aggregation will be broken - * down by the unique set of matching tag values for each measurement. + * A View specifies an aggregation and a set of tag keys. The aggregation will be broken + * down by the unique set of matching tag values for each measure. */ @Immutable -public abstract class ViewDescriptor { +public abstract class View { /** * Name of view. Must be unique. */ - public abstract Name getViewDescriptorName(); + public abstract Name getViewName(); /** * Name of view, as a {@code String}. */ public final String getName() { - return getViewDescriptorName().asString(); + return getViewName().asString(); } /** @@ -44,30 +44,30 @@ public final String getName() { public abstract String getDescription(); /** - * Measurement type of this view. + * Measure type of this view. */ public abstract Measure getMeasure(); /** - * Tag keys to match with the associated {@link Measure}. If no keys are specified, - * then all stats are recorded. Keys must be unique. + * Dimensions (a.k.a Tag Keys) to match with the associated {@link Measure}. + * If no dimensions are specified, then all stats are recorded. Dimensions must be unique. * *

            Note: The returned list is unmodifiable, attempts to update it will throw an * UnsupportedOperationException. */ - public abstract List getTagKeys(); + public abstract List getDimensions(); /** * Applies the given match function to the underlying data type. */ public abstract T match( - Function p0, - Function p1); + Function p0, + Function p1); /** - * The name of a {@code ViewDescriptor}. + * The name of a {@code View}. */ - // This type should be used as the key when associating data with ViewDescriptors. + // This type should be used as the key when associating data with Views. @Immutable @AutoValue public abstract static class Name { @@ -82,26 +82,26 @@ public abstract static class Name { public abstract String asString(); /** - * Creates a {@code ViewDescriptor.Name} from a {@code String}. + * Creates a {@code View.Name} from a {@code String}. * * @param name the name {@code String}. - * @return a {@code ViewDescriptor.Name} with the given name {@code String}. + * @return a {@code View.Name} with the given name {@code String}. */ public static Name create(String name) { - return new AutoValue_ViewDescriptor_Name(name); + return new AutoValue_View_Name(name); } } /** - * A {@link ViewDescriptor} for distribution-base aggregations. + * A {@link View} for distribution-base aggregations. */ @Immutable @AutoValue - public abstract static class DistributionViewDescriptor extends ViewDescriptor { + public abstract static class DistributionView extends View { /** - * Constructs a new {@link DistributionViewDescriptor}. + * Constructs a new {@link DistributionView}. */ - public static DistributionViewDescriptor create( + public static DistributionView create( String name, String description, Measure measure, @@ -116,15 +116,15 @@ public static DistributionViewDescriptor create( } /** - * Constructs a new {@link DistributionViewDescriptor}. + * Constructs a new {@link DistributionView}. */ - public static DistributionViewDescriptor create( + public static DistributionView create( Name name, String description, Measure measure, DistributionAggregationDescriptor distributionAggregationDescriptor, List tagKeys) { - return new AutoValue_ViewDescriptor_DistributionViewDescriptor( + return new AutoValue_View_DistributionView( name, description, measure, @@ -134,28 +134,28 @@ public static DistributionViewDescriptor create( /** * The {@link DistributionAggregationDescriptor} associated with this - * {@link DistributionViewDescriptor}. + * {@link DistributionView}. */ public abstract DistributionAggregationDescriptor getDistributionAggregationDescriptor(); @Override public T match( - Function p0, - Function p1) { + Function p0, + Function p1) { return p0.apply(this); } } /** - * A {@link ViewDescriptor} for interval-based aggregations. + * A {@link View} for interval-based aggregations. */ @Immutable @AutoValue - public abstract static class IntervalViewDescriptor extends ViewDescriptor { + public abstract static class IntervalView extends View { /** - * Constructs a new {@link IntervalViewDescriptor}. + * Constructs a new {@link IntervalView}. */ - public static IntervalViewDescriptor create( + public static IntervalView create( String name, String description, Measure measure, @@ -170,15 +170,15 @@ public static IntervalViewDescriptor create( } /** - * Constructs a new {@link IntervalViewDescriptor}. + * Constructs a new {@link IntervalView}. */ - public static IntervalViewDescriptor create( + public static IntervalView create( Name name, String description, Measure measure, IntervalAggregationDescriptor intervalAggregationDescriptor, List tagKeys) { - return new AutoValue_ViewDescriptor_IntervalViewDescriptor( + return new AutoValue_View_IntervalView( name, description, measure, @@ -188,14 +188,14 @@ public static IntervalViewDescriptor create( /** * The {@link IntervalAggregationDescriptor} associated with this - * {@link IntervalViewDescriptor}. + * {@link IntervalView}. */ public abstract IntervalAggregationDescriptor getIntervalAggregationDescriptor(); @Override public T match( - Function p0, - Function p1) { + Function p0, + Function p1) { return p1.apply(this); } } diff --git a/core/src/main/java/io/opencensus/stats/ViewData.java b/core/src/main/java/io/opencensus/stats/ViewData.java index 686e8914bc..7e885324f6 100644 --- a/core/src/main/java/io/opencensus/stats/ViewData.java +++ b/core/src/main/java/io/opencensus/stats/ViewData.java @@ -16,22 +16,22 @@ import com.google.auto.value.AutoValue; import io.opencensus.common.Function; import io.opencensus.common.Timestamp; -import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; -import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.View.IntervalView; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.annotation.concurrent.Immutable; /** - * The aggregated data for a particular {@link ViewDescriptor}. + * The aggregated data for a particular {@link View}. */ @Immutable public abstract class ViewData { /** - * The {@link ViewDescriptor} associated with this {@link ViewData}. + * The {@link View} associated with this {@link ViewData}. */ - public abstract ViewDescriptor getViewDescriptor(); + public abstract View getView(); /** * Applies the given match function to the underlying data type. @@ -53,7 +53,7 @@ public abstract static class DistributionViewData extends ViewData { /** * Constructs a new {@link DistributionViewData}. */ - public static DistributionViewData create(DistributionViewDescriptor distributionView, + public static DistributionViewData create(DistributionView distributionView, List distributionAggregations, Timestamp start, Timestamp end) { return new AutoValue_ViewData_DistributionViewData( distributionView, @@ -64,7 +64,7 @@ public static DistributionViewData create(DistributionViewDescriptor distributio } @Override - public abstract DistributionViewDescriptor getViewDescriptor(); + public abstract DistributionView getView(); /** * The {@link DistributionAggregation}s associated with this {@link DistributionViewData}. @@ -101,7 +101,7 @@ public abstract static class IntervalViewData extends ViewData { /** * Constructs a new {@link IntervalViewData}. */ - public static IntervalViewData create(IntervalViewDescriptor intervalView, + public static IntervalViewData create(IntervalView intervalView, List intervalAggregations) { return new AutoValue_ViewData_IntervalViewData( intervalView, @@ -109,7 +109,7 @@ public static IntervalViewData create(IntervalViewDescriptor intervalView, } @Override - public abstract IntervalViewDescriptor getViewDescriptor(); + public abstract IntervalView getView(); /** * The {@link IntervalAggregation}s associated with this {@link IntervalViewData}. diff --git a/core/src/main/java/io/opencensus/stats/ViewManager.java b/core/src/main/java/io/opencensus/stats/ViewManager.java index 9d723b1847..b55caf46d9 100644 --- a/core/src/main/java/io/opencensus/stats/ViewManager.java +++ b/core/src/main/java/io/opencensus/stats/ViewManager.java @@ -14,19 +14,19 @@ package io.opencensus.stats; /** - * Provides facilities to register {@link ViewDescriptor}s for collecting stats and retrieving + * Provides facilities to register {@link View}s for collecting stats and retrieving * stats data as a {@link ViewData}. */ public abstract class ViewManager { /** - * Pull model for stats. Registers a {@link ViewDescriptor} that will collect data to be accessed - * via {@link #getView(ViewDescriptor)}. + * Pull model for stats. Registers a {@link View} that will collect data to be accessed + * via {@link #getView(View)}. */ - public abstract void registerView(ViewDescriptor viewDescriptor); + public abstract void registerView(View view); /** * Returns the current stats data, {@link ViewData}, associated with the given - * {@link ViewDescriptor}. + * {@link View}. */ - public abstract ViewData getView(ViewDescriptor viewDescriptor); + public abstract ViewData getView(View view); } diff --git a/core/src/test/java/io/opencensus/stats/ViewDataTest.java b/core/src/test/java/io/opencensus/stats/ViewDataTest.java index 4b283cf20d..6637252164 100644 --- a/core/src/test/java/io/opencensus/stats/ViewDataTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewDataTest.java @@ -24,8 +24,8 @@ import io.opencensus.stats.IntervalAggregation.Interval; import io.opencensus.stats.ViewData.DistributionViewData; import io.opencensus.stats.ViewData.IntervalViewData; -import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; -import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.View.IntervalView; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -40,8 +40,8 @@ public final class ViewDataTest { public void testDistributionViewData() { DistributionAggregationDescriptor aggregationDescriptor = DistributionAggregationDescriptor.create(Arrays.asList(10.0, 20.0, 30.0, 40.0)); - final DistributionViewDescriptor view = - DistributionViewDescriptor.create( + final DistributionView view = + DistributionView.create( name, description, measure, aggregationDescriptor, tagKeys); final List aggregations = Arrays.asList( DistributionAggregation.create(5, 5.0, 15.0, Range.create(1.0, 5.0), tags1, @@ -52,12 +52,12 @@ public void testDistributionViewData() { final Timestamp end = Timestamp.fromMillis(2000); final ViewData viewData = DistributionViewData.create(view, aggregations, start, end); - assertThat(viewData.getViewDescriptor()).isEqualTo(view); + assertThat(viewData.getView()).isEqualTo(view); assertTrue(viewData.match( new Function () { @Override public Boolean apply(DistributionViewData dViewData) { return dViewData == viewData - && dViewData.getViewDescriptor().equals(view) + && dViewData.getView().equals(view) && shallowListEquals(dViewData.getDistributionAggregations(), aggregations) && dViewData.getStart().equals(start) && dViewData.getEnd().equals(end); @@ -74,8 +74,8 @@ && shallowListEquals(dViewData.getDistributionAggregations(), aggregations) public void testIntervalViewData() { IntervalAggregationDescriptor aggregationDescriptor = IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(111))); - final IntervalViewDescriptor view = - IntervalViewDescriptor.create( + final IntervalView view = + IntervalView.create( name, description, measure, aggregationDescriptor, tagKeys); final List aggregations = Arrays.asList( IntervalAggregation.create(tags1, Arrays.asList( @@ -84,7 +84,7 @@ public void testIntervalViewData() { Interval.create(Duration.fromMillis(111), 10, 100)))); final ViewData viewData = IntervalViewData.create(view, aggregations); - assertThat(viewData.getViewDescriptor()).isEqualTo(view); + assertThat(viewData.getView()).isEqualTo(view); assertTrue(viewData.match( new Function () { @Override public Boolean apply(DistributionViewData dViewData) { @@ -94,7 +94,7 @@ public void testIntervalViewData() { new Function () { @Override public Boolean apply(IntervalViewData iViewData) { return iViewData == viewData - && iViewData.getViewDescriptor().equals(view) + && iViewData.getView().equals(view) && shallowListEquals(iViewData.getIntervalAggregations(), aggregations); } })); @@ -102,8 +102,8 @@ public void testIntervalViewData() { @Test public void testViewDataEquals() { - DistributionViewDescriptor dView = - DistributionViewDescriptor.create( + DistributionView dView = + DistributionView.create( name, description, measure, @@ -113,8 +113,8 @@ public void testViewDataEquals() { Arrays.asList( DistributionAggregation.create( 5, 5.0, 15.0, Range.create(1.0, 5.0), tags1, Arrays.asList(1L))); - IntervalViewDescriptor iView = - IntervalViewDescriptor.create( + IntervalView iView = + IntervalView.create( name, description, measure, diff --git a/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java b/core/src/test/java/io/opencensus/stats/ViewTest.java similarity index 50% rename from core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java rename to core/src/test/java/io/opencensus/stats/ViewTest.java index 5abed72382..43562aa94d 100644 --- a/core/src/test/java/io/opencensus/stats/ViewDescriptorTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewTest.java @@ -19,103 +19,100 @@ import com.google.common.testing.EqualsTester; import io.opencensus.common.Duration; import io.opencensus.common.Function; -import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; -import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.View.IntervalView; import java.util.Arrays; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link ViewDescriptor} - */ +/** Tests for {@link View} */ @RunWith(JUnit4.class) -public final class ViewDescriptorTest { +public final class ViewTest { @Test - public void testDistributionViewDescriptor() { + public void testDistributionView() { DistributionAggregationDescriptor dAggrDescriptor = DistributionAggregationDescriptor.create(); - final ViewDescriptor viewDescriptor = DistributionViewDescriptor.create( + final View view = DistributionView.create( name, description, measure, dAggrDescriptor, keys); - assertThat(viewDescriptor.getViewDescriptorName()).isEqualTo(name); - assertThat(viewDescriptor.getName()).isEqualTo(name.asString()); - assertThat(viewDescriptor.getDescription()).isEqualTo(description); - assertThat(viewDescriptor.getMeasure().getName()) - .isEqualTo(measure.getName()); - assertThat(viewDescriptor.getTagKeys()).hasSize(2); - assertThat(viewDescriptor.getTagKeys().get(0).toString()).isEqualTo("foo"); - assertThat(viewDescriptor.getTagKeys().get(1).toString()).isEqualTo("bar"); - assertTrue(viewDescriptor.match( - new Function () { - @Override public Boolean apply(DistributionViewDescriptor dViewDescriptor) { - return dViewDescriptor == viewDescriptor; + assertThat(view.getViewName()).isEqualTo(name); + assertThat(view.getName()).isEqualTo(name.asString()); + assertThat(view.getDescription()).isEqualTo(description); + assertThat(view.getMeasure().getName()).isEqualTo(measure.getName()); + assertThat(view.getDimensions()).hasSize(2); + assertThat(view.getDimensions().get(0).toString()).isEqualTo("foo"); + assertThat(view.getDimensions().get(1).toString()).isEqualTo("bar"); + assertTrue(view.match( + new Function () { + @Override public Boolean apply(DistributionView dView) { + return dView == view; } }, - new Function () { - @Override public Boolean apply(IntervalViewDescriptor iViewDescriptor) { + new Function () { + @Override public Boolean apply(IntervalView iView) { return false; } })); } @Test - public void testIntervalViewDescriptor() { + public void testIntervalView() { IntervalAggregationDescriptor iAggrDescriptor = IntervalAggregationDescriptor.create( Arrays.asList(Duration.fromMillis(1), Duration.fromMillis(22), Duration.fromMillis(333))); - final ViewDescriptor viewDescriptor = IntervalViewDescriptor.create( + final View view = IntervalView.create( name, description, measure, iAggrDescriptor, keys); - assertThat(viewDescriptor.getViewDescriptorName()).isEqualTo(name); - assertThat(viewDescriptor.getName()).isEqualTo(name.asString()); - assertThat(viewDescriptor.getDescription()).isEqualTo(description); - assertThat(viewDescriptor.getMeasure().getName()) + assertThat(view.getViewName()).isEqualTo(name); + assertThat(view.getName()).isEqualTo(name.asString()); + assertThat(view.getDescription()).isEqualTo(description); + assertThat(view.getMeasure().getName()) .isEqualTo(measure.getName()); - assertThat(viewDescriptor.getTagKeys()).hasSize(2); - assertThat(viewDescriptor.getTagKeys().get(0).toString()).isEqualTo("foo"); - assertThat(viewDescriptor.getTagKeys().get(1).toString()).isEqualTo("bar"); - assertTrue(viewDescriptor.match( - new Function () { - @Override public Boolean apply(DistributionViewDescriptor dViewDescriptor) { + assertThat(view.getDimensions()).hasSize(2); + assertThat(view.getDimensions().get(0).toString()).isEqualTo("foo"); + assertThat(view.getDimensions().get(1).toString()).isEqualTo("bar"); + assertTrue(view.match( + new Function () { + @Override public Boolean apply(DistributionView dView) { return false; } }, - new Function () { - @Override public Boolean apply(IntervalViewDescriptor iViewDescriptor) { - return iViewDescriptor == viewDescriptor; + new Function () { + @Override public Boolean apply(IntervalView iView) { + return iView == view; } })); } @Test - public void testViewDescriptorEquals() { + public void testViewEquals() { DistributionAggregationDescriptor dAggrDescriptor = DistributionAggregationDescriptor.create(); IntervalAggregationDescriptor iAggrDescriptor = IntervalAggregationDescriptor.create( Arrays.asList(Duration.fromMillis(1), Duration.fromMillis(22), Duration.fromMillis(333))); new EqualsTester() .addEqualityGroup( - DistributionViewDescriptor.create( + DistributionView.create( name, description, measure, dAggrDescriptor, keys), - DistributionViewDescriptor.create( + DistributionView.create( name, description, measure, dAggrDescriptor, keys)) .addEqualityGroup( - DistributionViewDescriptor.create( + DistributionView.create( name, description + 2, measure, dAggrDescriptor, keys)) .addEqualityGroup( - IntervalViewDescriptor.create( + IntervalView.create( name, description, measure, iAggrDescriptor, keys), - IntervalViewDescriptor.create( + IntervalView.create( name, description, measure, iAggrDescriptor, keys)) .addEqualityGroup( - IntervalViewDescriptor.create( + IntervalView.create( name, description + 2, measure, iAggrDescriptor, keys)) .testEquals(); } @Test(expected = NullPointerException.class) - public void preventNullDistributionViewDescriptorName() { - DistributionViewDescriptor.create( - (ViewDescriptor.Name) null, + public void preventNullDistributionViewName() { + DistributionView.create( + (View.Name) null, description, measure, DistributionAggregationDescriptor.create(), @@ -123,8 +120,8 @@ public void preventNullDistributionViewDescriptorName() { } @Test(expected = NullPointerException.class) - public void preventNullDistributionViewDescriptorStringName() { - DistributionViewDescriptor.create( + public void preventNullDistributionViewStringName() { + DistributionView.create( (String) null, description, measure, @@ -133,9 +130,9 @@ public void preventNullDistributionViewDescriptorStringName() { } @Test(expected = NullPointerException.class) - public void preventNullIntervalViewDescriptorName() { - IntervalViewDescriptor.create( - (ViewDescriptor.Name) null, + public void preventNullIntervalViewName() { + IntervalView.create( + (View.Name) null, description, measure, IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(1))), @@ -143,8 +140,8 @@ public void preventNullIntervalViewDescriptorName() { } @Test(expected = NullPointerException.class) - public void preventNullIntervalViewDescriptorStringName() { - IntervalViewDescriptor.create( + public void preventNullIntervalViewStringName() { + IntervalView.create( (String) null, description, measure, @@ -153,29 +150,27 @@ public void preventNullIntervalViewDescriptorStringName() { } @Test - public void testViewDescriptorName() { - assertThat(ViewDescriptor.Name.create("my name").asString()).isEqualTo("my name"); + public void testViewName() { + assertThat(View.Name.create("my name").asString()).isEqualTo("my name"); } @Test(expected = NullPointerException.class) public void preventNullNameString() { - ViewDescriptor.Name.create(null); + View.Name.create(null); } @Test - public void testViewDescriptorNameEquals() { + public void testViewNameEquals() { new EqualsTester() .addEqualityGroup( - ViewDescriptor.Name.create("view-1"), ViewDescriptor.Name.create("view-1")) - .addEqualityGroup(ViewDescriptor.Name.create("view-2")) + View.Name.create("view-1"), View.Name.create("view-1")) + .addEqualityGroup(View.Name.create("view-2")) .testEquals(); } - private final ViewDescriptor.Name name = ViewDescriptor.Name.create("test-view-name"); + private final View.Name name = View.Name.create("test-view-name"); private final String description = "test-view-name description"; private final Measure measure = Measure.MeasureDouble.create( - "measurement", - "measurement description", - "1"); + "measure", "measure description", "1"); private final List keys = Arrays.asList(TagKey.create("foo"), TagKey.create("bar")); } diff --git a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java index 9ab4b4df9c..0880514213 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java +++ b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java @@ -21,8 +21,8 @@ import io.opencensus.stats.Measurement.MeasurementLong; import io.opencensus.stats.MutableViewData.MutableDistributionViewData; import io.opencensus.stats.MutableViewData.MutableIntervalViewData; -import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; -import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.View.IntervalView; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; @@ -45,25 +45,25 @@ final class MeasureToViewMap { HashMultimap.create(); @GuardedBy("this") - private final Map registeredViews = - new HashMap(); + private final Map registeredViews = + new HashMap(); - /** Returns a {@link ViewData} corresponding to the given {@link ViewDescriptor.Name}. */ - synchronized ViewData getView(ViewDescriptor.Name viewName, Clock clock) { + /** Returns a {@link ViewData} corresponding to the given {@link View.Name}. */ + synchronized ViewData getView(View.Name viewName, Clock clock) { MutableViewData view = getMutableViewData(viewName); return view == null ? null : view.toViewData(clock); } @Nullable - private synchronized MutableViewData getMutableViewData(ViewDescriptor.Name viewName) { - ViewDescriptor view = registeredViews.get(viewName); + private synchronized MutableViewData getMutableViewData(View.Name viewName) { + View view = registeredViews.get(viewName); if (view == null) { return null; } Collection views = mutableMap.get(view.getMeasure().getName()); for (MutableViewData viewData : views) { - if (viewData.getViewDescriptor().getViewDescriptorName().equals(viewName)) { + if (viewData.getView().getViewName().equals(viewName)) { return viewData; } } @@ -71,9 +71,9 @@ private synchronized MutableViewData getMutableViewData(ViewDescriptor.Name view + "\" registeredViews=" + registeredViews + ", mutableMap=" + mutableMap); } - /** Enable stats collection for the given {@link ViewDescriptor}. */ - synchronized void registerView(ViewDescriptor view, Clock clock) { - ViewDescriptor existing = registeredViews.get(view.getViewDescriptorName()); + /** Enable stats collection for the given {@link View}. */ + synchronized void registerView(View view, Clock clock) { + View existing = registeredViews.get(view.getViewName()); if (existing != null) { if (existing.equals(view)) { // Ignore views that are already registered. @@ -83,7 +83,7 @@ synchronized void registerView(ViewDescriptor view, Clock clock) { "A different view with the same name is already registered: " + existing); } } - registeredViews.put(view.getViewDescriptorName(), view); + registeredViews.put(view.getViewName(), view); MutableViewData mutableViewData = view.match( new CreateMutableDistributionViewDataFunction(clock), @@ -105,7 +105,7 @@ synchronized void record(StatsContextImpl tags, MeasureMap stats) { } private static final class CreateMutableDistributionViewDataFunction - implements Function { + implements Function { private final Clock clock; CreateMutableDistributionViewDataFunction(Clock clock) { @@ -113,15 +113,15 @@ private static final class CreateMutableDistributionViewDataFunction } @Override - public MutableViewData apply(DistributionViewDescriptor view) { + public MutableViewData apply(DistributionView view) { return MutableDistributionViewData.create(view, clock.now()); } } private static final class CreateMutableIntervalViewDataFunction - implements Function { + implements Function { @Override - public MutableViewData apply(IntervalViewDescriptor view) { + public MutableViewData apply(IntervalView view) { // TODO(songya): Create Interval Aggregations from internal Distributions. return MutableIntervalViewData.create(view); } diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java index 95ee2a2e51..0c0d7aee7f 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java +++ b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java @@ -16,9 +16,9 @@ import com.google.common.annotations.VisibleForTesting; import io.opencensus.common.Clock; import io.opencensus.common.Timestamp; +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.View.IntervalView; import io.opencensus.stats.ViewData.DistributionViewData; -import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; -import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -35,9 +35,9 @@ abstract class MutableViewData { static final TagValue UNKNOWN_TAG_VALUE = TagValue.create("unknown/not set"); /** - * The {@link ViewDescriptor} associated with this {@link ViewData}. + * The {@link View} associated with this {@link ViewData}. */ - abstract ViewDescriptor getViewDescriptor(); + abstract View getView(); /** * Record stats with the given tags. @@ -61,12 +61,12 @@ static final class MutableDistributionViewData extends MutableViewData { * Constructs a new {@link MutableDistributionViewData}. */ static MutableDistributionViewData create( - DistributionViewDescriptor distributionView, Timestamp start) { + DistributionView distributionView, Timestamp start) { return new MutableDistributionViewData(distributionView, start); } @Override - ViewDescriptor getViewDescriptor() { + View getView() { return distributionView; } @@ -74,7 +74,7 @@ ViewDescriptor getViewDescriptor() { void record(StatsContextImpl context, double value) { Map tags = context.tags; // TagKeys need to be unique within one view descriptor. - final List tagKeys = this.distributionView.getTagKeys(); + final List tagKeys = this.distributionView.getDimensions(); final List tagValues = new ArrayList(tagKeys.size()); // Record all the measures in a "Greedy" way. @@ -127,13 +127,13 @@ Timestamp getStart() { return start; } - private final DistributionViewDescriptor distributionView; + private final DistributionView distributionView; private final Map, MutableDistribution> tagValueDistributionMap = new HashMap, MutableDistribution>(); private final Timestamp start; private MutableDistributionViewData( - DistributionViewDescriptor distributionView, Timestamp start) { + DistributionView distributionView, Timestamp start) { this.distributionView = distributionView; this.start = start; } @@ -141,7 +141,7 @@ private MutableDistributionViewData( private final List generateTags(List tagValues) { final List tags = new ArrayList(tagValues.size()); int i = 0; - for (TagKey tagKey : this.distributionView.getTagKeys()) { + for (TagKey tagKey : this.distributionView.getDimensions()) { tags.add(Tag.create(tagKey, tagValues.get(i))); ++i; } @@ -163,12 +163,12 @@ static final class MutableIntervalViewData extends MutableViewData { /** * Constructs a new {@link MutableIntervalViewData}. */ - static MutableIntervalViewData create(IntervalViewDescriptor view) { + static MutableIntervalViewData create(IntervalView view) { throw new UnsupportedOperationException("Not implemented."); } @Override - ViewDescriptor getViewDescriptor() { + View getView() { throw new UnsupportedOperationException("Not implemented."); } diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java index 45f779d20b..c18a5aea68 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java @@ -15,7 +15,7 @@ import io.opencensus.common.Clock; import io.opencensus.internal.EventQueue; -import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; +import io.opencensus.stats.View.DistributionView; /** Object that stores all views and stats. */ final class StatsManager { @@ -32,17 +32,17 @@ final class StatsManager { this.clock = clock; } - void registerView(ViewDescriptor view) { + void registerView(View view) { // Only DistributionViews are supported currently. // TODO(sebright): Remove this once all views are supported. - if (!(view instanceof DistributionViewDescriptor)) { + if (!(view instanceof DistributionView)) { throw new UnsupportedOperationException( "The prototype will only support distribution views."); } measureToViewMap.registerView(view, clock); } - ViewData getView(ViewDescriptor.Name viewName) { + ViewData getView(View.Name viewName) { ViewData view = measureToViewMap.getView(viewName, clock); if (view == null) { throw new IllegalArgumentException( diff --git a/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java b/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java index 132ff6d413..ea56d7bd24 100644 --- a/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java +++ b/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java @@ -22,18 +22,18 @@ final class ViewManagerImpl extends ViewManager { } @Override - public void registerView(ViewDescriptor view) { + public void registerView(View view) { statsManager.registerView(view); } // TODO(sebright): Expose this method. - ViewData getView(ViewDescriptor.Name viewName) { + ViewData getView(View.Name viewName) { return statsManager.getView(viewName); } // TODO(sebright): Replace this method with the View.Name version. @Override - public ViewData getView(ViewDescriptor view) { - return statsManager.getView(view.getViewDescriptorName()); + public ViewData getView(View view) { + return statsManager.getView(view.getViewName()); } } diff --git a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java index cca7676c27..e3d6534e31 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java @@ -18,9 +18,9 @@ import io.opencensus.common.Function; import io.opencensus.common.Timestamp; +import io.opencensus.stats.View.DistributionView; import io.opencensus.stats.ViewData.DistributionViewData; import io.opencensus.stats.ViewData.IntervalViewData; -import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; import io.opencensus.testing.common.TestClock; import java.util.Arrays; import org.junit.Test; @@ -37,10 +37,10 @@ public class MeasureToViewMapTest { "measurement description", "By"); - private static final ViewDescriptor.Name VIEW_NAME = ViewDescriptor.Name.create("my view"); + private static final View.Name VIEW_NAME = View.Name.create("my view"); - private static final ViewDescriptor VIEW = - DistributionViewDescriptor.create( + private static final View VIEW = + DistributionView.create( VIEW_NAME, "view description", MEASURE, @@ -58,7 +58,7 @@ public void testRegisterAndGetDistributionView() { new Function() { @Override public Void apply(DistributionViewData view) { - assertThat(view.getViewDescriptor()).isEqualTo(VIEW); + assertThat(view.getView()).isEqualTo(VIEW); assertThat(view.getStart()).isEqualTo(Timestamp.create(10, 20)); assertThat(view.getEnd()).isEqualTo(Timestamp.create(30, 40)); assertThat(view.getDistributionAggregations()).isEmpty(); diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index 93ae0a0df0..bcb9b52fa5 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -174,7 +174,7 @@ public Void apply(IntervalViewData view) { @Test public void testRecordLong() { MeasureLong measure = MeasureLong.create("long measure", "description", "1"); - viewManager.registerView(ViewDescriptor.DistributionViewDescriptor + viewManager.registerView(View.DistributionView .create("name", "description", measure, DistributionAggregationDescriptor.create(), Arrays.asList(K1))); thrown.expect(UnsupportedOperationException.class); diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index fa6325d5da..c5531d6031 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -21,8 +21,8 @@ import io.opencensus.internal.SimpleEventQueue; import io.opencensus.stats.Measure.MeasureDouble; import io.opencensus.stats.ViewData.DistributionViewData; -import io.opencensus.stats.ViewDescriptor.DistributionViewDescriptor; -import io.opencensus.stats.ViewDescriptor.IntervalViewDescriptor; +import io.opencensus.stats.View.DistributionView; +import io.opencensus.stats.View.IntervalView; import io.opencensus.testing.common.TestClock; import java.util.Arrays; import java.util.Collection; @@ -57,8 +57,8 @@ public class ViewManagerImplTest { private static final MeasureDouble MEASURE = Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); - private static final ViewDescriptor.Name VIEW_NAME = ViewDescriptor.Name.create("my view"); - private static final ViewDescriptor.Name VIEW_NAME_2 = ViewDescriptor.Name.create("my view 2"); + private static final View.Name VIEW_NAME = View.Name.create("my view"); + private static final View.Name VIEW_NAME_2 = View.Name.create("my view 2"); private static final String VIEW_DESCRIPTION = "view description"; @@ -79,30 +79,30 @@ public class ViewManagerImplTest { private final ViewManagerImpl viewManager = statsComponent.getViewManager(); private final StatsRecorder statsRecorder = statsComponent.getStatsRecorder(); - private static DistributionViewDescriptor createDistributionViewDescriptor() { - return createDistributionViewDescriptor( + private static DistributionView createDistributionView() { + return createDistributionView( VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); } - private static DistributionViewDescriptor createDistributionViewDescriptor( - ViewDescriptor.Name name, + private static DistributionView createDistributionView( + View.Name name, Measure measure, DistributionAggregationDescriptor aggDescr, List keys) { - return DistributionViewDescriptor.create(name, VIEW_DESCRIPTION, measure, aggDescr, keys); + return DistributionView.create(name, VIEW_DESCRIPTION, measure, aggDescr, keys); } @Test public void testRegisterAndGetView() { - DistributionViewDescriptor view = createDistributionViewDescriptor(); + DistributionView view = createDistributionView(); viewManager.registerView(view); - assertThat(viewManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(view); + assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view); } @Test public void preventRegisteringIntervalView() { - ViewDescriptor intervalView = - IntervalViewDescriptor.create( + View intervalView = + IntervalView.create( VIEW_NAME, VIEW_DESCRIPTION, MEASURE, @@ -114,24 +114,24 @@ public void preventRegisteringIntervalView() { @Test public void allowRegisteringSameViewTwice() { - DistributionViewDescriptor view = createDistributionViewDescriptor(); + DistributionView view = createDistributionView(); viewManager.registerView(view); viewManager.registerView(view); - assertThat(viewManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(view); + assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view); } @Test public void preventRegisteringDifferentViewWithSameName() { - ViewDescriptor view1 = - DistributionViewDescriptor.create( + View view1 = + DistributionView.create( VIEW_NAME, "View description.", MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); viewManager.registerView(view1); - ViewDescriptor view2 = - DistributionViewDescriptor.create( + View view2 = + DistributionView.create( VIEW_NAME, "This is a different description.", MEASURE, @@ -142,7 +142,7 @@ public void preventRegisteringDifferentViewWithSameName() { thrown.expectMessage("A different view with the same name is already registered"); viewManager.registerView(view2); } finally { - assertThat(viewManager.getView(VIEW_NAME).getViewDescriptor()).isEqualTo(view1); + assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view1); } } @@ -154,8 +154,8 @@ public void disallowGettingNonexistentViewData() { @Test public void testRecord() { - DistributionViewDescriptor view = - createDistributionViewDescriptor( + DistributionView view = + createDistributionView( VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, @@ -168,7 +168,7 @@ public void testRecord() { } clock.setTime(Timestamp.create(3, 4)); DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertThat(viewData.getViewDescriptor()).isEqualTo(view); + assertThat(viewData.getView()).isEqualTo(view); assertThat(viewData.getStart()).isEqualTo(Timestamp.create(1, 2)); assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(3, 4)); assertDistributionAggregationsEquivalent( @@ -182,8 +182,8 @@ public void testRecord() { @Test public void getViewDoesNotClearStats() { - DistributionViewDescriptor view = - createDistributionViewDescriptor( + DistributionView view = + createDistributionView( VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, @@ -221,7 +221,7 @@ public void getViewDoesNotClearStats() { @Test public void testRecordMultipleTagValues() { viewManager.registerView( - createDistributionViewDescriptor( + createDistributionView( VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, @@ -259,7 +259,7 @@ public void allowRecordingWithoutRegisteringMatchingViewData() { @Test public void testRecordWithEmptyStatsContext() { viewManager.registerView( - createDistributionViewDescriptor( + createDistributionView( VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, @@ -283,7 +283,7 @@ public void testRecordWithEmptyStatsContext() { @Test public void testRecordWithNonExistentMeasurementDescriptor() { viewManager.registerView( - createDistributionViewDescriptor( + createDistributionView( VIEW_NAME, Measure.MeasureDouble.create(MEASURE_NAME, "measure", MEASURE_UNIT), DISTRIBUTION_AGGREGATION_DESCRIPTOR, @@ -299,7 +299,7 @@ public void testRecordWithNonExistentMeasurementDescriptor() { @Test public void testRecordWithTagsThatDoNotMatchViewData() { viewManager.registerView( - createDistributionViewDescriptor( + createDistributionView( VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, @@ -328,7 +328,7 @@ public void testViewDataWithMultipleTagKeys() { TagKey key1 = TagKey.create("Key-1"); TagKey key2 = TagKey.create("Key-2"); viewManager.registerView( - createDistributionViewDescriptor( + createDistributionView( VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, @@ -371,14 +371,14 @@ public void testViewDataWithMultipleTagKeys() { @Test public void testMultipleViewDatasSameMeasure() { - ViewDescriptor view1 = - createDistributionViewDescriptor( + View view1 = + createDistributionView( VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); - ViewDescriptor view2 = - createDistributionViewDescriptor( + View view2 = + createDistributionView( VIEW_NAME_2, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, @@ -412,11 +412,11 @@ public void testMultipleViewsDifferentMeasures() { Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); MeasureDouble measure2 = Measure.MeasureDouble.create(MEASURE_NAME_2, MEASURE_DESCRIPTION, MEASURE_UNIT); - ViewDescriptor view1 = - createDistributionViewDescriptor( + View view1 = + createDistributionView( VIEW_NAME, measure1, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); - ViewDescriptor view2 = - createDistributionViewDescriptor( + View view2 = + createDistributionView( VIEW_NAME_2, measure2, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); viewManager.registerView(view1); @@ -447,8 +447,8 @@ public void testMultipleViewsDifferentMeasures() { @Test public void testGetDistributionViewDataWithoutBucketBoundaries() { - ViewDescriptor view = - createDistributionViewDescriptor( + View view = + createDistributionView( VIEW_NAME, MEASURE, DistributionAggregationDescriptor.create(), Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); From 5c9e8268b300f0c8923c89dd73c0fef9b1d70e91 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 25 May 2017 18:49:37 -0700 Subject: [PATCH 0244/1581] Refactor Tag classes. Main changes in this commit: - Add a Tag class to represent a paired key and value in a View. - Add a TagValueString class to represent a validated String tag value. - Replace TagKey type parameter with TagKey subclasses for each type. --- .../src/main/java/io/opencensus/tags/Tag.java | 239 ++++++++++++++++++ .../java/io/opencensus/tags/TagContext.java | 76 +++--- .../main/java/io/opencensus/tags/TagKey.java | 72 ++++-- .../io/opencensus/tags/TagValueString.java | 55 ++++ .../io/opencensus/tags/TagContextTest.java | 80 ++---- .../java/io/opencensus/tags/TagKeyTest.java | 8 - .../test/java/io/opencensus/tags/TagTest.java | 144 +++++++++++ .../opencensus/tags/TagValueStringTest.java | 55 ++++ 8 files changed, 605 insertions(+), 124 deletions(-) create mode 100644 core/src/main/java/io/opencensus/tags/Tag.java create mode 100644 core/src/main/java/io/opencensus/tags/TagValueString.java create mode 100644 core/src/test/java/io/opencensus/tags/TagTest.java create mode 100644 core/src/test/java/io/opencensus/tags/TagValueStringTest.java diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java new file mode 100644 index 0000000000..59572fc495 --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -0,0 +1,239 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import com.google.auto.value.AutoValue; +import io.opencensus.common.Function; +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; +import io.opencensus.tags.TagKey.TagKeyString; +import javax.annotation.concurrent.Immutable; + +@Immutable +@AutoValue +public abstract class Tag { + + // The tag is either a TagString, TagLong, or TagBoolean. + abstract Object getTag(); + + /** + * Returns the tag's key. + * + * @return the tag's key. + */ + public TagKey getKey() { + return match(GET_TAG_KEY_STRING, GET_TAG_KEY_LONG, GET_TAG_KEY_BOOLEAN); + } + + private static final Function GET_TAG_KEY_STRING = + new Function() { + @Override + public TagKey apply(TagString tag) { + return tag.getKey(); + } + }; + + private static final Function GET_TAG_KEY_LONG = + new Function() { + @Override + public TagKey apply(TagLong tag) { + return tag.getKey(); + } + }; + + private static final Function GET_TAG_KEY_BOOLEAN = + new Function() { + @Override + public TagKey apply(TagBoolean tag) { + return tag.getKey(); + } + }; + + /** + * Applies a function to the tag's key and value. The function that is called depends on the type + * of the tag. This is similar to the visitor pattern. + * + * @param stringFunction the function to call when the tag has a {@code String} value. + * @param longFunction the function to call when the tag has a {@code long} value. + * @param booleanFunction the function to call when the tag has a {@code boolean} value. + * @param The result type of the function. + * @return The result of calling the function that matches the tag's type. + */ + public T match( + Function stringFunction, + Function longFunction, + Function booleanFunction) { + return matchWithDefault( + stringFunction, longFunction, booleanFunction, Tag.throwAssertionError()); + } + + /** + * Applies a function to the tag's key and value. This method is like {@link #match(Function, + * Function, Function)}, except that it has a default case, for backwards compatibility when tag + * types are added. + * + * @param stringFunction the function to call when the tag has a {@code String} value. + * @param longFunction the function to call when the tag has a {@code long} value. + * @param booleanFunction the function to call when the tag has a {@code boolean} value. + * @param defaultFunction the function to call when the tag has a value other than {@code String}, + * {@code long}, or {@code boolean}. + * @param The result type of the function. + * @return The result of calling the function that matches the tag's type. + */ + // TODO(sebright): How should we deal with the possibility of adding more tag types in the future? + // Will this method work? What type of parameter should we use for the default + // case? Should we remove the non-backwards compatible "match" method? + public T matchWithDefault( + Function stringFunction, + Function longFunction, + Function booleanFunction, + Function defaultFunction) { + Object tag = getTag(); + if (tag instanceof TagString) { + return stringFunction.apply((TagString) tag); + } else if (tag instanceof TagLong) { + return longFunction.apply((TagLong) tag); + } else if (tag instanceof TagBoolean) { + return booleanFunction.apply((TagBoolean) tag); + } else { + return defaultFunction.apply(tag); + } + } + + private static Function throwAssertionError() { + @SuppressWarnings("unchecked") + Function function = (Function) THROW_ASSERTION_ERROR; + return function; + } + + private static final Function THROW_ASSERTION_ERROR = + new Function() { + @Override + public Void apply(Object tag) { + throw new AssertionError(); + } + }; + + /** + * Creates a {@code Tag} from the given {@code String} key and value. + * + * @param key the tag key. + * @param value the tag value. + * @return a {@code Tag} with the given key and value. + */ + public static Tag createStringTag(TagKeyString key, TagValueString value) { + return createInternal(TagString.create(key, value)); + } + + /** + * Creates a {@code Tag} from the given {@code long} key and value. + * + * @param key the tag key. + * @param value the tag value. + * @return a {@code Tag} with the given key and value. + */ + public static Tag createLongTag(TagKeyLong key, long value) { + return createInternal(TagLong.create(key, value)); + } + + /** + * Creates a {@code Tag} from the given {@code boolean} key and value. + * + * @param key the tag key. + * @param value the tag value. + * @return a {@code Tag} with the given key and value. + */ + public static Tag createBooleanTag(TagKeyBoolean key, boolean value) { + return createInternal(TagBoolean.create(key, value)); + } + + private static Tag createInternal(Object tag) { + return new AutoValue_Tag(tag); + } + + /** + * A tag with a {@code String} key and value. + */ + @Immutable + @AutoValue + public abstract static class TagString { + static TagString create(TagKeyString key, TagValueString value) { + return new AutoValue_Tag_TagString(key, value); + } + + /** + * Returns the associated tag key. + * + * @return the associated tag key. + */ + public abstract TagKeyString getKey(); + + /** + * Returns the associated tag value. + * + * @return the associated tag value. + */ + public abstract TagValueString getValue(); + } + + /** + * A tag with a {@code long} key and value. + */ + @Immutable + @AutoValue + public abstract static class TagLong { + static TagLong create(TagKeyLong key, long value) { + return new AutoValue_Tag_TagLong(key, value); + } + + /** + * Returns the associated tag key. + * + * @return the associated tag key. + */ + public abstract TagKeyLong getKey(); + + /** + * Returns the associated tag value. + * + * @return the associated tag value. + */ + public abstract long getValue(); + } + + /** + * A tag with a {@code boolean} key and value. + */ + @Immutable + @AutoValue + public abstract static class TagBoolean { + static TagBoolean create(TagKeyBoolean key, boolean value) { + return new AutoValue_Tag_TagBoolean(key, value); + } + + /** + * Returns the associated tag key. + * + * @return the associated tag key. + */ + public abstract TagKeyBoolean getKey(); + + /** + * Returns the associated tag value. + * + * @return the associated tag value. + */ + public abstract boolean getValue(); + } +} diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java index 6b617e4d1d..480377376d 100644 --- a/core/src/main/java/io/opencensus/tags/TagContext.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -13,10 +13,11 @@ package io.opencensus.tags; -import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; -import io.opencensus.internal.StringUtil; -import io.opencensus.tags.TagKey.TagType; +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; +import io.opencensus.tags.TagKey.TagKeyString; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -31,17 +32,17 @@ */ @Immutable public final class TagContext { - /** The maximum length for a string tag value. */ - public static final int MAX_STRING_LENGTH = StringUtil.MAX_LENGTH; + + private static final TagContext EMPTY = newBuilder().build(); // The types of the TagKey and value must match for each entry. - private final Map, Object> tags; + private final Map tags; - TagContext(Map, Object> tags) { - this.tags = Collections.unmodifiableMap(new HashMap, Object>(tags)); + TagContext(Map tags) { + this.tags = Collections.unmodifiableMap(new HashMap(tags)); } - Map, Object> getTags() { + Map getTags() { return tags; } @@ -54,16 +55,34 @@ public Builder toBuilder() { return new Builder(getTags()); } + /** + * Returns an empty {@code TagContext}. + * + * @return an empty {@code TagContext}. + */ + public static TagContext empty() { + return EMPTY; + } + + /** + * Returns an empty {@code Builder}. + * + * @return an empty {@code Builder}. + */ + public static Builder newBuilder() { + return new Builder(); + } + /** Builder for the {@link TagContext} class. */ public static final class Builder { - private final Map, Object> tags; + private final Map tags; - private Builder(Map, Object> tags) { - this.tags = new HashMap, Object>(tags); + private Builder(Map tags) { + this.tags = new HashMap(tags); } Builder() { - this.tags = new HashMap, Object>(); + this.tags = new HashMap(); } /** @@ -72,17 +91,10 @@ private Builder(Map, Object> tags) { * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this - * @throws IllegalArgumentException if either argument is null, the key is the wrong type, or - * the value contains unprintable characters or is longer than {@link - * TagContext#MAX_STRING_LENGTH}. + * @throws IllegalArgumentException if either argument is null. */ - public Builder set(TagKey key, String value) { - checkArgument(key.getTagType() == TagType.TAG_STRING); - - // TODO(sebright): Consider adding a TagValue class to avoid validating the String every time - // it is set. - checkArgument(StringUtil.isValid(value)); - return setInternal(key, value); + public Builder set(TagKeyString key, TagValueString value) { + return setInternal(key, checkNotNull(value, "value")); } /** @@ -91,11 +103,10 @@ public Builder set(TagKey key, String value) { * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this - * @throws IllegalArgumentException if the key is null or the key is the wrong type. + * @throws IllegalArgumentException if the key is null. */ // TODO(sebright): Make this public once we support types other than String. - Builder set(TagKey key, long value) { - checkArgument(key.getTagType() == TagType.TAG_LONG); + Builder set(TagKeyLong key, long value) { return setInternal(key, value); } @@ -105,16 +116,15 @@ Builder set(TagKey key, long value) { * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this - * @throws IllegalArgumentException if the key is null or the key is the wrong type. + * @throws IllegalArgumentException if the key is null. */ // TODO(sebright): Make this public once we support types other than String. - Builder set(TagKey key, boolean value) { - checkArgument(key.getTagType() == TagType.TAG_BOOLEAN); + Builder set(TagKeyBoolean key, boolean value) { return setInternal(key, value); } - private Builder setInternal(TagKey key, TagValueT value) { - tags.put(key, value); + private Builder setInternal(TagKey key, Object value) { + tags.put(checkNotNull(key), value); return this; } @@ -124,7 +134,7 @@ private Builder setInternal(TagKey key, TagValueT value) * @param key the {@code TagKey} which will be cleared. * @return this */ - public Builder clear(TagKey key) { + public Builder clear(TagKey key) { tags.remove(key); return this; } @@ -135,7 +145,7 @@ public Builder clear(TagKey key) { * @return a {@code TagContext} with the same tags as this builder. */ public TagContext build() { - return new TagContext(new HashMap, Object>(tags)); + return new TagContext(new HashMap(tags)); } } } diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index ba93573ddf..6063709ca4 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -14,36 +14,21 @@ package io.opencensus.tags; import static com.google.common.base.Preconditions.checkArgument; -import static io.opencensus.tags.TagKey.TagType.TAG_BOOLEAN; -import static io.opencensus.tags.TagKey.TagType.TAG_LONG; -import static io.opencensus.tags.TagKey.TagType.TAG_STRING; import com.google.auto.value.AutoValue; import io.opencensus.internal.StringUtil; import javax.annotation.concurrent.Immutable; -/** - * A key to a value stored in a {@link TagContext}. - * - * @param The type of value that can be paired with this {@code TagKey}. {@code TagKey}s - * can only be instantiated with types {@code String}, {@code Long}, and {@code Boolean}. - */ +/** A key to a value stored in a {@link TagContext}. */ @Immutable -@AutoValue -public abstract class TagKey { +public abstract class TagKey { /** The maximum length for a tag key name. */ public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; - enum TagType { - TAG_STRING, - TAG_LONG, - TAG_BOOLEAN - } - TagKey() {} /** - * Constructs a {@code TagKey} with the given name. + * Constructs a {@code TagKeyString} with the given name. * *

            The name must meet the following requirements: * @@ -56,13 +41,13 @@ enum TagType { * @return a {@code TagKey} with the given name. * @throws IllegalArgumentException if the name is not valid. */ - public static TagKey createStringKey(String name) { + public static TagKeyString createStringKey(String name) { checkArgument(StringUtil.isValid(name)); - return new AutoValue_TagKey(name, TAG_STRING); + return TagKeyString.create(name); } /** - * Constructs a {@code TagKey} with the given name. + * Constructs a {@code TagKeyLong} with the given name. * *

            The name must meet the following requirements: * @@ -75,13 +60,13 @@ public static TagKey createStringKey(String name) { * @throws IllegalArgumentException if the name is not valid. */ // TODO(sebright): Make this public once we support types other than String. - static TagKey createLongKey(String name) { + static TagKeyLong createLongKey(String name) { checkArgument(StringUtil.isValid(name)); - return new AutoValue_TagKey(name, TAG_LONG); + return TagKeyLong.create(name); } /** - * Constructs a {@code TagKey} with the given name. + * Constructs a {@code TagKeyBoolean} with the given name. * *

            The name must meet the following requirements: * @@ -94,12 +79,43 @@ static TagKey createLongKey(String name) { * @throws IllegalArgumentException if the name is not valid. */ // TODO(sebright): Make this public once we support types other than String. - static TagKey createBooleanKey(String name) { + static TagKeyBoolean createBooleanKey(String name) { checkArgument(StringUtil.isValid(name)); - return new AutoValue_TagKey(name, TAG_BOOLEAN); + return TagKeyBoolean.create(name); + } + + public abstract String getName(); + + /** + * A {@code TagKey} for values of type {@code String}. + */ + @Immutable + @AutoValue + public abstract static class TagKeyString extends TagKey { + static TagKeyString create(String name) { + return new AutoValue_TagKey_TagKeyString(name); + } } - abstract String getName(); + /** + * A {@code TagKey} for values of type {@code long}. + */ + @Immutable + @AutoValue + public abstract static class TagKeyLong extends TagKey { + static TagKeyLong create(String name) { + return new AutoValue_TagKey_TagKeyLong(name); + } + } - abstract TagType getTagType(); + /** + * A {@code TagKey} for values of type {@code boolean}. + */ + @Immutable + @AutoValue + public abstract static class TagKeyBoolean extends TagKey { + static TagKeyBoolean create(String name) { + return new AutoValue_TagKey_TagKeyBoolean(name); + } + } } diff --git a/core/src/main/java/io/opencensus/tags/TagValueString.java b/core/src/main/java/io/opencensus/tags/TagValueString.java new file mode 100644 index 0000000000..5cb68d299b --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/TagValueString.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import com.google.auto.value.AutoValue; +import com.google.common.base.Preconditions; +import io.opencensus.internal.StringUtil; +import io.opencensus.tags.TagKey.TagKeyString; +import javax.annotation.concurrent.Immutable; + +/** A validated tag value associated with a {@link TagKeyString}. */ +// TODO(sebright): Is there any reason to use a TagValue class for booleans and longs, too? +@Immutable +@AutoValue +public abstract class TagValueString { + /** The maximum length for a {@code String} tag value. */ + public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; + + TagValueString() {} + + /** + * Constructs a {@code TagValueString} from the given string. The string must meet the following + * requirements: + * + *

              + *
            1. It cannot be longer than {@link #MAX_LENGTH}. + *
            2. It can only contain printable ASCII characters. + *
            + * + * @param value the tag value. + * @throws IllegalArgumentException if the {@code String} is not valid. + */ + public static TagValueString create(String value) { + Preconditions.checkArgument(StringUtil.isValid(value)); + return new AutoValue_TagValueString(value); + } + + /** + * Returns the tag value as a {@code String}. + * + * @return the tag value as a {@code String}. + */ + public abstract String asString(); +} diff --git a/core/src/test/java/io/opencensus/tags/TagContextTest.java b/core/src/test/java/io/opencensus/tags/TagContextTest.java index a64cbbeabc..28fcad8a43 100644 --- a/core/src/test/java/io/opencensus/tags/TagContextTest.java +++ b/core/src/test/java/io/opencensus/tags/TagContextTest.java @@ -16,7 +16,9 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableMap; -import java.util.Arrays; +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; +import io.opencensus.tags.TagKey.TagKeyString; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -30,85 +32,53 @@ public class TagContextTest { @Rule public final ExpectedException thrown = ExpectedException.none(); - private static final TagKey KS1 = TagKey.createStringKey("k1"); - private static final TagKey KS2 = TagKey.createStringKey("k2"); + private static final TagKeyString KS1 = TagKey.createStringKey("k1"); + private static final TagKeyString KS2 = TagKey.createStringKey("k2"); + + private static final TagValueString V1 = TagValueString.create("k1"); + private static final TagValueString V2 = TagValueString.create("k2"); @Test public void applyBuilderOperationsInOrder() { - assertThat(newBuilder().set(KS1, "v1").set(KS1, "v2").build().getTags()) - .containsExactly(KS1, "v2"); + assertThat(newBuilder().set(KS1, V1).set(KS1, V2).build().getTags()) + .containsExactly(KS1, V2); } @Test public void allowMutlipleKeysWithSameNameButDifferentTypes() { - TagKey stringKey = TagKey.createStringKey("key"); - TagKey longKey = TagKey.createLongKey("key"); - TagKey booleanKey = TagKey.createBooleanKey("key"); + TagKeyString stringKey = TagKey.createStringKey("key"); + TagKeyLong intKey = TagKey.createLongKey("key"); + TagKeyBoolean boolKey = TagKey.createBooleanKey("key"); assertThat( newBuilder() - .set(stringKey, "value") - .set(longKey, 123) - .set(booleanKey, true) + .set(stringKey, TagValueString.create("value")) + .set(intKey, 123) + .set(boolKey, true) .build() .getTags()) - .containsExactly(stringKey, "value", longKey, 123L, booleanKey, true); + .containsExactly(stringKey, TagValueString.create("value"), intKey, 123L, boolKey, true); } @Test public void testSet() { - TagContext tags = singletonTagMap(KS1, "v1"); - assertThat(tags.toBuilder().set(KS1, "v2").build().getTags()).containsExactly(KS1, "v2"); - assertThat(tags.toBuilder().set(KS2, "v2").build().getTags()) - .containsExactly(KS1, "v1", KS2, "v2"); + TagContext tags = singletonTagContext(KS1, V1); + assertThat(tags.toBuilder().set(KS1, V2).build().getTags()).containsExactly(KS1, V2); + assertThat(tags.toBuilder().set(KS2, V2).build().getTags()) + .containsExactly(KS1, V1, KS2, V2); } @Test public void testClear() { - TagContext tags = singletonTagMap(KS1, "v1"); + TagContext tags = singletonTagContext(KS1, V1); assertThat(tags.toBuilder().clear(KS1).build().getTags()).isEmpty(); - assertThat(tags.toBuilder().clear(KS2).build().getTags()).containsExactly(KS1, "v1"); - } - - @Test - public void allowStringTagValueWithMaxLength() { - char[] chars = new char[TagContext.MAX_STRING_LENGTH]; - Arrays.fill(chars, 'v'); - String value = new String(chars); - TagKey key = TagKey.createStringKey("K"); - newBuilder().set(key, value); - } - - @Test - public void disallowStringTagValueOverMaxLength() { - char[] chars = new char[TagContext.MAX_STRING_LENGTH + 1]; - Arrays.fill(chars, 'v'); - String value = new String(chars); - TagKey key = TagKey.createStringKey("K"); - thrown.expect(IllegalArgumentException.class); - newBuilder().set(key, value); - } - - @Test - public void disallowStringTagValueWithUnprintableChars() { - String value = "\2ab\3cd"; - TagKey key = TagKey.createStringKey("K"); - thrown.expect(IllegalArgumentException.class); - newBuilder().set(key, value); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private final TagKey badLongKey = (TagKey) TagKey.createStringKey("Key"); - - @Test(expected = IllegalArgumentException.class) - public void disallowSettingWrongTypeOfKey() { - newBuilder().set(badLongKey, 123); + assertThat(tags.toBuilder().clear(KS2).build().getTags()).containsExactly(KS1, V1); } private static TagContext.Builder newBuilder() { return new TagContext.Builder(); } - private static TagContext singletonTagMap(TagKey key, TagValueT value) { - return new TagContext(ImmutableMap., Object>of(key, value)); + private static TagContext singletonTagContext(TagKey key, Object value) { + return new TagContext(ImmutableMap.of(key, value)); } } diff --git a/core/src/test/java/io/opencensus/tags/TagKeyTest.java b/core/src/test/java/io/opencensus/tags/TagKeyTest.java index 2628b73e63..f0c92a6819 100644 --- a/core/src/test/java/io/opencensus/tags/TagKeyTest.java +++ b/core/src/test/java/io/opencensus/tags/TagKeyTest.java @@ -16,7 +16,6 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import io.opencensus.tags.TagKey.TagType; import java.util.Arrays; import org.junit.Rule; import org.junit.Test; @@ -35,13 +34,6 @@ public void testGetName() { assertThat(TagKey.createStringKey("foo").getName()).isEqualTo("foo"); } - @Test - public void testGetTagType() { - assertThat(TagKey.createStringKey("key").getTagType()).isEqualTo(TagType.TAG_STRING); - assertThat(TagKey.createLongKey("key").getTagType()).isEqualTo(TagType.TAG_LONG); - assertThat(TagKey.createBooleanKey("key").getTagType()).isEqualTo(TagType.TAG_BOOLEAN); - } - @Test public void createString_AllowTagKeyNameWithMaxLength() { char[] key = new char[TagKey.MAX_LENGTH]; diff --git a/core/src/test/java/io/opencensus/tags/TagTest.java b/core/src/test/java/io/opencensus/tags/TagTest.java new file mode 100644 index 0000000000..f90ad0eacb --- /dev/null +++ b/core/src/test/java/io/opencensus/tags/TagTest.java @@ -0,0 +1,144 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Function; +import io.opencensus.tags.Tag.TagBoolean; +import io.opencensus.tags.Tag.TagLong; +import io.opencensus.tags.Tag.TagString; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link Tag}. */ +@RunWith(JUnit4.class) +public final class TagTest { + + @Test + public void testGetStringKey() { + assertThat( + Tag.createStringTag(TagKey.createStringKey("k"), TagValueString.create("v")).getKey()) + .isEqualTo(TagKey.createStringKey("k")); + } + + @Test + public void testGetLongKey() { + assertThat(Tag.createLongTag(TagKey.createLongKey("k"), 2L).getKey()) + .isEqualTo(TagKey.createLongKey("k")); + } + + @Test + public void testGetBooleanKey() { + assertThat(Tag.createBooleanTag(TagKey.createBooleanKey("k"), false).getKey()) + .isEqualTo(TagKey.createBooleanKey("k")); + } + + @Test + public void testMatchStringTag() { + assertThat( + Tag.createStringTag(TagKey.createStringKey("k1"), TagValueString.create("value")) + .match( + new Function() { + @Override + public String apply(TagString tag) { + return tag.getValue().asString(); + } + }, + new Function() { + @Override + public String apply(TagLong tag) { + throw new AssertionError(); + } + }, + new Function() { + @Override + public String apply(TagBoolean tag) { + throw new AssertionError(); + } + })) + .isEqualTo("value"); + } + + @Test + public void testMatchLong() { + assertThat( + Tag.createLongTag(TagKey.createLongKey("k2"), 3L) + .match( + new Function() { + @Override + public Long apply(TagString tag) { + throw new AssertionError(); + } + }, + new Function() { + @Override + public Long apply(TagLong tag) { + return tag.getValue(); + } + }, + new Function() { + @Override + public Long apply(TagBoolean tag) { + throw new AssertionError(); + } + })) + .isEqualTo(3L); + } + + @Test + public void testMatchBoolean() { + assertThat( + Tag.createBooleanTag(TagKey.createBooleanKey("k3"), false) + .match( + new Function() { + @Override + public Boolean apply(TagString tag) { + throw new AssertionError(); + } + }, + new Function() { + @Override + public Boolean apply(TagLong tag) { + throw new AssertionError(); + } + }, + new Function() { + @Override + public Boolean apply(TagBoolean tag) { + return tag.getValue(); + } + })) + .isEqualTo(false); + } + + @Test + public void testTagEquals() { + new EqualsTester() + .addEqualityGroup( + Tag.createStringTag(TagKey.createStringKey("Key1"), TagValueString.create("foo")), + Tag.createStringTag(TagKey.createStringKey("Key1"), TagValueString.create("foo"))) + .addEqualityGroup( + Tag.createLongTag(TagKey.createLongKey("Key1"), 100L), + Tag.createLongTag(TagKey.createLongKey("Key1"), 100)) + .addEqualityGroup( + Tag.createBooleanTag(TagKey.createBooleanKey("Key1"), true), + Tag.createBooleanTag(TagKey.createBooleanKey("Key1"), true)) + .addEqualityGroup(Tag.createBooleanTag(TagKey.createBooleanKey("Key2"), true)) + .addEqualityGroup(Tag.createBooleanTag(TagKey.createBooleanKey("Key1"), false)) + .testEquals(); + } +} diff --git a/core/src/test/java/io/opencensus/tags/TagValueStringTest.java b/core/src/test/java/io/opencensus/tags/TagValueStringTest.java new file mode 100644 index 0000000000..7aeaa3159b --- /dev/null +++ b/core/src/test/java/io/opencensus/tags/TagValueStringTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.tags.TagValueString; +import java.util.Arrays; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link TagValueString}. */ +@RunWith(JUnit4.class) +public class TagValueStringTest { + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void allowStringTagValueWithMaxLength() { + char[] chars = new char[TagValueString.MAX_LENGTH]; + Arrays.fill(chars, 'v'); + String value = new String(chars); + assertThat(TagValueString.create(value).asString()).isEqualTo(value); + } + + @Test + public void disallowStringTagValueOverMaxLength() { + char[] chars = new char[TagValueString.MAX_LENGTH + 1]; + Arrays.fill(chars, 'v'); + String value = new String(chars); + thrown.expect(IllegalArgumentException.class); + TagValueString.create(value); + } + + @Test + public void disallowStringTagValueWithUnprintableChars() { + String value = "\2ab\3cd"; + thrown.expect(IllegalArgumentException.class); + TagValueString.create(value); + } +} From 4c64c6ca09c9bf459fc546fc1fd85860f3ea64e7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Sun, 4 Jun 2017 18:39:23 -0700 Subject: [PATCH 0245/1581] Cleanup. --- core/src/main/java/io/opencensus/tags/Tag.java | 9 +++++++-- .../test/java/io/opencensus/tags/TagContextTest.java | 10 +++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index 59572fc495..94fdb76e4a 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -20,6 +20,9 @@ import io.opencensus.tags.TagKey.TagKeyString; import javax.annotation.concurrent.Immutable; +/** + * Paired {@link TagKey} and value. + */ @Immutable @AutoValue public abstract class Tag { @@ -143,7 +146,8 @@ public static Tag createStringTag(TagKeyString key, TagValueString value) { * @param value the tag value. * @return a {@code Tag} with the given key and value. */ - public static Tag createLongTag(TagKeyLong key, long value) { + // TODO(sebright): Make this public once we support types other than String. + static Tag createLongTag(TagKeyLong key, long value) { return createInternal(TagLong.create(key, value)); } @@ -154,7 +158,8 @@ public static Tag createLongTag(TagKeyLong key, long value) { * @param value the tag value. * @return a {@code Tag} with the given key and value. */ - public static Tag createBooleanTag(TagKeyBoolean key, boolean value) { + // TODO(sebright): Make this public once we support types other than String. + static Tag createBooleanTag(TagKeyBoolean key, boolean value) { return createInternal(TagBoolean.create(key, value)); } diff --git a/core/src/test/java/io/opencensus/tags/TagContextTest.java b/core/src/test/java/io/opencensus/tags/TagContextTest.java index 28fcad8a43..d4b9cda25c 100644 --- a/core/src/test/java/io/opencensus/tags/TagContextTest.java +++ b/core/src/test/java/io/opencensus/tags/TagContextTest.java @@ -35,8 +35,8 @@ public class TagContextTest { private static final TagKeyString KS1 = TagKey.createStringKey("k1"); private static final TagKeyString KS2 = TagKey.createStringKey("k2"); - private static final TagValueString V1 = TagValueString.create("k1"); - private static final TagValueString V2 = TagValueString.create("k2"); + private static final TagValueString V1 = TagValueString.create("v1"); + private static final TagValueString V2 = TagValueString.create("v2"); @Test public void applyBuilderOperationsInOrder() { @@ -47,16 +47,16 @@ public void applyBuilderOperationsInOrder() { @Test public void allowMutlipleKeysWithSameNameButDifferentTypes() { TagKeyString stringKey = TagKey.createStringKey("key"); - TagKeyLong intKey = TagKey.createLongKey("key"); + TagKeyLong longKey = TagKey.createLongKey("key"); TagKeyBoolean boolKey = TagKey.createBooleanKey("key"); assertThat( newBuilder() .set(stringKey, TagValueString.create("value")) - .set(intKey, 123) + .set(longKey, 123) .set(boolKey, true) .build() .getTags()) - .containsExactly(stringKey, TagValueString.create("value"), intKey, 123L, boolKey, true); + .containsExactly(stringKey, TagValueString.create("value"), longKey, 123L, boolKey, true); } @Test From 930e6459e74f080ea0be54ae386c0de488af6ec2 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 19 Jun 2017 19:59:23 -0700 Subject: [PATCH 0246/1581] Make tag value in Tag class optional. --- .../src/main/java/io/opencensus/tags/Tag.java | 58 ++++++++++--------- .../test/java/io/opencensus/tags/TagTest.java | 2 +- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index 94fdb76e4a..299bb46bab 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -18,10 +18,11 @@ import io.opencensus.tags.TagKey.TagKeyBoolean; import io.opencensus.tags.TagKey.TagKeyLong; import io.opencensus.tags.TagKey.TagKeyString; +import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; /** - * Paired {@link TagKey} and value. + * {@link TagKey} paired with an optional value. */ @Immutable @AutoValue @@ -68,8 +69,8 @@ public TagKey apply(TagBoolean tag) { * of the tag. This is similar to the visitor pattern. * * @param stringFunction the function to call when the tag has a {@code String} value. - * @param longFunction the function to call when the tag has a {@code long} value. - * @param booleanFunction the function to call when the tag has a {@code boolean} value. + * @param longFunction the function to call when the tag has a {@code Long} value. + * @param booleanFunction the function to call when the tag has a {@code Boolean} value. * @param The result type of the function. * @return The result of calling the function that matches the tag's type. */ @@ -87,10 +88,10 @@ public T match( * types are added. * * @param stringFunction the function to call when the tag has a {@code String} value. - * @param longFunction the function to call when the tag has a {@code long} value. - * @param booleanFunction the function to call when the tag has a {@code boolean} value. + * @param longFunction the function to call when the tag has a {@code Long} value. + * @param booleanFunction the function to call when the tag has a {@code Boolean} value. * @param defaultFunction the function to call when the tag has a value other than {@code String}, - * {@code long}, or {@code boolean}. + * {@code Long}, or {@code Boolean}. * @param The result type of the function. * @return The result of calling the function that matches the tag's type. */ @@ -132,34 +133,34 @@ public Void apply(Object tag) { * Creates a {@code Tag} from the given {@code String} key and value. * * @param key the tag key. - * @param value the tag value. + * @param value the tag value, or {@code null} if the key is not paired with a value. * @return a {@code Tag} with the given key and value. */ - public static Tag createStringTag(TagKeyString key, TagValueString value) { + public static Tag createStringTag(TagKeyString key, @Nullable TagValueString value) { return createInternal(TagString.create(key, value)); } /** - * Creates a {@code Tag} from the given {@code long} key and value. + * Creates a {@code Tag} from the given {@code Long} key and value. * * @param key the tag key. - * @param value the tag value. + * @param value the tag value, or {@code null} if the key is not paired with a value. * @return a {@code Tag} with the given key and value. */ // TODO(sebright): Make this public once we support types other than String. - static Tag createLongTag(TagKeyLong key, long value) { + static Tag createLongTag(TagKeyLong key, @Nullable Long value) { return createInternal(TagLong.create(key, value)); } /** - * Creates a {@code Tag} from the given {@code boolean} key and value. + * Creates a {@code Tag} from the given {@code Boolean} key and value. * * @param key the tag key. - * @param value the tag value. + * @param value the tag value, or {@code null} if the key is not paired with a value. * @return a {@code Tag} with the given key and value. */ // TODO(sebright): Make this public once we support types other than String. - static Tag createBooleanTag(TagKeyBoolean key, boolean value) { + static Tag createBooleanTag(TagKeyBoolean key, @Nullable Boolean value) { return createInternal(TagBoolean.create(key, value)); } @@ -173,7 +174,7 @@ private static Tag createInternal(Object tag) { @Immutable @AutoValue public abstract static class TagString { - static TagString create(TagKeyString key, TagValueString value) { + static TagString create(TagKeyString key, @Nullable TagValueString value) { return new AutoValue_Tag_TagString(key, value); } @@ -185,20 +186,21 @@ static TagString create(TagKeyString key, TagValueString value) { public abstract TagKeyString getKey(); /** - * Returns the associated tag value. + * Returns the associated tag value, or {@code null} if the key is not paired with a value. * - * @return the associated tag value. + * @return the associated tag value, or {@code null} if the key is not paired with a value. */ + @Nullable public abstract TagValueString getValue(); } /** - * A tag with a {@code long} key and value. + * A tag with a {@code Long} key and value. */ @Immutable @AutoValue public abstract static class TagLong { - static TagLong create(TagKeyLong key, long value) { + static TagLong create(TagKeyLong key, @Nullable Long value) { return new AutoValue_Tag_TagLong(key, value); } @@ -210,20 +212,21 @@ static TagLong create(TagKeyLong key, long value) { public abstract TagKeyLong getKey(); /** - * Returns the associated tag value. + * Returns the associated tag value, or {@code null} if the key is not paired with a value. * - * @return the associated tag value. + * @return the associated tag value, or {@code null} if the key is not paired with a value. */ - public abstract long getValue(); + @Nullable + public abstract Long getValue(); } /** - * A tag with a {@code boolean} key and value. + * A tag with a {@code Boolean} key and value. */ @Immutable @AutoValue public abstract static class TagBoolean { - static TagBoolean create(TagKeyBoolean key, boolean value) { + static TagBoolean create(TagKeyBoolean key, @Nullable Boolean value) { return new AutoValue_Tag_TagBoolean(key, value); } @@ -235,10 +238,11 @@ static TagBoolean create(TagKeyBoolean key, boolean value) { public abstract TagKeyBoolean getKey(); /** - * Returns the associated tag value. + * Returns the associated tag value, or {@code null} if the key is not paired with a value. * - * @return the associated tag value. + * @return the associated tag value, or {@code null} if the key is not paired with a value. */ - public abstract boolean getValue(); + @Nullable + public abstract Boolean getValue(); } } diff --git a/core/src/test/java/io/opencensus/tags/TagTest.java b/core/src/test/java/io/opencensus/tags/TagTest.java index f90ad0eacb..f240ba89b4 100644 --- a/core/src/test/java/io/opencensus/tags/TagTest.java +++ b/core/src/test/java/io/opencensus/tags/TagTest.java @@ -133,7 +133,7 @@ public void testTagEquals() { Tag.createStringTag(TagKey.createStringKey("Key1"), TagValueString.create("foo"))) .addEqualityGroup( Tag.createLongTag(TagKey.createLongKey("Key1"), 100L), - Tag.createLongTag(TagKey.createLongKey("Key1"), 100)) + Tag.createLongTag(TagKey.createLongKey("Key1"), 100L)) .addEqualityGroup( Tag.createBooleanTag(TagKey.createBooleanKey("Key1"), true), Tag.createBooleanTag(TagKey.createBooleanKey("Key1"), true)) From 72fd93dfcbf7de98f62c012cbd96a18f7768c82d Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 22 Jun 2017 12:13:55 -0700 Subject: [PATCH 0247/1581] Make TagString, TagLong, and TagBoolean subclasses of Tag. --- .../src/main/java/io/opencensus/tags/Tag.java | 146 ++++++------------ .../java/io/opencensus/tags/TagUtils.java | 38 +++++ .../java/io/opencensus/tags/TagUtilsTest.java | 26 ++++ 3 files changed, 114 insertions(+), 96 deletions(-) create mode 100644 core/src/main/java/io/opencensus/tags/TagUtils.java create mode 100644 core/src/test/java/io/opencensus/tags/TagUtilsTest.java diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index 299bb46bab..461992c638 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -21,48 +21,16 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; -/** - * {@link TagKey} paired with an optional value. - */ +/** {@link TagKey} paired with an optional value. */ @Immutable -@AutoValue public abstract class Tag { - // The tag is either a TagString, TagLong, or TagBoolean. - abstract Object getTag(); - /** * Returns the tag's key. * * @return the tag's key. */ - public TagKey getKey() { - return match(GET_TAG_KEY_STRING, GET_TAG_KEY_LONG, GET_TAG_KEY_BOOLEAN); - } - - private static final Function GET_TAG_KEY_STRING = - new Function() { - @Override - public TagKey apply(TagString tag) { - return tag.getKey(); - } - }; - - private static final Function GET_TAG_KEY_LONG = - new Function() { - @Override - public TagKey apply(TagLong tag) { - return tag.getKey(); - } - }; - - private static final Function GET_TAG_KEY_BOOLEAN = - new Function() { - @Override - public TagKey apply(TagBoolean tag) { - return tag.getKey(); - } - }; + public abstract TagKey getKey(); /** * Applies a function to the tag's key and value. The function that is called depends on the type @@ -79,7 +47,7 @@ public T match( Function longFunction, Function booleanFunction) { return matchWithDefault( - stringFunction, longFunction, booleanFunction, Tag.throwAssertionError()); + stringFunction, longFunction, booleanFunction, TagUtils.throwAssertionError()); } /** @@ -98,36 +66,11 @@ public T match( // TODO(sebright): How should we deal with the possibility of adding more tag types in the future? // Will this method work? What type of parameter should we use for the default // case? Should we remove the non-backwards compatible "match" method? - public T matchWithDefault( + public abstract T matchWithDefault( Function stringFunction, Function longFunction, Function booleanFunction, - Function defaultFunction) { - Object tag = getTag(); - if (tag instanceof TagString) { - return stringFunction.apply((TagString) tag); - } else if (tag instanceof TagLong) { - return longFunction.apply((TagLong) tag); - } else if (tag instanceof TagBoolean) { - return booleanFunction.apply((TagBoolean) tag); - } else { - return defaultFunction.apply(tag); - } - } - - private static Function throwAssertionError() { - @SuppressWarnings("unchecked") - Function function = (Function) THROW_ASSERTION_ERROR; - return function; - } - - private static final Function THROW_ASSERTION_ERROR = - new Function() { - @Override - public Void apply(Object tag) { - throw new AssertionError(); - } - }; + Function defaultFunction); /** * Creates a {@code Tag} from the given {@code String} key and value. @@ -137,7 +80,7 @@ public Void apply(Object tag) { * @return a {@code Tag} with the given key and value. */ public static Tag createStringTag(TagKeyString key, @Nullable TagValueString value) { - return createInternal(TagString.create(key, value)); + return TagString.create(key, value); } /** @@ -149,7 +92,7 @@ public static Tag createStringTag(TagKeyString key, @Nullable TagValueString val */ // TODO(sebright): Make this public once we support types other than String. static Tag createLongTag(TagKeyLong key, @Nullable Long value) { - return createInternal(TagLong.create(key, value)); + return TagLong.create(key, value); } /** @@ -161,28 +104,20 @@ static Tag createLongTag(TagKeyLong key, @Nullable Long value) { */ // TODO(sebright): Make this public once we support types other than String. static Tag createBooleanTag(TagKeyBoolean key, @Nullable Boolean value) { - return createInternal(TagBoolean.create(key, value)); + return TagBoolean.create(key, value); } - private static Tag createInternal(Object tag) { - return new AutoValue_Tag(tag); - } - - /** - * A tag with a {@code String} key and value. - */ + /** A tag with a {@code String} key and value. */ @Immutable @AutoValue - public abstract static class TagString { + public abstract static class TagString extends Tag { + TagString() {} + static TagString create(TagKeyString key, @Nullable TagValueString value) { return new AutoValue_Tag_TagString(key, value); } - /** - * Returns the associated tag key. - * - * @return the associated tag key. - */ + @Override public abstract TagKeyString getKey(); /** @@ -192,23 +127,28 @@ static TagString create(TagKeyString key, @Nullable TagValueString value) { */ @Nullable public abstract TagValueString getValue(); + + @Override + public T matchWithDefault( + Function stringFunction, + Function longFunction, + Function booleanFunction, + Function defaultFunction) { + return stringFunction.apply(this); + } } - /** - * A tag with a {@code Long} key and value. - */ + /** A tag with a {@code Long} key and value. */ @Immutable @AutoValue - public abstract static class TagLong { + public abstract static class TagLong extends Tag { + TagLong() {} + static TagLong create(TagKeyLong key, @Nullable Long value) { return new AutoValue_Tag_TagLong(key, value); } - /** - * Returns the associated tag key. - * - * @return the associated tag key. - */ + @Override public abstract TagKeyLong getKey(); /** @@ -218,23 +158,28 @@ static TagLong create(TagKeyLong key, @Nullable Long value) { */ @Nullable public abstract Long getValue(); + + @Override + public T matchWithDefault( + Function stringFunction, + Function longFunction, + Function booleanFunction, + Function defaultFunction) { + return longFunction.apply(this); + } } - /** - * A tag with a {@code Boolean} key and value. - */ + /** A tag with a {@code Boolean} key and value. */ @Immutable @AutoValue - public abstract static class TagBoolean { + public abstract static class TagBoolean extends Tag { + TagBoolean() {} + static TagBoolean create(TagKeyBoolean key, @Nullable Boolean value) { return new AutoValue_Tag_TagBoolean(key, value); } - /** - * Returns the associated tag key. - * - * @return the associated tag key. - */ + @Override public abstract TagKeyBoolean getKey(); /** @@ -244,5 +189,14 @@ static TagBoolean create(TagKeyBoolean key, @Nullable Boolean value) { */ @Nullable public abstract Boolean getValue(); + + @Override + public T matchWithDefault( + Function stringFunction, + Function longFunction, + Function booleanFunction, + Function defaultFunction) { + return booleanFunction.apply(this); + } } } diff --git a/core/src/main/java/io/opencensus/tags/TagUtils.java b/core/src/main/java/io/opencensus/tags/TagUtils.java new file mode 100644 index 0000000000..1da34e3285 --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/TagUtils.java @@ -0,0 +1,38 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import io.opencensus.common.Function; + +/** + * Utility methods for the tag classes. + */ +final class TagUtils { + private TagUtils() {} + + static Function throwAssertionError() { + // It is safe to cast a producer of Void to anything, because Void is always null. + @SuppressWarnings("unchecked") + Function function = (Function) THROW_ASSERTION_ERROR; + return function; + } + + private static final Function THROW_ASSERTION_ERROR = + new Function() { + @Override + public Void apply(Object tag) { + throw new AssertionError(); + } + }; +} diff --git a/core/src/test/java/io/opencensus/tags/TagUtilsTest.java b/core/src/test/java/io/opencensus/tags/TagUtilsTest.java new file mode 100644 index 0000000000..ca86b53479 --- /dev/null +++ b/core/src/test/java/io/opencensus/tags/TagUtilsTest.java @@ -0,0 +1,26 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import org.junit.Test; + +/** + * Tests for {@link TagUtils}. + */ +public class TagUtilsTest { + @Test(expected = AssertionError.class) + public void testThrowAssertionError() { + TagUtils.throwAssertionError().apply("ignored"); + } +} From 89a427c0dcabe2a7f5c6d325613a273838d0434d Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 22 Jun 2017 12:15:35 -0700 Subject: [PATCH 0248/1581] Add TagKey.match methods. --- .../main/java/io/opencensus/tags/TagKey.java | 70 ++++++++++++++++ .../java/io/opencensus/tags/TagKeyTest.java | 82 +++++++++++++++++++ 2 files changed, 152 insertions(+) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index 6063709ca4..7876908d38 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -16,6 +16,7 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.auto.value.AutoValue; +import io.opencensus.common.Function; import io.opencensus.internal.StringUtil; import javax.annotation.concurrent.Immutable; @@ -86,6 +87,48 @@ static TagKeyBoolean createBooleanKey(String name) { public abstract String getName(); + /** + * Applies a function to the {@code TagKey} subclass. The function that is called depends on the + * type of the tag key. This is similar to the visitor pattern. + * + * @param stringFunction the function to call when the {@code TagKey} is a {@code TagKeyString}. + * @param longFunction the function to call when the {@code TagKey} is a {@code TagKeyLong}. + * @param booleanFunction the function to call when the {@code TagKey} is a {@code TagKeyBoolean}. + * @param The result type of the function. + * @return The result of calling the function that matches the tag key's type. + */ + // TODO(sebright): Should we make this public in the first release? + public T match( + Function stringFunction, + Function longFunction, + Function booleanFunction) { + return matchWithDefault( + stringFunction, longFunction, booleanFunction, TagUtils.throwAssertionError()); + } + + /** + * Applies a function to the {@code TagKey} subclass. This method is like {@link #match(Function, + * Function, Function)}, except that it has a default case, for backwards compatibility when tag + * types are added. + * + * @param stringFunction the function to call when the {@code TagKey} is a {@code TagKeyString}. + * @param longFunction the function to call when the {@code TagKey} is a {@code TagKeyLong}. + * @param booleanFunction the function to call when the {@code TagKey} is a {@code TagKeyBoolean}. + * @param defaultFunction the function to call when the tag key has a type other than + * {@code String}, {@code long}, or {@code boolean}. + * @param The result type of the function. + * @return The result of calling the function that matches the tag key's type. + */ + // TODO(sebright): Should we make this public in the first release? + // TODO(sebright): How should we deal with the possibility of adding more tag types in the future? + // Will this method work? What type of parameter should we use for the default + // case? Should we remove the non-backwards compatible "match" method? + public abstract T matchWithDefault( + Function stringFunction, + Function longFunction, + Function booleanFunction, + Function defaultFunction); + /** * A {@code TagKey} for values of type {@code String}. */ @@ -95,6 +138,15 @@ public abstract static class TagKeyString extends TagKey { static TagKeyString create(String name) { return new AutoValue_TagKey_TagKeyString(name); } + + @Override + public T matchWithDefault( + Function stringFunction, + Function longFunction, + Function booleanFunction, + Function defaultFunction) { + return stringFunction.apply(this); + } } /** @@ -106,6 +158,15 @@ public abstract static class TagKeyLong extends TagKey { static TagKeyLong create(String name) { return new AutoValue_TagKey_TagKeyLong(name); } + + @Override + public T matchWithDefault( + Function stringFunction, + Function longFunction, + Function booleanFunction, + Function defaultFunction) { + return longFunction.apply(this); + } } /** @@ -117,5 +178,14 @@ public abstract static class TagKeyBoolean extends TagKey { static TagKeyBoolean create(String name) { return new AutoValue_TagKey_TagKeyBoolean(name); } + + @Override + public T matchWithDefault( + Function stringFunction, + Function longFunction, + Function booleanFunction, + Function defaultFunction) { + return booleanFunction.apply(this); + } } } diff --git a/core/src/test/java/io/opencensus/tags/TagKeyTest.java b/core/src/test/java/io/opencensus/tags/TagKeyTest.java index f0c92a6819..a88a6a2b3e 100644 --- a/core/src/test/java/io/opencensus/tags/TagKeyTest.java +++ b/core/src/test/java/io/opencensus/tags/TagKeyTest.java @@ -16,6 +16,10 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; +import io.opencensus.common.Function; +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; +import io.opencensus.tags.TagKey.TagKeyString; import java.util.Arrays; import org.junit.Rule; import org.junit.Test; @@ -55,6 +59,84 @@ public void createString_DisallowUnprintableChars() { TagKey.createStringKey("\2ab\3cd"); } + @Test + public void testMatchStringKey() { + assertThat( + TagKey.createStringKey("key") + .match( + new Function() { + @Override + public String apply(TagKeyString tag) { + return tag.getName(); + } + }, + new Function() { + @Override + public String apply(TagKeyLong tag) { + throw new AssertionError(); + } + }, + new Function() { + @Override + public String apply(TagKeyBoolean tag) { + throw new AssertionError(); + } + })) + .isEqualTo("key"); + } + + @Test + public void testMatchLongKey() { + assertThat( + TagKey.createLongKey("key") + .match( + new Function() { + @Override + public String apply(TagKeyString tag) { + throw new AssertionError(); + } + }, + new Function() { + @Override + public String apply(TagKeyLong tag) { + return tag.getName(); + } + }, + new Function() { + @Override + public String apply(TagKeyBoolean tag) { + throw new AssertionError(); + } + })) + .isEqualTo("key"); + } + + @Test + public void testMatchBooleanKey() { + assertThat( + TagKey.createBooleanKey("key") + .match( + new Function() { + @Override + public String apply(TagKeyString tag) { + throw new AssertionError(); + } + }, + new Function() { + @Override + public String apply(TagKeyLong tag) { + throw new AssertionError(); + } + }, + new Function() { + @Override + public String apply(TagKeyBoolean tag) { + return tag.getName(); + } + })) + .isEqualTo("key"); + } + @Test public void testTagKeyEquals() { new EqualsTester() From 83e1b4a7d21cb3b1383d23aefb9a1a2360fa7b76 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 26 Jun 2017 10:30:16 -0700 Subject: [PATCH 0249/1581] Move TagKey factory methods into TagKey subclasses. --- .../main/java/io/opencensus/tags/TagKey.java | 125 ++++++++---------- .../io/opencensus/tags/TagContextTest.java | 10 +- .../java/io/opencensus/tags/TagKeyTest.java | 22 +-- .../test/java/io/opencensus/tags/TagTest.java | 37 +++--- 4 files changed, 92 insertions(+), 102 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index 7876908d38..8599ef9203 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -28,63 +28,6 @@ public abstract class TagKey { TagKey() {} - /** - * Constructs a {@code TagKeyString} with the given name. - * - *

            The name must meet the following requirements: - * - *

              - *
            1. It cannot be longer than {@link #MAX_LENGTH}. - *
            2. It can only contain printable ASCII characters. - *
            - * - * @param name the name of the key. - * @return a {@code TagKey} with the given name. - * @throws IllegalArgumentException if the name is not valid. - */ - public static TagKeyString createStringKey(String name) { - checkArgument(StringUtil.isValid(name)); - return TagKeyString.create(name); - } - - /** - * Constructs a {@code TagKeyLong} with the given name. - * - *

            The name must meet the following requirements: - * - *

              - *
            1. It cannot be longer than {@link #MAX_LENGTH}. - *
            2. It can only contain printable ASCII characters. - *
            - * - * @param name the name of the key. - * @throws IllegalArgumentException if the name is not valid. - */ - // TODO(sebright): Make this public once we support types other than String. - static TagKeyLong createLongKey(String name) { - checkArgument(StringUtil.isValid(name)); - return TagKeyLong.create(name); - } - - /** - * Constructs a {@code TagKeyBoolean} with the given name. - * - *

            The name must meet the following requirements: - * - *

              - *
            1. It cannot be longer than {@link #MAX_LENGTH}. - *
            2. It can only contain printable ASCII characters. - *
            - * - * @param name the name of the key. - * @throws IllegalArgumentException if the name is not valid. - */ - // TODO(sebright): Make this public once we support types other than String. - static TagKeyBoolean createBooleanKey(String name) { - checkArgument(StringUtil.isValid(name)); - return TagKeyBoolean.create(name); - } - public abstract String getName(); /** @@ -114,8 +57,8 @@ public T match( * @param stringFunction the function to call when the {@code TagKey} is a {@code TagKeyString}. * @param longFunction the function to call when the {@code TagKey} is a {@code TagKeyLong}. * @param booleanFunction the function to call when the {@code TagKey} is a {@code TagKeyBoolean}. - * @param defaultFunction the function to call when the tag key has a type other than - * {@code String}, {@code long}, or {@code boolean}. + * @param defaultFunction the function to call when the tag key has a type other than {@code + * String}, {@code long}, or {@code boolean}. * @param The result type of the function. * @return The result of calling the function that matches the tag key's type. */ @@ -129,13 +72,27 @@ public abstract T matchWithDefault( Function booleanFunction, Function defaultFunction); - /** - * A {@code TagKey} for values of type {@code String}. - */ + /** A {@code TagKey} for values of type {@code String}. */ @Immutable @AutoValue public abstract static class TagKeyString extends TagKey { - static TagKeyString create(String name) { + + /** + * Constructs a {@code TagKeyString} with the given name. + * + *

            The name must meet the following requirements: + * + *

              + *
            1. It cannot be longer than {@link #MAX_LENGTH}. + *
            2. It can only contain printable ASCII characters. + *
            + * + * @param name the name of the key. + * @return a {@code TagKeyString} with the given name. + * @throws IllegalArgumentException if the name is not valid. + */ + public static TagKeyString create(String name) { + checkArgument(StringUtil.isValid(name)); return new AutoValue_TagKey_TagKeyString(name); } @@ -149,13 +106,28 @@ public T matchWithDefault( } } - /** - * A {@code TagKey} for values of type {@code long}. - */ + /** A {@code TagKey} for values of type {@code long}. */ @Immutable @AutoValue public abstract static class TagKeyLong extends TagKey { + + /** + * Constructs a {@code TagKeyLong} with the given name. + * + *

            The name must meet the following requirements: + * + *

              + *
            1. It cannot be longer than {@link #MAX_LENGTH}. + *
            2. It can only contain printable ASCII characters. + *
            + * + * @param name the name of the key. + * @return a {@code TagKeyLong} with the given name. + * @throws IllegalArgumentException if the name is not valid. + */ + // TODO(sebright): Make this public once we support types other than String. static TagKeyLong create(String name) { + checkArgument(StringUtil.isValid(name)); return new AutoValue_TagKey_TagKeyLong(name); } @@ -169,13 +141,28 @@ public T matchWithDefault( } } - /** - * A {@code TagKey} for values of type {@code boolean}. - */ + /** A {@code TagKey} for values of type {@code boolean}. */ @Immutable @AutoValue public abstract static class TagKeyBoolean extends TagKey { + + /** + * Constructs a {@code TagKeyBoolean} with the given name. + * + *

            The name must meet the following requirements: + * + *

              + *
            1. It cannot be longer than {@link #MAX_LENGTH}. + *
            2. It can only contain printable ASCII characters. + *
            + * + * @param name the name of the key. + * @return a {@code TagKeyBoolean} with the given name. + * @throws IllegalArgumentException if the name is not valid. + */ + // TODO(sebright): Make this public once we support types other than String. static TagKeyBoolean create(String name) { + checkArgument(StringUtil.isValid(name)); return new AutoValue_TagKey_TagKeyBoolean(name); } diff --git a/core/src/test/java/io/opencensus/tags/TagContextTest.java b/core/src/test/java/io/opencensus/tags/TagContextTest.java index d4b9cda25c..91da5a63c0 100644 --- a/core/src/test/java/io/opencensus/tags/TagContextTest.java +++ b/core/src/test/java/io/opencensus/tags/TagContextTest.java @@ -32,8 +32,8 @@ public class TagContextTest { @Rule public final ExpectedException thrown = ExpectedException.none(); - private static final TagKeyString KS1 = TagKey.createStringKey("k1"); - private static final TagKeyString KS2 = TagKey.createStringKey("k2"); + private static final TagKeyString KS1 = TagKeyString.create("k1"); + private static final TagKeyString KS2 = TagKeyString.create("k2"); private static final TagValueString V1 = TagValueString.create("v1"); private static final TagValueString V2 = TagValueString.create("v2"); @@ -46,9 +46,9 @@ public void applyBuilderOperationsInOrder() { @Test public void allowMutlipleKeysWithSameNameButDifferentTypes() { - TagKeyString stringKey = TagKey.createStringKey("key"); - TagKeyLong longKey = TagKey.createLongKey("key"); - TagKeyBoolean boolKey = TagKey.createBooleanKey("key"); + TagKeyString stringKey = TagKeyString.create("key"); + TagKeyLong longKey = TagKeyLong.create("key"); + TagKeyBoolean boolKey = TagKeyBoolean.create("key"); assertThat( newBuilder() .set(stringKey, TagValueString.create("value")) diff --git a/core/src/test/java/io/opencensus/tags/TagKeyTest.java b/core/src/test/java/io/opencensus/tags/TagKeyTest.java index a88a6a2b3e..60e68d287e 100644 --- a/core/src/test/java/io/opencensus/tags/TagKeyTest.java +++ b/core/src/test/java/io/opencensus/tags/TagKeyTest.java @@ -35,14 +35,14 @@ public final class TagKeyTest { @Test public void testGetName() { - assertThat(TagKey.createStringKey("foo").getName()).isEqualTo("foo"); + assertThat(TagKeyString.create("foo").getName()).isEqualTo("foo"); } @Test public void createString_AllowTagKeyNameWithMaxLength() { char[] key = new char[TagKey.MAX_LENGTH]; Arrays.fill(key, 'k'); - TagKey.createStringKey(new String(key)); + TagKeyString.create(new String(key)); } @Test @@ -50,19 +50,19 @@ public void createString_DisallowTagKeyNameOverMaxLength() { char[] key = new char[TagKey.MAX_LENGTH + 1]; Arrays.fill(key, 'k'); thrown.expect(IllegalArgumentException.class); - TagKey.createStringKey(new String(key)); + TagKeyString.create(new String(key)); } @Test public void createString_DisallowUnprintableChars() { thrown.expect(IllegalArgumentException.class); - TagKey.createStringKey("\2ab\3cd"); + TagKeyString.create("\2ab\3cd"); } @Test public void testMatchStringKey() { assertThat( - TagKey.createStringKey("key") + TagKeyString.create("key") .match( new Function() { @Override @@ -88,7 +88,7 @@ public String apply(TagKeyBoolean tag) { @Test public void testMatchLongKey() { assertThat( - TagKey.createLongKey("key") + TagKeyLong.create("key") .match( new Function() { @Override @@ -114,7 +114,7 @@ public String apply(TagKeyBoolean tag) { @Test public void testMatchBooleanKey() { assertThat( - TagKey.createBooleanKey("key") + TagKeyBoolean.create("key") .match( new Function() { @Override @@ -140,10 +140,10 @@ public String apply(TagKeyBoolean tag) { @Test public void testTagKeyEquals() { new EqualsTester() - .addEqualityGroup(TagKey.createStringKey("foo"), TagKey.createStringKey("foo")) - .addEqualityGroup(TagKey.createLongKey("foo")) - .addEqualityGroup(TagKey.createBooleanKey("foo")) - .addEqualityGroup(TagKey.createStringKey("bar")) + .addEqualityGroup(TagKeyString.create("foo"), TagKeyString.create("foo")) + .addEqualityGroup(TagKeyLong.create("foo")) + .addEqualityGroup(TagKeyBoolean.create("foo")) + .addEqualityGroup(TagKeyString.create("bar")) .testEquals(); } } diff --git a/core/src/test/java/io/opencensus/tags/TagTest.java b/core/src/test/java/io/opencensus/tags/TagTest.java index f240ba89b4..7c40e326d0 100644 --- a/core/src/test/java/io/opencensus/tags/TagTest.java +++ b/core/src/test/java/io/opencensus/tags/TagTest.java @@ -20,6 +20,9 @@ import io.opencensus.tags.Tag.TagBoolean; import io.opencensus.tags.Tag.TagLong; import io.opencensus.tags.Tag.TagString; +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; +import io.opencensus.tags.TagKey.TagKeyString; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -31,26 +34,26 @@ public final class TagTest { @Test public void testGetStringKey() { assertThat( - Tag.createStringTag(TagKey.createStringKey("k"), TagValueString.create("v")).getKey()) - .isEqualTo(TagKey.createStringKey("k")); + Tag.createStringTag(TagKeyString.create("k"), TagValueString.create("v")).getKey()) + .isEqualTo(TagKeyString.create("k")); } @Test public void testGetLongKey() { - assertThat(Tag.createLongTag(TagKey.createLongKey("k"), 2L).getKey()) - .isEqualTo(TagKey.createLongKey("k")); + assertThat(Tag.createLongTag(TagKeyLong.create("k"), 2L).getKey()) + .isEqualTo(TagKeyLong.create("k")); } @Test public void testGetBooleanKey() { - assertThat(Tag.createBooleanTag(TagKey.createBooleanKey("k"), false).getKey()) - .isEqualTo(TagKey.createBooleanKey("k")); + assertThat(Tag.createBooleanTag(TagKeyBoolean.create("k"), false).getKey()) + .isEqualTo(TagKeyBoolean.create("k")); } @Test public void testMatchStringTag() { assertThat( - Tag.createStringTag(TagKey.createStringKey("k1"), TagValueString.create("value")) + Tag.createStringTag(TagKeyString.create("k1"), TagValueString.create("value")) .match( new Function() { @Override @@ -76,7 +79,7 @@ public String apply(TagBoolean tag) { @Test public void testMatchLong() { assertThat( - Tag.createLongTag(TagKey.createLongKey("k2"), 3L) + Tag.createLongTag(TagKeyLong.create("k2"), 3L) .match( new Function() { @Override @@ -102,7 +105,7 @@ public Long apply(TagBoolean tag) { @Test public void testMatchBoolean() { assertThat( - Tag.createBooleanTag(TagKey.createBooleanKey("k3"), false) + Tag.createBooleanTag(TagKeyBoolean.create("k3"), false) .match( new Function() { @Override @@ -129,16 +132,16 @@ public Boolean apply(TagBoolean tag) { public void testTagEquals() { new EqualsTester() .addEqualityGroup( - Tag.createStringTag(TagKey.createStringKey("Key1"), TagValueString.create("foo")), - Tag.createStringTag(TagKey.createStringKey("Key1"), TagValueString.create("foo"))) + Tag.createStringTag(TagKeyString.create("Key1"), TagValueString.create("foo")), + Tag.createStringTag(TagKeyString.create("Key1"), TagValueString.create("foo"))) .addEqualityGroup( - Tag.createLongTag(TagKey.createLongKey("Key1"), 100L), - Tag.createLongTag(TagKey.createLongKey("Key1"), 100L)) + Tag.createLongTag(TagKeyLong.create("Key1"), 100L), + Tag.createLongTag(TagKeyLong.create("Key1"), 100L)) .addEqualityGroup( - Tag.createBooleanTag(TagKey.createBooleanKey("Key1"), true), - Tag.createBooleanTag(TagKey.createBooleanKey("Key1"), true)) - .addEqualityGroup(Tag.createBooleanTag(TagKey.createBooleanKey("Key2"), true)) - .addEqualityGroup(Tag.createBooleanTag(TagKey.createBooleanKey("Key1"), false)) + Tag.createBooleanTag(TagKeyBoolean.create("Key1"), true), + Tag.createBooleanTag(TagKeyBoolean.create("Key1"), true)) + .addEqualityGroup(Tag.createBooleanTag(TagKeyBoolean.create("Key2"), true)) + .addEqualityGroup(Tag.createBooleanTag(TagKeyBoolean.create("Key1"), false)) .testEquals(); } } From 7c4d991187f2e1504929ad3b168f936a0e004d6f Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 26 Jun 2017 10:36:24 -0700 Subject: [PATCH 0250/1581] Use more specific types for default case in Tag and TagKey 'match' methods. --- core/src/main/java/io/opencensus/tags/Tag.java | 8 ++++---- core/src/main/java/io/opencensus/tags/TagKey.java | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index 461992c638..07087ccd6f 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -70,7 +70,7 @@ public abstract T matchWithDefault( Function stringFunction, Function longFunction, Function booleanFunction, - Function defaultFunction); + Function defaultFunction); /** * Creates a {@code Tag} from the given {@code String} key and value. @@ -133,7 +133,7 @@ public T matchWithDefault( Function stringFunction, Function longFunction, Function booleanFunction, - Function defaultFunction) { + Function defaultFunction) { return stringFunction.apply(this); } } @@ -164,7 +164,7 @@ public T matchWithDefault( Function stringFunction, Function longFunction, Function booleanFunction, - Function defaultFunction) { + Function defaultFunction) { return longFunction.apply(this); } } @@ -195,7 +195,7 @@ public T matchWithDefault( Function stringFunction, Function longFunction, Function booleanFunction, - Function defaultFunction) { + Function defaultFunction) { return booleanFunction.apply(this); } } diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index 8599ef9203..68697a2bd1 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -70,7 +70,7 @@ public abstract T matchWithDefault( Function stringFunction, Function longFunction, Function booleanFunction, - Function defaultFunction); + Function defaultFunction); /** A {@code TagKey} for values of type {@code String}. */ @Immutable @@ -101,7 +101,7 @@ public T matchWithDefault( Function stringFunction, Function longFunction, Function booleanFunction, - Function defaultFunction) { + Function defaultFunction) { return stringFunction.apply(this); } } @@ -136,7 +136,7 @@ public T matchWithDefault( Function stringFunction, Function longFunction, Function booleanFunction, - Function defaultFunction) { + Function defaultFunction) { return longFunction.apply(this); } } @@ -171,7 +171,7 @@ public T matchWithDefault( Function stringFunction, Function longFunction, Function booleanFunction, - Function defaultFunction) { + Function defaultFunction) { return booleanFunction.apply(this); } } From 565d94a1b5287ce7a5834dc47b329f19c02e5832 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 26 Jun 2017 10:43:21 -0700 Subject: [PATCH 0251/1581] Add TODO. --- core/src/main/java/io/opencensus/tags/Tag.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index 07087ccd6f..16294245df 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -22,6 +22,7 @@ import javax.annotation.concurrent.Immutable; /** {@link TagKey} paired with an optional value. */ +// TODO(sebright): Do we also need to represent TagKeys paired with non-null values? @Immutable public abstract class Tag { From a556047079c74310232df726051defd04b27707b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 26 Jun 2017 10:42:05 -0700 Subject: [PATCH 0252/1581] Move Tag factory methods into Tag subclasses. --- .../src/main/java/io/opencensus/tags/Tag.java | 64 ++++++++----------- .../test/java/io/opencensus/tags/TagTest.java | 28 ++++---- 2 files changed, 40 insertions(+), 52 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index 16294245df..e571bd7aed 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -73,48 +73,20 @@ public abstract T matchWithDefault( Function booleanFunction, Function defaultFunction); - /** - * Creates a {@code Tag} from the given {@code String} key and value. - * - * @param key the tag key. - * @param value the tag value, or {@code null} if the key is not paired with a value. - * @return a {@code Tag} with the given key and value. - */ - public static Tag createStringTag(TagKeyString key, @Nullable TagValueString value) { - return TagString.create(key, value); - } - - /** - * Creates a {@code Tag} from the given {@code Long} key and value. - * - * @param key the tag key. - * @param value the tag value, or {@code null} if the key is not paired with a value. - * @return a {@code Tag} with the given key and value. - */ - // TODO(sebright): Make this public once we support types other than String. - static Tag createLongTag(TagKeyLong key, @Nullable Long value) { - return TagLong.create(key, value); - } - - /** - * Creates a {@code Tag} from the given {@code Boolean} key and value. - * - * @param key the tag key. - * @param value the tag value, or {@code null} if the key is not paired with a value. - * @return a {@code Tag} with the given key and value. - */ - // TODO(sebright): Make this public once we support types other than String. - static Tag createBooleanTag(TagKeyBoolean key, @Nullable Boolean value) { - return TagBoolean.create(key, value); - } - /** A tag with a {@code String} key and value. */ @Immutable @AutoValue public abstract static class TagString extends Tag { TagString() {} - static TagString create(TagKeyString key, @Nullable TagValueString value) { + /** + * Creates a {@code TagString} from the given {@code String} key and value. + * + * @param key the tag key. + * @param value the tag value, or {@code null} if the key is not paired with a value. + * @return a {@code TagString} with the given key and value. + */ + public static Tag create(TagKeyString key, @Nullable TagValueString value) { return new AutoValue_Tag_TagString(key, value); } @@ -145,7 +117,15 @@ public T matchWithDefault( public abstract static class TagLong extends Tag { TagLong() {} - static TagLong create(TagKeyLong key, @Nullable Long value) { + /** + * Creates a {@code TagLong} from the given {@code Long} key and value. + * + * @param key the tag key. + * @param value the tag value, or {@code null} if the key is not paired with a value. + * @return a {@code TagLong} with the given key and value. + */ + // TODO(sebright): Make this public once we support types other than String. + static Tag create(TagKeyLong key, @Nullable Long value) { return new AutoValue_Tag_TagLong(key, value); } @@ -176,7 +156,15 @@ public T matchWithDefault( public abstract static class TagBoolean extends Tag { TagBoolean() {} - static TagBoolean create(TagKeyBoolean key, @Nullable Boolean value) { + /** + * Creates a {@code TagBoolean} from the given {@code Boolean} key and value. + * + * @param key the tag key. + * @param value the tag value, or {@code null} if the key is not paired with a value. + * @return a {@code TagBoolean} with the given key and value. + */ + // TODO(sebright): Make this public once we support types other than String. + static Tag create(TagKeyBoolean key, @Nullable Boolean value) { return new AutoValue_Tag_TagBoolean(key, value); } diff --git a/core/src/test/java/io/opencensus/tags/TagTest.java b/core/src/test/java/io/opencensus/tags/TagTest.java index 7c40e326d0..981b434b12 100644 --- a/core/src/test/java/io/opencensus/tags/TagTest.java +++ b/core/src/test/java/io/opencensus/tags/TagTest.java @@ -34,26 +34,26 @@ public final class TagTest { @Test public void testGetStringKey() { assertThat( - Tag.createStringTag(TagKeyString.create("k"), TagValueString.create("v")).getKey()) + TagString.create(TagKeyString.create("k"), TagValueString.create("v")).getKey()) .isEqualTo(TagKeyString.create("k")); } @Test public void testGetLongKey() { - assertThat(Tag.createLongTag(TagKeyLong.create("k"), 2L).getKey()) + assertThat(TagLong.create(TagKeyLong.create("k"), 2L).getKey()) .isEqualTo(TagKeyLong.create("k")); } @Test public void testGetBooleanKey() { - assertThat(Tag.createBooleanTag(TagKeyBoolean.create("k"), false).getKey()) + assertThat(TagBoolean.create(TagKeyBoolean.create("k"), false).getKey()) .isEqualTo(TagKeyBoolean.create("k")); } @Test public void testMatchStringTag() { assertThat( - Tag.createStringTag(TagKeyString.create("k1"), TagValueString.create("value")) + TagString.create(TagKeyString.create("k1"), TagValueString.create("value")) .match( new Function() { @Override @@ -79,7 +79,7 @@ public String apply(TagBoolean tag) { @Test public void testMatchLong() { assertThat( - Tag.createLongTag(TagKeyLong.create("k2"), 3L) + TagLong.create(TagKeyLong.create("k2"), 3L) .match( new Function() { @Override @@ -105,7 +105,7 @@ public Long apply(TagBoolean tag) { @Test public void testMatchBoolean() { assertThat( - Tag.createBooleanTag(TagKeyBoolean.create("k3"), false) + TagBoolean.create(TagKeyBoolean.create("k3"), false) .match( new Function() { @Override @@ -132,16 +132,16 @@ public Boolean apply(TagBoolean tag) { public void testTagEquals() { new EqualsTester() .addEqualityGroup( - Tag.createStringTag(TagKeyString.create("Key1"), TagValueString.create("foo")), - Tag.createStringTag(TagKeyString.create("Key1"), TagValueString.create("foo"))) + TagString.create(TagKeyString.create("Key1"), TagValueString.create("foo")), + TagString.create(TagKeyString.create("Key1"), TagValueString.create("foo"))) .addEqualityGroup( - Tag.createLongTag(TagKeyLong.create("Key1"), 100L), - Tag.createLongTag(TagKeyLong.create("Key1"), 100L)) + TagLong.create(TagKeyLong.create("Key1"), 100L), + TagLong.create(TagKeyLong.create("Key1"), 100L)) .addEqualityGroup( - Tag.createBooleanTag(TagKeyBoolean.create("Key1"), true), - Tag.createBooleanTag(TagKeyBoolean.create("Key1"), true)) - .addEqualityGroup(Tag.createBooleanTag(TagKeyBoolean.create("Key2"), true)) - .addEqualityGroup(Tag.createBooleanTag(TagKeyBoolean.create("Key1"), false)) + TagBoolean.create(TagKeyBoolean.create("Key1"), true), + TagBoolean.create(TagKeyBoolean.create("Key1"), true)) + .addEqualityGroup(TagBoolean.create(TagKeyBoolean.create("Key2"), true)) + .addEqualityGroup(TagBoolean.create(TagKeyBoolean.create("Key1"), false)) .testEquals(); } } From 3fc1e56dfad6bd9075a47dd70ef1305296e77562 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 26 Jun 2017 14:29:18 -0700 Subject: [PATCH 0253/1581] Add examples for Tag and TagKey 'match' methods. --- .../src/main/java/io/opencensus/tags/Tag.java | 23 +++++++++++++-- .../main/java/io/opencensus/tags/TagKey.java | 28 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index e571bd7aed..202a4634d4 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -35,7 +35,16 @@ public abstract class Tag { /** * Applies a function to the tag's key and value. The function that is called depends on the type - * of the tag. This is similar to the visitor pattern. + * of the tag. This is similar to the visitor pattern. For example, this code serializes a {@code + * Tag}. + * + *
            {@code
            +   * byte[] serializedValue =
            +   *     tag.match(
            +   *         stringTag -> serializeString(stringTag.getValue().asString()),
            +   *         longTag -> serializeLong(longTag.getValue()),
            +   *         booleanTag -> serializeBoolean(booleanTag.getValue()));
            +   * }
            * * @param stringFunction the function to call when the tag has a {@code String} value. * @param longFunction the function to call when the tag has a {@code Long} value. @@ -54,7 +63,17 @@ public T match( /** * Applies a function to the tag's key and value. This method is like {@link #match(Function, * Function, Function)}, except that it has a default case, for backwards compatibility when tag - * types are added. + * types are added. For example, this code serializes a {@code Tag} and tries to handle new tag + * types by calling {@code toString()}. + * + *
            {@code
            +   * byte[] serializedValue =
            +   *     tag.matchWithDefault(
            +   *         stringTag -> serializeString(stringTag.getValue().asString()),
            +   *         longTag -> serializeLong(longTag.getValue()),
            +   *         booleanTag -> serializeBoolean(booleanTag.getValue()),
            +   *         unknownTag -> serializeString(unknownTag.toString()));
            +   * }
            * * @param stringFunction the function to call when the tag has a {@code String} value. * @param longFunction the function to call when the tag has a {@code Long} value. diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index 68697a2bd1..e7655ac92d 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -32,7 +32,16 @@ public abstract class TagKey { /** * Applies a function to the {@code TagKey} subclass. The function that is called depends on the - * type of the tag key. This is similar to the visitor pattern. + * type of the tag key. This is similar to the visitor pattern. For example, this code creates a + * {@code Tag} from a {@code TagKey}. + * + *
            {@code
            +   * Tag tag =
            +   *     tagKey.match(
            +   *         stringKey -> TagString.create(stringKey, TagValueString.create("string value")),
            +   *         longKey -> TagLong.create(longKey, 100L),
            +   *         booleanKey -> TagBoolean.create(booleanKey, true));
            +   * }
            * * @param stringFunction the function to call when the {@code TagKey} is a {@code TagKeyString}. * @param longFunction the function to call when the {@code TagKey} is a {@code TagKeyLong}. @@ -52,7 +61,22 @@ public T match( /** * Applies a function to the {@code TagKey} subclass. This method is like {@link #match(Function, * Function, Function)}, except that it has a default case, for backwards compatibility when tag - * types are added. + * types are added. For example, this code creates a {@code Tag} from a {@code TagKey}. It handles + * new tag types by logging an error and returning a {@code TagKeyString}. + * + *
            {@code
            +   * Tag tag =
            +   *     tagKey.matchWithDefault(
            +   *         stringKey -> TagString.create(stringKey, TagValueString.create("string value")),
            +   *         longKey -> TagLong.create(longKey, 100L),
            +   *         booleanKey -> TagBoolean.create(booleanKey, true),
            +   *         unknownKey -> {
            +   *           logger.log(Level.WARNING, "Unknown tag key type: " + unknownKey.toString());
            +   *           return TagString.create(
            +   *               TagKeyString.create(unknownKey.getName()),
            +   *               TagValueString.create("string value"));
            +   *         });
            +   * }
            * * @param stringFunction the function to call when the {@code TagKey} is a {@code TagKeyString}. * @param longFunction the function to call when the {@code TagKey} is a {@code TagKeyLong}. From 62d23e9b3b307605547e45742150f0fe71350f5b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 27 Jun 2017 18:19:08 -0700 Subject: [PATCH 0254/1581] Use non-null TagValueStrings, longs, and booleans as Tag values. --- .../src/main/java/io/opencensus/tags/Tag.java | 53 +++++++++---------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index 202a4634d4..c1b7a1ae93 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -18,11 +18,9 @@ import io.opencensus.tags.TagKey.TagKeyBoolean; import io.opencensus.tags.TagKey.TagKeyLong; import io.opencensus.tags.TagKey.TagKeyString; -import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; -/** {@link TagKey} paired with an optional value. */ -// TODO(sebright): Do we also need to represent TagKeys paired with non-null values? +/** {@link TagKey} paired with a value. */ @Immutable public abstract class Tag { @@ -47,8 +45,8 @@ public abstract class Tag { * }
            * * @param stringFunction the function to call when the tag has a {@code String} value. - * @param longFunction the function to call when the tag has a {@code Long} value. - * @param booleanFunction the function to call when the tag has a {@code Boolean} value. + * @param longFunction the function to call when the tag has a {@code long} value. + * @param booleanFunction the function to call when the tag has a {@code boolean} value. * @param The result type of the function. * @return The result of calling the function that matches the tag's type. */ @@ -76,10 +74,10 @@ public T match( * }
            * * @param stringFunction the function to call when the tag has a {@code String} value. - * @param longFunction the function to call when the tag has a {@code Long} value. - * @param booleanFunction the function to call when the tag has a {@code Boolean} value. + * @param longFunction the function to call when the tag has a {@code long} value. + * @param booleanFunction the function to call when the tag has a {@code boolean} value. * @param defaultFunction the function to call when the tag has a value other than {@code String}, - * {@code Long}, or {@code Boolean}. + * {@code long}, or {@code boolean}. * @param The result type of the function. * @return The result of calling the function that matches the tag's type. */ @@ -102,10 +100,10 @@ public abstract static class TagString extends Tag { * Creates a {@code TagString} from the given {@code String} key and value. * * @param key the tag key. - * @param value the tag value, or {@code null} if the key is not paired with a value. + * @param value the tag value. * @return a {@code TagString} with the given key and value. */ - public static Tag create(TagKeyString key, @Nullable TagValueString value) { + public static Tag create(TagKeyString key, TagValueString value) { return new AutoValue_Tag_TagString(key, value); } @@ -113,11 +111,10 @@ public static Tag create(TagKeyString key, @Nullable TagValueString value) { public abstract TagKeyString getKey(); /** - * Returns the associated tag value, or {@code null} if the key is not paired with a value. + * Returns the associated tag value. * - * @return the associated tag value, or {@code null} if the key is not paired with a value. + * @return the associated tag value. */ - @Nullable public abstract TagValueString getValue(); @Override @@ -130,21 +127,21 @@ public T matchWithDefault( } } - /** A tag with a {@code Long} key and value. */ + /** A tag with a {@code long} key and value. */ @Immutable @AutoValue public abstract static class TagLong extends Tag { TagLong() {} /** - * Creates a {@code TagLong} from the given {@code Long} key and value. + * Creates a {@code TagLong} from the given {@code long} key and value. * * @param key the tag key. - * @param value the tag value, or {@code null} if the key is not paired with a value. + * @param value the tag value. * @return a {@code TagLong} with the given key and value. */ // TODO(sebright): Make this public once we support types other than String. - static Tag create(TagKeyLong key, @Nullable Long value) { + static Tag create(TagKeyLong key, long value) { return new AutoValue_Tag_TagLong(key, value); } @@ -152,12 +149,11 @@ static Tag create(TagKeyLong key, @Nullable Long value) { public abstract TagKeyLong getKey(); /** - * Returns the associated tag value, or {@code null} if the key is not paired with a value. + * Returns the associated tag value. * - * @return the associated tag value, or {@code null} if the key is not paired with a value. + * @return the associated tag value. */ - @Nullable - public abstract Long getValue(); + public abstract long getValue(); @Override public T matchWithDefault( @@ -169,21 +165,21 @@ public T matchWithDefault( } } - /** A tag with a {@code Boolean} key and value. */ + /** A tag with a {@code boolean} key and value. */ @Immutable @AutoValue public abstract static class TagBoolean extends Tag { TagBoolean() {} /** - * Creates a {@code TagBoolean} from the given {@code Boolean} key and value. + * Creates a {@code TagBoolean} from the given {@code boolean} key and value. * * @param key the tag key. - * @param value the tag value, or {@code null} if the key is not paired with a value. + * @param value the tag value. * @return a {@code TagBoolean} with the given key and value. */ // TODO(sebright): Make this public once we support types other than String. - static Tag create(TagKeyBoolean key, @Nullable Boolean value) { + static Tag create(TagKeyBoolean key, boolean value) { return new AutoValue_Tag_TagBoolean(key, value); } @@ -191,12 +187,11 @@ static Tag create(TagKeyBoolean key, @Nullable Boolean value) { public abstract TagKeyBoolean getKey(); /** - * Returns the associated tag value, or {@code null} if the key is not paired with a value. + * Returns the associated tag value. * - * @return the associated tag value, or {@code null} if the key is not paired with a value. + * @return the associated tag value. */ - @Nullable - public abstract Boolean getValue(); + public abstract boolean getValue(); @Override public T matchWithDefault( From ee656b5828e65cff3bde91e9975976e08faa666e Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 27 Jun 2017 18:27:25 -0700 Subject: [PATCH 0255/1581] Remove TODO. --- core/src/main/java/io/opencensus/tags/TagValueString.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/io/opencensus/tags/TagValueString.java b/core/src/main/java/io/opencensus/tags/TagValueString.java index 5cb68d299b..5f3e5bdaee 100644 --- a/core/src/main/java/io/opencensus/tags/TagValueString.java +++ b/core/src/main/java/io/opencensus/tags/TagValueString.java @@ -20,7 +20,6 @@ import javax.annotation.concurrent.Immutable; /** A validated tag value associated with a {@link TagKeyString}. */ -// TODO(sebright): Is there any reason to use a TagValue class for booleans and longs, too? @Immutable @AutoValue public abstract class TagValueString { From 3dc96a9d88669a5d14c2bf6b1d62a53a2cbf7c45 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 6 Jul 2017 21:23:17 -0700 Subject: [PATCH 0256/1581] Remove Tag and TagKey "match" methods that don't have default cases. The remaining "match" methods are backwards compatible. This commit also renames "matchWithDefault" to "match". --- .../src/main/java/io/opencensus/tags/Tag.java | 45 ++++-------------- .../main/java/io/opencensus/tags/TagKey.java | 46 ++++--------------- .../java/io/opencensus/tags/TagUtils.java | 38 --------------- .../java/io/opencensus/tags/TagKeyTest.java | 10 ++-- .../test/java/io/opencensus/tags/TagTest.java | 10 ++-- .../java/io/opencensus/tags/TagUtilsTest.java | 26 ----------- 6 files changed, 30 insertions(+), 145 deletions(-) delete mode 100644 core/src/main/java/io/opencensus/tags/TagUtils.java delete mode 100644 core/src/test/java/io/opencensus/tags/TagUtilsTest.java diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index c1b7a1ae93..ccf683154c 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -33,42 +33,16 @@ public abstract class Tag { /** * Applies a function to the tag's key and value. The function that is called depends on the type - * of the tag. This is similar to the visitor pattern. For example, this code serializes a {@code - * Tag}. + * of the tag. This is similar to the visitor pattern. {@code match} also takes a function to + * handle the default case, for backwards compatibility when tag types are added. For example, + * this code serializes a {@code Tag} and tries to handle new tag types by calling {@code + * toString()}. * *
            {@code
                * byte[] serializedValue =
                *     tag.match(
                *         stringTag -> serializeString(stringTag.getValue().asString()),
                *         longTag -> serializeLong(longTag.getValue()),
            -   *         booleanTag -> serializeBoolean(booleanTag.getValue()));
            -   * }
            - * - * @param stringFunction the function to call when the tag has a {@code String} value. - * @param longFunction the function to call when the tag has a {@code long} value. - * @param booleanFunction the function to call when the tag has a {@code boolean} value. - * @param The result type of the function. - * @return The result of calling the function that matches the tag's type. - */ - public T match( - Function stringFunction, - Function longFunction, - Function booleanFunction) { - return matchWithDefault( - stringFunction, longFunction, booleanFunction, TagUtils.throwAssertionError()); - } - - /** - * Applies a function to the tag's key and value. This method is like {@link #match(Function, - * Function, Function)}, except that it has a default case, for backwards compatibility when tag - * types are added. For example, this code serializes a {@code Tag} and tries to handle new tag - * types by calling {@code toString()}. - * - *
            {@code
            -   * byte[] serializedValue =
            -   *     tag.matchWithDefault(
            -   *         stringTag -> serializeString(stringTag.getValue().asString()),
            -   *         longTag -> serializeLong(longTag.getValue()),
                *         booleanTag -> serializeBoolean(booleanTag.getValue()),
                *         unknownTag -> serializeString(unknownTag.toString()));
                * }
            @@ -81,10 +55,7 @@ public T match( * @param The result type of the function. * @return The result of calling the function that matches the tag's type. */ - // TODO(sebright): How should we deal with the possibility of adding more tag types in the future? - // Will this method work? What type of parameter should we use for the default - // case? Should we remove the non-backwards compatible "match" method? - public abstract T matchWithDefault( + public abstract T match( Function stringFunction, Function longFunction, Function booleanFunction, @@ -118,7 +89,7 @@ public static Tag create(TagKeyString key, TagValueString value) { public abstract TagValueString getValue(); @Override - public T matchWithDefault( + public T match( Function stringFunction, Function longFunction, Function booleanFunction, @@ -156,7 +127,7 @@ static Tag create(TagKeyLong key, long value) { public abstract long getValue(); @Override - public T matchWithDefault( + public T match( Function stringFunction, Function longFunction, Function booleanFunction, @@ -194,7 +165,7 @@ static Tag create(TagKeyBoolean key, boolean value) { public abstract boolean getValue(); @Override - public T matchWithDefault( + public T match( Function stringFunction, Function longFunction, Function booleanFunction, diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index e7655ac92d..d63a94122d 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -32,43 +32,16 @@ public abstract class TagKey { /** * Applies a function to the {@code TagKey} subclass. The function that is called depends on the - * type of the tag key. This is similar to the visitor pattern. For example, this code creates a - * {@code Tag} from a {@code TagKey}. + * type of the tag key. This is similar to the visitor pattern. {@code match} also takes a + * function to handle the default case, for backwards compatibility when tag types are added. For + * example, this code creates a {@code Tag} from a {@code TagKey}. It handles new tag types by + * logging an error and returning a {@code TagKeyString}. * *
            {@code
                * Tag tag =
                *     tagKey.match(
                *         stringKey -> TagString.create(stringKey, TagValueString.create("string value")),
                *         longKey -> TagLong.create(longKey, 100L),
            -   *         booleanKey -> TagBoolean.create(booleanKey, true));
            -   * }
            - * - * @param stringFunction the function to call when the {@code TagKey} is a {@code TagKeyString}. - * @param longFunction the function to call when the {@code TagKey} is a {@code TagKeyLong}. - * @param booleanFunction the function to call when the {@code TagKey} is a {@code TagKeyBoolean}. - * @param The result type of the function. - * @return The result of calling the function that matches the tag key's type. - */ - // TODO(sebright): Should we make this public in the first release? - public T match( - Function stringFunction, - Function longFunction, - Function booleanFunction) { - return matchWithDefault( - stringFunction, longFunction, booleanFunction, TagUtils.throwAssertionError()); - } - - /** - * Applies a function to the {@code TagKey} subclass. This method is like {@link #match(Function, - * Function, Function)}, except that it has a default case, for backwards compatibility when tag - * types are added. For example, this code creates a {@code Tag} from a {@code TagKey}. It handles - * new tag types by logging an error and returning a {@code TagKeyString}. - * - *
            {@code
            -   * Tag tag =
            -   *     tagKey.matchWithDefault(
            -   *         stringKey -> TagString.create(stringKey, TagValueString.create("string value")),
            -   *         longKey -> TagLong.create(longKey, 100L),
                *         booleanKey -> TagBoolean.create(booleanKey, true),
                *         unknownKey -> {
                *           logger.log(Level.WARNING, "Unknown tag key type: " + unknownKey.toString());
            @@ -87,10 +60,7 @@ public  T match(
                * @return The result of calling the function that matches the tag key's type.
                */
               // TODO(sebright): Should we make this public in the first release?
            -  // TODO(sebright): How should we deal with the possibility of adding more tag types in the future?
            -  //                 Will this method work? What type of parameter should we use for the default
            -  //                 case? Should we remove the non-backwards compatible "match" method?
            -  public abstract  T matchWithDefault(
            +  public abstract  T match(
                   Function stringFunction,
                   Function longFunction,
                   Function booleanFunction,
            @@ -121,7 +91,7 @@ public static TagKeyString create(String name) {
                 }
             
                 @Override
            -    public  T matchWithDefault(
            +    public  T match(
                     Function stringFunction,
                     Function longFunction,
                     Function booleanFunction,
            @@ -156,7 +126,7 @@ static TagKeyLong create(String name) {
                 }
             
                 @Override
            -    public  T matchWithDefault(
            +    public  T match(
                     Function stringFunction,
                     Function longFunction,
                     Function booleanFunction,
            @@ -191,7 +161,7 @@ static TagKeyBoolean create(String name) {
                 }
             
                 @Override
            -    public  T matchWithDefault(
            +    public  T match(
                     Function stringFunction,
                     Function longFunction,
                     Function booleanFunction,
            diff --git a/core/src/main/java/io/opencensus/tags/TagUtils.java b/core/src/main/java/io/opencensus/tags/TagUtils.java
            deleted file mode 100644
            index 1da34e3285..0000000000
            --- a/core/src/main/java/io/opencensus/tags/TagUtils.java
            +++ /dev/null
            @@ -1,38 +0,0 @@
            -/*
            - * Copyright 2017, Google Inc.
            - * Licensed under the Apache License, Version 2.0 (the "License");
            - * you may not use this file except in compliance with the License.
            - * You may obtain a copy of the License at
            - *     http://www.apache.org/licenses/LICENSE-2.0
            - * Unless required by applicable law or agreed to in writing, software
            - * distributed under the License is distributed on an "AS IS" BASIS,
            - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            - * See the License for the specific language governing permissions and
            - * limitations under the License.
            - */
            -
            -package io.opencensus.tags;
            -
            -import io.opencensus.common.Function;
            -
            -/**
            - * Utility methods for the tag classes.
            - */
            -final class TagUtils {
            -  private TagUtils() {}
            -
            -  static  Function throwAssertionError() {
            -    // It is safe to cast a producer of Void to anything, because Void is always null.
            -    @SuppressWarnings("unchecked")
            -    Function function = (Function) THROW_ASSERTION_ERROR;
            -    return function;
            -  }
            -
            -  private static final Function THROW_ASSERTION_ERROR =
            -      new Function() {
            -        @Override
            -        public Void apply(Object tag) {
            -          throw new AssertionError();
            -        }
            -      };
            -}
            diff --git a/core/src/test/java/io/opencensus/tags/TagKeyTest.java b/core/src/test/java/io/opencensus/tags/TagKeyTest.java
            index 60e68d287e..0805fd7499 100644
            --- a/core/src/test/java/io/opencensus/tags/TagKeyTest.java
            +++ b/core/src/test/java/io/opencensus/tags/TagKeyTest.java
            @@ -17,6 +17,7 @@
             
             import com.google.common.testing.EqualsTester;
             import io.opencensus.common.Function;
            +import io.opencensus.common.Functions;
             import io.opencensus.tags.TagKey.TagKeyBoolean;
             import io.opencensus.tags.TagKey.TagKeyLong;
             import io.opencensus.tags.TagKey.TagKeyString;
            @@ -81,7 +82,8 @@ public String apply(TagKeyLong tag) {
                                   public String apply(TagKeyBoolean tag) {
                                     throw new AssertionError();
                                   }
            -                    }))
            +                    },
            +                    Functions.throwIllegalArgumentException()))
                     .isEqualTo("key");
               }
             
            @@ -107,7 +109,8 @@ public String apply(TagKeyLong tag) {
                                   public String apply(TagKeyBoolean tag) {
                                     throw new AssertionError();
                                   }
            -                    }))
            +                    },
            +                    Functions.throwIllegalArgumentException()))
                     .isEqualTo("key");
               }
             
            @@ -133,7 +136,8 @@ public String apply(TagKeyLong tag) {
                                   public String apply(TagKeyBoolean tag) {
                                     return tag.getName();
                                   }
            -                    }))
            +                    },
            +                    Functions.throwIllegalArgumentException()))
                     .isEqualTo("key");
               }
             
            diff --git a/core/src/test/java/io/opencensus/tags/TagTest.java b/core/src/test/java/io/opencensus/tags/TagTest.java
            index 981b434b12..483be6b6d1 100644
            --- a/core/src/test/java/io/opencensus/tags/TagTest.java
            +++ b/core/src/test/java/io/opencensus/tags/TagTest.java
            @@ -17,6 +17,7 @@
             
             import com.google.common.testing.EqualsTester;
             import io.opencensus.common.Function;
            +import io.opencensus.common.Functions;
             import io.opencensus.tags.Tag.TagBoolean;
             import io.opencensus.tags.Tag.TagLong;
             import io.opencensus.tags.Tag.TagString;
            @@ -72,7 +73,8 @@ public String apply(TagLong tag) {
                                   public String apply(TagBoolean tag) {
                                     throw new AssertionError();
                                   }
            -                    }))
            +                    },
            +                    Functions.throwIllegalArgumentException()))
                     .isEqualTo("value");
               }
             
            @@ -98,7 +100,8 @@ public Long apply(TagLong tag) {
                                   public Long apply(TagBoolean tag) {
                                     throw new AssertionError();
                                   }
            -                    }))
            +                    },
            +                    Functions.throwIllegalArgumentException()))
                     .isEqualTo(3L);
               }
             
            @@ -124,7 +127,8 @@ public Boolean apply(TagLong tag) {
                                   public Boolean apply(TagBoolean tag) {
                                     return tag.getValue();
                                   }
            -                    }))
            +                    },
            +                    Functions.throwIllegalArgumentException()))
                     .isEqualTo(false);
               }
             
            diff --git a/core/src/test/java/io/opencensus/tags/TagUtilsTest.java b/core/src/test/java/io/opencensus/tags/TagUtilsTest.java
            deleted file mode 100644
            index ca86b53479..0000000000
            --- a/core/src/test/java/io/opencensus/tags/TagUtilsTest.java
            +++ /dev/null
            @@ -1,26 +0,0 @@
            -/*
            - * Copyright 2017, Google Inc.
            - * Licensed under the Apache License, Version 2.0 (the "License");
            - * you may not use this file except in compliance with the License.
            - * You may obtain a copy of the License at
            - *     http://www.apache.org/licenses/LICENSE-2.0
            - * Unless required by applicable law or agreed to in writing, software
            - * distributed under the License is distributed on an "AS IS" BASIS,
            - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            - * See the License for the specific language governing permissions and
            - * limitations under the License.
            - */
            -
            -package io.opencensus.tags;
            -
            -import org.junit.Test;
            -
            -/**
            - * Tests for {@link TagUtils}.
            - */
            -public class TagUtilsTest {
            -  @Test(expected = AssertionError.class)
            -  public void testThrowAssertionError() {
            -    TagUtils.throwAssertionError().apply("ignored");
            -  }
            -}
            
            From 04f11bb81d1899347171bff1ca471fec75fc46cd Mon Sep 17 00:00:00 2001
            From: Kristen Kozak 
            Date: Thu, 6 Jul 2017 21:23:17 -0700
            Subject: [PATCH 0257/1581] Use Tag subclasses for Tag factory method return
             types.
            
            ---
             core/src/main/java/io/opencensus/tags/Tag.java | 6 +++---
             1 file changed, 3 insertions(+), 3 deletions(-)
            
            diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java
            index ccf683154c..587e2203ee 100644
            --- a/core/src/main/java/io/opencensus/tags/Tag.java
            +++ b/core/src/main/java/io/opencensus/tags/Tag.java
            @@ -74,7 +74,7 @@ public abstract static class TagString extends Tag {
                  * @param value the tag value.
                  * @return a {@code TagString} with the given key and value.
                  */
            -    public static Tag create(TagKeyString key, TagValueString value) {
            +    public static TagString create(TagKeyString key, TagValueString value) {
                   return new AutoValue_Tag_TagString(key, value);
                 }
             
            @@ -112,7 +112,7 @@ public abstract static class TagLong extends Tag {
                  * @return a {@code TagLong} with the given key and value.
                  */
                 // TODO(sebright): Make this public once we support types other than String.
            -    static Tag create(TagKeyLong key, long value) {
            +    static TagLong create(TagKeyLong key, long value) {
                   return new AutoValue_Tag_TagLong(key, value);
                 }
             
            @@ -150,7 +150,7 @@ public abstract static class TagBoolean extends Tag {
                  * @return a {@code TagBoolean} with the given key and value.
                  */
                 // TODO(sebright): Make this public once we support types other than String.
            -    static Tag create(TagKeyBoolean key, boolean value) {
            +    static TagBoolean create(TagKeyBoolean key, boolean value) {
                   return new AutoValue_Tag_TagBoolean(key, value);
                 }
             
            
            From 8826e06606fc40bb45bf79fc2db6a04cecb8017d Mon Sep 17 00:00:00 2001
            From: Kristen Kozak 
            Date: Thu, 6 Jul 2017 21:23:17 -0700
            Subject: [PATCH 0258/1581] Remove redundant copy of "tags" HashMap.
            
            ---
             core/src/main/java/io/opencensus/tags/TagContext.java | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java
            index 480377376d..ccfc94d35b 100644
            --- a/core/src/main/java/io/opencensus/tags/TagContext.java
            +++ b/core/src/main/java/io/opencensus/tags/TagContext.java
            @@ -145,7 +145,7 @@ public Builder clear(TagKey key) {
                  * @return a {@code TagContext} with the same tags as this builder.
                  */
                 public TagContext build() {
            -      return new TagContext(new HashMap(tags));
            +      return new TagContext(tags);
                 }
               }
             }
            
            From 13879bfe2d6dd8d3f7072d3cba0bbeb1dc85cc4d Mon Sep 17 00:00:00 2001
            From: Kristen Kozak 
            Date: Thu, 6 Jul 2017 21:23:17 -0700
            Subject: [PATCH 0259/1581] Add example without lambdas to Tag.match Javadoc.
            
            ---
             .../src/main/java/io/opencensus/tags/Tag.java | 31 +++++++++++++++++++
             1 file changed, 31 insertions(+)
            
            diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java
            index 587e2203ee..36630e4b10 100644
            --- a/core/src/main/java/io/opencensus/tags/Tag.java
            +++ b/core/src/main/java/io/opencensus/tags/Tag.java
            @@ -47,6 +47,37 @@ public abstract class Tag {
                *         unknownTag -> serializeString(unknownTag.toString()));
                * }
            * + *

            Without lambdas: + * + *

            
            +   *   byte[] serializedValue =
            +   *       tag.match(
            +   *           new Function<TagString, String>() {
            +   *             @Override
            +   *             public String apply(TagString stringTag) {
            +   *               return serializeString(stringTag.getValue().asString());
            +   *             }
            +   *           },
            +   *           new Function<TagLong, String>() {
            +   *             @Override
            +   *             public String apply(TagLong longTag) {
            +   *               serializeLong(longTag.getValue());
            +   *             }
            +   *           },
            +   *           new Function<TagBoolean, String>() {
            +   *             @Override
            +   *             public String apply(TagBoolean booleanTag) {
            +   *               serializeBoolean(booleanTag.getValue());
            +   *             }
            +   *           },
            +   *           new Function<Tag, String>() {
            +   *             @Override
            +   *             public String apply(TagBoolean unknownTag) {
            +   *               serializeString(unknownTag.toString());
            +   *             }
            +   *           });
            +   * 
            + * * @param stringFunction the function to call when the tag has a {@code String} value. * @param longFunction the function to call when the tag has a {@code long} value. * @param booleanFunction the function to call when the tag has a {@code boolean} value. From 3a2293b00efe39342f7507f13be1a65878dc87fb Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 6 Jul 2017 21:23:17 -0700 Subject: [PATCH 0260/1581] Add example without lambdas to TagKey.match Javadoc. --- .../main/java/io/opencensus/tags/TagKey.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index d63a94122d..b99068e3b3 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -51,6 +51,40 @@ public abstract class TagKey { * }); * }
            * + *

            Without lambdas: + * + *

            
            +   *   Tag tag =
            +   *       tagKey.match(
            +   *           new Function<TagKeyString, Tag>() {
            +   *             @Override
            +   *             public Tag apply(TagKeyString stringKey) {
            +   *               return TagString.create(stringKey, TagValueString.create("string value"));
            +   *             }
            +   *           },
            +   *           new Function<TagKeyLong, Tag>() {
            +   *             @Override
            +   *             public Tag apply(TagKeyLong longKey) {
            +   *               return TagLong.create(longKey, 100L);
            +   *             }
            +   *           },
            +   *           new Function<TagKeyBoolean, Tag>() {
            +   *             @Override
            +   *             public Tag apply(TagKeyBoolean booleanKey) {
            +   *               return TagBoolean.create(booleanKey, true);
            +   *             }
            +   *           },
            +   *           new Function<TagKey, Tag>() {
            +   *             @Override
            +   *             public Tag apply(TagKey unknownKey) {
            +   *               logger.log(Level.WARNING, "Unknown tag key type: " + unknownKey.toString());
            +   *               return TagString.create(
            +   *                   TagKeyString.create(unknownKey.getName()),
            +   *                   TagValueString.create("string value"));
            +   *             }
            +   *           });
            +   * 
            + * * @param stringFunction the function to call when the {@code TagKey} is a {@code TagKeyString}. * @param longFunction the function to call when the {@code TagKey} is a {@code TagKeyLong}. * @param booleanFunction the function to call when the {@code TagKey} is a {@code TagKeyBoolean}. From 945236db8bd03b1761fa4d287d0f134894a30782 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 6 Jul 2017 23:00:34 -0700 Subject: [PATCH 0261/1581] Change hasRemoteParent to be Boolean where null means root Span. (#427) --- .../main/java/io/opencensus/trace/Sampler.java | 15 ++++++++------- .../java/io/opencensus/trace/export/SpanData.java | 14 +++++++++----- .../trace/samplers/AlwaysSampleSampler.java | 2 +- .../trace/samplers/NeverSampleSampler.java | 2 +- .../trace/samplers/ProbabilitySampler.java | 2 +- .../io/opencensus/trace/export/SpanDataTest.java | 4 ++-- .../java/io/opencensus/trace/SpanBuilderImpl.java | 11 +++++++---- .../main/java/io/opencensus/trace/SpanImpl.java | 9 +++++---- .../io/opencensus/trace/SpanBuilderImplTest.java | 12 ++++++++---- 9 files changed, 42 insertions(+), 29 deletions(-) diff --git a/api/src/main/java/io/opencensus/trace/Sampler.java b/api/src/main/java/io/opencensus/trace/Sampler.java index 327bfa422f..3277a4ea0e 100644 --- a/api/src/main/java/io/opencensus/trace/Sampler.java +++ b/api/src/main/java/io/opencensus/trace/Sampler.java @@ -21,19 +21,20 @@ public abstract class Sampler { /** * Called during {@link Span} creation to make a sampling decision. * - * @param parentContext The parent {@code Span} {@link SpanContext}. May be {@code null} if this + * @param parentContext the parent span's {@link SpanContext}. {@code null} if this is a root + * span. + * @param hasRemoteParent {@code true} if the parent {@code Span} is remote. {@code null} if this * is a root span. - * @param remoteParent true if the parentContext is remote. - * @param traceId The {@link TraceId} for the new {@code Span}. This will be identical to that in + * @param traceId the {@link TraceId} for the new {@code Span}. This will be identical to that in * the parentContext, unless this is a root span. - * @param spanId The span ID for the new {@code Span}. - * @param name The name of the new {@code Span}. - * @param parentLinks The parentLinks associated with the new {@code Span}. + * @param spanId the span ID for the new {@code Span}. + * @param name the name of the new {@code Span}. + * @param parentLinks the parentLinks associated with the new {@code Span}. * @return {@code true} if the {@code Span} is sampled. */ public abstract boolean shouldSample( @Nullable SpanContext parentContext, - boolean remoteParent, + @Nullable Boolean hasRemoteParent, TraceId traceId, SpanId spanId, String name, diff --git a/api/src/main/java/io/opencensus/trace/export/SpanData.java b/api/src/main/java/io/opencensus/trace/export/SpanData.java index b4d5d5c70b..bd4daa866f 100644 --- a/api/src/main/java/io/opencensus/trace/export/SpanData.java +++ b/api/src/main/java/io/opencensus/trace/export/SpanData.java @@ -44,7 +44,8 @@ public abstract class SpanData { * @param context the {@code SpanContext} of the {@code Span}. * @param parentSpanId the parent {@code SpanId} of the {@code Span}. {@code null} if the {@code * Span} is a root. - * @param hasRemoteParent {@code true} if the parent is on a different process. + * @param hasRemoteParent {@code true} if the parent {@code Span} is remote. {@code null} if this + * is a root span. * @param name the name of the {@code Span}. * @param startTimestamp the start {@code Timestamp} of the {@code Span}. * @param attributes the attributes associated with the {@code Span}. @@ -61,7 +62,7 @@ public abstract class SpanData { public static SpanData create( SpanContext context, @Nullable SpanId parentSpanId, - boolean hasRemoteParent, + @Nullable Boolean hasRemoteParent, String name, Timestamp startTimestamp, Attributes attributes, @@ -102,11 +103,14 @@ public static SpanData create( public abstract SpanId getParentSpanId(); /** - * Returns {@code true} if the parent is on a different process. + * Returns {@code true} if the parent is on a different process. {@code null} if this is a root + * span. * - * @return {@code true} if the parent is on a different process. + * @return {@code true} if the parent is on a different process. {@code null} if this is a root + * span. */ - public abstract boolean getHasRemoteParent(); + @Nullable + public abstract Boolean getHasRemoteParent(); /** * Returns the name of this {@code Span}. diff --git a/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java b/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java index e20265d9f8..b8a2c750c1 100644 --- a/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java +++ b/api/src/main/java/io/opencensus/trace/samplers/AlwaysSampleSampler.java @@ -32,7 +32,7 @@ final class AlwaysSampleSampler extends Sampler { @Override public boolean shouldSample( @Nullable SpanContext parentContext, - boolean remoteParent, + @Nullable Boolean hasRemoteParent, TraceId traceId, SpanId spanId, String name, diff --git a/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java b/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java index f773f3a7bb..f40a94755f 100644 --- a/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java +++ b/api/src/main/java/io/opencensus/trace/samplers/NeverSampleSampler.java @@ -32,7 +32,7 @@ final class NeverSampleSampler extends Sampler { @Override public boolean shouldSample( @Nullable SpanContext parentContext, - boolean remoteParent, + @Nullable Boolean hasRemoteParent, TraceId traceId, SpanId spanId, String name, diff --git a/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java b/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java index 7a4029e5ca..f76c498fce 100644 --- a/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java +++ b/api/src/main/java/io/opencensus/trace/samplers/ProbabilitySampler.java @@ -71,7 +71,7 @@ static ProbabilitySampler create(double probability) { @Override public final boolean shouldSample( @Nullable SpanContext parentContext, - boolean remoteParent, + @Nullable Boolean hasRemoteParent, TraceId traceId, SpanId spanId, String name, diff --git a/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java index 8212d4b9a5..21fc79451c 100644 --- a/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java +++ b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java @@ -126,7 +126,7 @@ public void spanData_RootActiveSpan() { SpanData.create( spanContext, null, - false, + null, SPAN_NAME, startTimestamp, attributes, @@ -138,7 +138,7 @@ public void spanData_RootActiveSpan() { null); assertThat(spanData.getContext()).isEqualTo(spanContext); assertThat(spanData.getParentSpanId()).isNull(); - assertThat(spanData.getHasRemoteParent()).isFalse(); + assertThat(spanData.getHasRemoteParent()).isNull(); assertThat(spanData.getName()).isEqualTo(SPAN_NAME); assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); assertThat(spanData.getAttributes()).isEqualTo(attributes); diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java index 66f6451840..b853f7812a 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java @@ -40,7 +40,7 @@ final class SpanBuilderImpl extends SpanBuilder { private SpanImpl startSpanInternal( @Nullable SpanContext parent, - boolean hasRemoteParent, + @Nullable Boolean hasRemoteParent, String name, Sampler sampler, List parentLinks, @@ -57,7 +57,7 @@ private SpanImpl startSpanInternal( traceId = TraceId.generateRandomId(random); traceOptionsBuilder = TraceOptions.builder(); // This is a root span so no remote or local parent. - hasRemoteParent = false; + hasRemoteParent = null; } else { // New child span. traceId = parent.getTraceId(); @@ -123,12 +123,13 @@ private SpanBuilderImpl( @Override public SpanImpl startSpan() { SpanContext parentContext = remoteParentSpanContext; - boolean hasRemoteParent = parentContext != null; + Boolean hasRemoteParent = Boolean.TRUE; TimestampConverter timestampConverter = null; - if (!hasRemoteParent) { + if (remoteParentSpanContext == null) { // This is not a child of a remote Span. Get the parent SpanContext from the parent Span if // any. Span parent = this.parent; + hasRemoteParent = Boolean.FALSE; if (parent != null) { parentContext = parent.getContext(); // Pass the timestamp converter from the parent to ensure that the recorded events are in @@ -136,6 +137,8 @@ public SpanImpl startSpan() { if (parent instanceof SpanImpl) { timestampConverter = ((SpanImpl) parent).getTimestampConverter(); } + } else { + hasRemoteParent = null; } } return startSpanInternal( diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java index e32f0c90a4..aecf06a0d8 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java @@ -44,7 +44,7 @@ public final class SpanImpl extends Span implements Element { // The parent SpanId of this span. Null if this is a root span. private final SpanId parentSpanId; // True if the parent is on a different process. - private final boolean hasRemoteParent; + private final Boolean hasRemoteParent; // Active trace params when the Span was created. private final TraceParams traceParams; // Handler called when the span starts and ends. @@ -93,7 +93,8 @@ public final class SpanImpl extends Span implements Element { * @param options the options for the new span, importantly Options.RECORD_EVENTS. * @param name the displayed name for the new span. * @param parentSpanId the span_id of the parent span, or null if the new span is a root span. - * @param hasRemoteParent true if the parent span is in another process. + * @param hasRemoteParent {@code true} if the parentContext is remote. {@code null} if this is a + * root span. * @param traceParams trace parameters like sampler and probability. * @param startEndHandler handler called when the span starts and ends. * @param timestampConverter null if the span is a root span or the parent is not sampled. If the @@ -108,7 +109,7 @@ public static SpanImpl startSpan( @Nullable EnumSet options, String name, @Nullable SpanId parentSpanId, - boolean hasRemoteParent, + @Nullable Boolean hasRemoteParent, TraceParams traceParams, StartEndHandler startEndHandler, @Nullable TimestampConverter timestampConverter, @@ -480,7 +481,7 @@ private SpanImpl( @Nullable EnumSet options, String name, @Nullable SpanId parentSpanId, - boolean hasRemoteParent, + @Nullable Boolean hasRemoteParent, TraceParams traceParams, StartEndHandler startEndHandler, @Nullable TimestampConverter timestampConverter, diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java index 76d3dd751c..158b541a18 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java @@ -61,7 +61,7 @@ public void startSpanNullParent() { assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); SpanData spanData = span.toSpanData(); assertThat(spanData.getParentSpanId()).isNull(); - assertThat(spanData.getHasRemoteParent()).isFalse(); + assertThat(spanData.getHasRemoteParent()).isNull(); assertThat(spanData.getStartTimestamp()).isEqualTo(testClock.now()); assertThat(spanData.getName()).isEqualTo(SPAN_NAME); } @@ -78,7 +78,7 @@ public void startSpanNullParentWithRecordEvents() { assertThat(span.getContext().getTraceOptions().isSampled()).isFalse(); SpanData spanData = span.toSpanData(); assertThat(spanData.getParentSpanId()).isNull(); - assertThat(spanData.getHasRemoteParent()).isFalse(); + assertThat(spanData.getHasRemoteParent()).isNull(); } @Test @@ -99,12 +99,16 @@ public void startChildSpan() { assertThat(rootSpan.getContext().isValid()).isTrue(); assertThat(rootSpan.getOptions().contains(Options.RECORD_EVENTS)).isTrue(); assertThat(rootSpan.getContext().getTraceOptions().isSampled()).isTrue(); + assertThat(((SpanImpl) rootSpan).toSpanData().getHasRemoteParent()) + .isNull(); Span childSpan = SpanBuilderImpl.createWithParent(SPAN_NAME, rootSpan, spanBuilderOptions).startSpan(); assertThat(childSpan.getContext().isValid()).isTrue(); assertThat(childSpan.getContext().getTraceId()).isEqualTo(rootSpan.getContext().getTraceId()); assertThat(((SpanImpl) childSpan).toSpanData().getParentSpanId()) .isEqualTo(rootSpan.getContext().getSpanId()); + assertThat(((SpanImpl) childSpan).toSpanData().getHasRemoteParent()) + .isFalse(); assertThat(((SpanImpl) childSpan).getTimestampConverter()) .isEqualTo(((SpanImpl) rootSpan).getTimestampConverter()); } @@ -118,7 +122,7 @@ public void startRemoteSpan_NullParent() { assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); SpanData spanData = span.toSpanData(); assertThat(spanData.getParentSpanId()).isNull(); - assertThat(spanData.getHasRemoteParent()).isFalse(); + assertThat(spanData.getHasRemoteParent()).isNull(); } @Test @@ -131,7 +135,7 @@ public void startRemoteSpanInvalidParent() { assertThat(span.getContext().getTraceOptions().isSampled()).isTrue(); SpanData spanData = span.toSpanData(); assertThat(spanData.getParentSpanId()).isNull(); - assertThat(spanData.getHasRemoteParent()).isFalse(); + assertThat(spanData.getHasRemoteParent()).isNull(); } @Test From 26a3ff3d9f1853a93406a304c9011f77b5ee5a34 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 6 Jul 2017 23:42:40 -0700 Subject: [PATCH 0262/1581] Start 0.6.0 development cycle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2ca6b295bb..31956b3659 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ subprojects { } group = "io.opencensus" - version = "0.5.0-SNAPSHOT" // CURRENT_OPENCENSUS_VERSION + version = "0.6.0-SNAPSHOT" // CURRENT_OPENCENSUS_VERSION sourceCompatibility = 1.6 targetCompatibility = 1.6 From 6bd1b3f39d6f88d366c7b38f2ddb2320c19d2928 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 7 Jul 2017 12:10:04 -0700 Subject: [PATCH 0263/1581] Use {@literal @} in Javadoc. --- core/src/main/java/io/opencensus/tags/Tag.java | 8 ++++---- core/src/main/java/io/opencensus/tags/TagKey.java | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index 36630e4b10..337af90ec4 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -53,25 +53,25 @@ public abstract class Tag { * byte[] serializedValue = * tag.match( * new Function<TagString, String>() { - * @Override + * {@literal @}Override * public String apply(TagString stringTag) { * return serializeString(stringTag.getValue().asString()); * } * }, * new Function<TagLong, String>() { - * @Override + * {@literal @}Override * public String apply(TagLong longTag) { * serializeLong(longTag.getValue()); * } * }, * new Function<TagBoolean, String>() { - * @Override + * {@literal @}Override * public String apply(TagBoolean booleanTag) { * serializeBoolean(booleanTag.getValue()); * } * }, * new Function<Tag, String>() { - * @Override + * {@literal @}Override * public String apply(TagBoolean unknownTag) { * serializeString(unknownTag.toString()); * } diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index b99068e3b3..3ab6a4c7eb 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -57,25 +57,25 @@ public abstract class TagKey { * Tag tag = * tagKey.match( * new Function<TagKeyString, Tag>() { - * @Override + * {@literal @}Override * public Tag apply(TagKeyString stringKey) { * return TagString.create(stringKey, TagValueString.create("string value")); * } * }, * new Function<TagKeyLong, Tag>() { - * @Override + * {@literal @}Override * public Tag apply(TagKeyLong longKey) { * return TagLong.create(longKey, 100L); * } * }, * new Function<TagKeyBoolean, Tag>() { - * @Override + * {@literal @}Override * public Tag apply(TagKeyBoolean booleanKey) { * return TagBoolean.create(booleanKey, true); * } * }, * new Function<TagKey, Tag>() { - * @Override + * {@literal @}Override * public Tag apply(TagKey unknownKey) { * logger.log(Level.WARNING, "Unknown tag key type: " + unknownKey.toString()); * return TagString.create( From ce8ad4b715c5245c672135041fde1237d17cd8c2 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 7 Jul 2017 12:26:21 -0700 Subject: [PATCH 0264/1581] Replace instrumentation with opencensus in the releasing instructions. (#432) --- RELEASING.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index c46725e7ed..e72eed5be9 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,8 +1,8 @@ -# How to Create a Release of Instrumentation Java (for Maintainers Only) +# How to Create a Release of OpenCensus Java (for Maintainers Only) ## Build Environments -We deploy Instrumentation Java to Maven Central under the following systems: +We deploy OpenCensus Java to Maven Central under the following systems: - Ubuntu 14.04 @@ -19,11 +19,10 @@ your OSSRH (OSS Repository Hosting) account and signing keys. page](http://central.sonatype.org/pages/ossrh-guide.html) to set up an account with OSSRH. - You only need to create the account, not set up a new project - - Contact a Instrumentation Java maintainer on JIRA to add your account after you + - Contact a OpenCensus Java maintainer on JIRA to add your account after you have created it. - - Comment under [this JIRA bug](https://issues.sonatype.org/browse/OSSRH-27038?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel) - for release permission to com.google.instrumentation. - - Request release permission to io.opencensus. + - Comment under [this JIRA bug](https://issues.sonatype.org/browse/OSSRH-32121) + for release permission to io.opencensus. - (For release deployment only) [Install GnuPG](http://central.sonatype.org/pages/working-with-pgp-signatures.html#installing-gnupg) and [generate your key @@ -53,8 +52,8 @@ naming convention of `v..x`, while the tags include the patch version `v..`. For example, the same branch `v0.4.x` would be used to create all `v0.4` tags (e.g. `v0.4.0`, `v0.4.1`). -In this section upstream repository refers to the main instrumentation-java -github repository. +In this section upstream repository refers to the main opencensus-java github +repository. Before any push to the upstream repository you need to create a [personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/). @@ -157,7 +156,7 @@ artifacts will go to a staging repository. When deploying a Release, the deployment will create [a new staging repository](https://oss.sonatype.org/#stagingRepositories). You'll need to look -up the ID in the OSSRH UI (usually in the form of `instrumentation-*`). +up the ID in the OSSRH UI (usually in the form of `opencensus-*`). ## Releasing on Maven Central From 7d91f470803115e988e59f4dd875309899101209 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 7 Jul 2017 15:28:18 -0700 Subject: [PATCH 0265/1581] Update to gradle 4.0 (#434) --- gradle/wrapper/gradle-wrapper.jar | Bin 54212 -> 54783 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e963759cbac1b5cb57af132b0be81a3aa0870a17..cc735e8dbad162a0ef33399e06e521567d864b23 100644 GIT binary patch delta 6729 zcmaKR2{@E*_x~6>*>_p8?_`VYWy>yvSg1$ ziQi*p-uIjD`@jD8bv@?Hxj*M~&VBCtJdfv0TR!$_5jN>fEo>ZW2!wzD0)bqE#FBE6 zoPBx{Hv1}q8iQCR1M2T?yKY#Je*p_G;h+rqdC;FnBB;-DSH3H_C*wDiwI2=BP2F20+firOh8SKa9DSVRx02z$E$?N2 zu=3VL5%OYpT#fSTMN&7~G0OK2w#*j^ow(mQO`Be+a-CA6_9334-MZYCd6e}wQ(R>) zSU$uUb_KUpe}=4meRd(>rpw_qC5md{i*n;j-BQ01m-D9l6W<}3xnl4}Gn^xD{w8^o zYvXDWoOQGEiC0~qbZ)JI(A!*ZadHdGT^)7a?cj~jfG>T0<+%J8dW5pPcpF3v-JyGS zo$q2rM&|a&rip_O>;Zn-EwLxo@`}}7H8yxLO!4$?E949t<`Zy|-C?Pve4VW9*u_i1 zs)dMX!I1W8o%(ukc^rc-Es4IZBfuk8C6{Jd6W;u!jfQ?H~8$%=(} zPeyB~#9xJmW09H8ZoMpOXHy=Yj*M#?!44^T^f)j(p0$cUxSTD7M?CB_DJ3I1mO#ky z!J9%&1SLfe-GSqU2?n79$7SDJ%TeKyzZ{v8L?Xg!RDC71kQIBK!^ABu2cqnjo#B^Y zj*sY%!y+qWIG|=`Y!{XBCJ=7%*?2wv>ig*zWt#&pdX-RdHZHb^ZVbS`D!^X!M0Zmp zwNxT%^6zli3OQ9J^oCs?v#F;sW6dieJ(6-wF4nT3#5D_iR&*y;=NRw&scA}$SRf=I zg+Q2?AP_bHVMPllbr2whZJn&$-P277t*AfyoMcqgi8DSUHM;T6YR9IDApPSAlh(2`YDdh8@G-7I?KzSOpiTV8kB)itth08=%iI_nQw&95bA8?2|0WkYe=oq zh^c_3Ryn6+ti^KwnVnKD8ddWkTJ4iPS^snT^K@H&_sHe(H*tt3GCUHG^1Zbcy~yah zpAHj`)UJs1EYsBdB9>8boTuB>V)UPQ5|E0g5Nav9Q*>DGEdTPcG%NTYA3U_i(`5h~3W1@_X@-&(u1L ze&lZ)iD>oWtEt=<(yN7U&+zpmuSFkO3@0y?HGd_X(&8~!e~FlNzbhx3&Z3$3cq+C< zR)A3Pi-nv1n|OL5j{N$;#~M6qtmLbX=IzDt3B_p>SJ}u{y^vHD_13&=;~dE~8dI`% zu)GnAX+8l-YaflP{knL^6P)G^4w8UFc3q*}T%V`q_7&%3xAe6y+8@h%^j=O|%eYSWEdG`}rT5iAmtQS* z_SaI98vYJJjzE3JE?ee{@%2=9L^{7Oag#{cHmT{;qtVXHZ_|3yQ4*9G4sW71p1Q3U z$hN}m#KY$3{J{D7TW`mNga~&wsdRxPN$1*!WuH^oGoB@-?&diq!-5c4t>*gC;ac9> zS6n1SW7M_1Z=~+n0nMsZb1_oGUgeF7bCM$KPb$o)kg~9$kQJO-qXM}pqYRc2j!DTO z>j<5p+;C_3G@EDgq7EW4oM)GtinZ-i-nh_~{Sn_C)l5wjS-lkV-ojxby;@Ggjo3a5 z*tBhgpK44vYqL1FMN{O%Ac+rf9}BAA+K9|?mk8`de>f9$L&~bS>Idmp;aG4cT6JxN z0po!)(x+*Z+m3lhY_BnWuuT-sM5hdewU5Z_1*Isxnh#jz5?~gx-iY&zg>5|^r{-7; z;#Pwp^rIZu?IYke)6`Tpoz(fcpZfHZk{3z5ho}(~X%r24(gJ>Doy$xYyB`m>4b0!g z4HPqSfXi{R(7t!8^>Vu7`sKz$Ihe6(OoogklF<;Cy|(_k%1mSxT_w}))T(^ry&Nso zOW*2-u6I3)Ey3t=8V3L;*GGr)U^j5KWvM&5-b z+950X`Xh;bzPu=N5pWw>(d^@sx(l~3bZ8z@>85rMlqHDHl$q9eQe)%KU>;CeaGi!S ztb3xzJaI+e9MIqy^6307gtVTuC$xu*Xq4M$K#$WL9?MZS;EwfhS=-7zk8}47?{&w0 zuMv7H3?}2tw>I#G^7kE?Z}0sj(vvg29F&pl-8HzhQLCll*0>Yu#W}h4MZCuD^tiDbsZb7FtatcV=P_Vp%;Mm-^syzY z{9y-CpZN{WhKkyWbhgIFiMO6ocIP^dri{gV)!lIX>NprD%Ysm=cfca$0g$|xFVOh8awz{cuiaK=Wqs2AdvQCFx`TcG`$rjBlACkwwn1YwItlc|*4#)K zO@Gw1BYZ+=eO%OGZ&H(f$wi6br8peHI+$;I|&bMd7>6^w!iiOrAKAz}F zZLav{2zno7a4i*UZ6AL^Oxla;{Cb{P8NL!r>*0G zHVj2Aqo-E58RY`rnz_Z^+Qp|jj{7ddHLDhvIJZjX=gMi!EY^?zH|sgq*H|t06V3bOx#UV2am8_8UTW%m$zRUOV@OLDfdThTvpb&AlG` z%0B+ly%$1dJS9Y~2_m`mhN1ECO_T5ZnI)z4kl1Qwg4qW$yXps1i2gA7^3e4C? zi@Y_RN7RRpT)k@~@GB%*@LSny#hJ0$(y$OWgqQxb`Np=8YWsp$+JBB1 z$Vb+!kEgYlu&V4uhJ{q$K}?Z2A)kd-3)%ec5%TDhyj9%bAyoOzbV|RDwt8T+eubf; z`Z08LVNB37!w5K-z1<(=%r2<7+4nI%p;k9rD5yWoV#W+m{k=EmU$mHYD#Ov7I>^y1 zSS#a_T_PU2wNhG{pY^?#`!ffL$cLBj4)`r{dMsK$k4UZj@}ht>$us?UzKB$)MJgf? zPY!D{cjY@@?%S~bI;>`WO5emwLD@>7JXgyJArZgC;Z4M|BT=9b4IDaz zEU#$%G131JA>H^y{E)JLu}3=e?fkXd6dh91KVfM!kBGxAu~2gh(ws=;L|4@ZR?mmh z56bRZ*T)-=zTPGBr+48nV6jIAen{uDP<{}jw~cFWA638IB&(HHy7(~ADV$L>jME*$OF}B@!_MZ zI2HtRQ#$4*`*I}kU_aK@8H&bjyn_xp#HB|_TKp;FBHyFF>=Ql90s~GE$2fkX%cHtwJj9c5)t?HvW?i;PzQ~B0>w?{LfnU~lOr_%%#%cVq*LPf{ z`#oPRaXZ@?x%8^1t@*zz<%tweuL-l{Qs@`9exu5aw{52~s}7$X7(T|z+yBH>I%_Cl zpLm@^*REn|WhBc^jO`7w(D+u@oZ{EMU+i|8oaw}hN>4*tR$d^;G?!Y)N;e6ESQ9d> z#^W+?dY9?lT41xnF7epvo1f+*v3tqB$;7 zM)xXB{(Zki*o#bq6vbc@57E~x5{^ua9!E&?8!d;H=U*pBbVO#dz%E5Mc!~b^ZStm@ z%Uw4+cXw?E_lI`Qc5djmOOI#GM1e}ws@npe?$fCB9H53CeG>m!E!&G{t@9H_4BowzR24DWQ z{GD5b^m7!)Iwb*f1xM&$@F#_RM$dWwe>GUjbtxP1&@Gh)^BgF}Stq4B+-g0W2m;}! z2QSom=gslTkM$df&>fenM9XLkGj?)(wB)ULiwZ48i^M?D5(NVun$PCYL0}aR0$~K- z$hlE`F6|`caN(M?uw zVG1BQH8H|PelYB}vvro0iccXD2}L z-=4O8ZzpbpL5&hZAVTLnF<}9s#5BOykKCxV0c0JFP$N8)PN{?G(tlciWMG_1AVT7t zu?#*2NC?cfbE3d!&7uGHhR%Ug2{B*-V7Y@51wL2$=fI0}{{eIVzwZS9ULi2k#t0pz zM_G}!3!><83VdhGz`*suz|XJx1uL+ie-W7IME5@d%}z$BEIX(Z1a5R)KpC%W7`qpO zF-?INJ9zywxP(w%%!tTvB1gya;Wd8<}38TPBb~5t+3HcbzHHRc-9v_hC zL?2zi3e@}GKI4u z9S88XhYICMt%~5MJT~~?1Gh!?oN*VAX?OlOo-{(+$s2h)B)OM!;T>H@>st?(3#DT17VCv5&Lpu=#7U-r& zxvwvViN%7zry%hBT0~M%Krc+3LNxaR@j+l6xH_?O?k}dJ7TH<$kNYn+qdW^B*cr^y z+3zd=47W@a`0`_xvslrYYVKo%zRL#n?7(Rsros!s?3q>q0WaBs)d7s|Ca4o{0CmE^ zMmNS*5In?Jn}ACma%V>l&G)3A5lYemr1h(#zYBa~gwD4DEG=xny-yb|fzL9{zn@^> ee;I!b(Kf)Pg%No3iGWlLT&N}ZjEiVHoBux=2b-$^ delta 6082 zcmZ8l1yqzx7haZbrCC@?U}+>p5L+6RZs~521{VWKC0+!iM7q1B1a_rMffbYnQ5q#h z{9ktYzwhVYbLPxFcb?~&duQ&~>6R+7R6LX?J=7^@ z@dg9}(T%;X&9Kb8?Xl&72l*HJGYy31a}Z$rJ_N4c6UFvb=Z#58&!3EZTh;e01Vtvn z#s#<&F#v5{)PS{cH4ewG&PR;1W|&%ta2C5N5tQVFyXRlr2B;C=gs!;&F~pomM>1Od zs;`_K9E%2Ofkb~SS=0j|>^;83`7|o|>(LE9>zDVYJZ)`|$A`Q4*O{Z8xnrwlIc&{^ zAE!u91xM=#Eg5}`mANjv+&G+qGr3)-( zMev!%etHHZ3fgRTX@qn7P{qEVdL=)4PBcj3(GNNS7(bP!em3k|mxaEQ<5zy9cVCz5 zyPF2}-!e#|2ew4rk{x5>LMosB_BE5eQoR}Wb{`qq9dnT7K&GE2Cw9v}iD|QZagD0c zkX4+!znM>2P2LRCGmhXhJTNcPlwq;(6@R)PUGV)oQ}|Hj*ivC39pZdNpm{4gCT-ZF z)uzPEdrkC@D7N;#9!~Q!Q9>Y7%n%4CSbJonPKI+r zm~sr71THv_VVx_FjWMebsaCRjkBQQ~V87*HD=$Ibux9vUvm9huj~Ep8oRyB8Q4c zK9)&$Xg4?tVNFlykRS?u@{$lgaZ`kHLpo!=^6}n`0saQc)5G_{$WadKanE(cv0(=} zY|7S5s+7s@{clRJ+T%a4$905y1$MS6Zi!tE{L+TlRK|bPp0~L9n%Ci=_~jt;{*{)D z*+|(ID~~XRbZ7cP<|_v$pVr zy7tb>dF+=;&a*!}%6iNhc<;lW*U|M3YRXlVmh7?e)xQRDN0F(2iU<~`DOl01EBn;= zf5ZQdY)!)+an~Iye)#)izv8)`-F`SH$1@QapN^yhS4Mb-$j!zf$+s(+-EHpX%NEEG z5w#wALHlsKF_eHw^|D2cNPDAxR%A`1K7z2?!J?U0+K!70f+vyQKjC7E-o7$POA_5U zfI7J4ha4L?{2sq3S9<;DGNvoG;`sL5dP~-PhtE)QeOu2}#L9v0*qd^3zjqop`N}hW z0?jgztLwLqw6E3G){#6DALxrx=TAWr!F_TA&^5W@-g|`OJ&R6t0r%nSv_ti5wM$OP z7kvk0UA=6JSJiyleLj9>W@EXMUTz|~X2tJ;lug;CCi_)ua%agytk=g|jfCJZmA}wL zDrsP%SYpke^{oou?oZVp%FD|^u-x4n zNq2hW(w9(M*3&Q$C0R1qt@<_!8EqN=Vk{^3%zu-7t8gzznI)%iWB2PtQ5&; zzh=@VUNGoiRa%rtaE(qhuP<%6~*b?iug<-ret&+Y1?bU#R2c50#4xQ_s@U z;uh`ixN8Vd6$vW7dNS*anixSY_>QK8e)%L6!jsyRQfXaVUM$S(uGS;wF1n;{boFV%NPPk{S0{T3;*#(FrB-ewSGZ#MHA7C zcYZE@iO~8r@2*ABH5(@5fQ+b5g##UMRzBCEPNPi(^u~9#LAqNO`ZI5VQ1tWp4#muQ zwt0mAug>t{{6d1^3C(j}1CuVFdPYDd#oMaG-%X7kVb{2kWIE(}K-nQ`kiF!9xXWlYG1M+equqPL|CueuYKh z=twaw?oLt$s&1C73AJLqS8VE0DHbXMRVW*T>nkQqTL04hdJ57HGK;WP0pbtj-zpO1~bsi=r}WSseW4 zG-fD!z4@l@H@-H}{h=T+$5|h_z|LYE6*xvlqdE8QBrO^LN_iP>6)lgMVI`}R$$G)@Qxg6e;2+B z(TRU`Z09w(%_}^ji)@`Pz-Z3dCY+CQGS!i&a1W12w#lzKCcO}67WH{==`)`0=GO;# zzw@V$q-kRd2O@Y1$l@jv9M#jDcil^W;5~KD3-IZ5G)7v~`c}tsYUzFSW%bwDt9G0Qa>`FS8lc2SvHaCHz;fE6nd6awj44jbr<5=XF7}qYk5hgbTAl!wnO?z2N0u0WHm{wZ9j=H7b5# zEItMWz|%kW`WEI0InG}?Dwdc_8A$h8H#b`?dAjjkHfG%Mh$p7`XUkExYl+XT1H$n~ zI~a2tSw`(7)iTqMV?I*sJ^96fgwJx}J_Fl{#&4-Ky-M$Awj*^@@32A{o?yc4``oUQ zXW-eF4(gO_+|c)4P7SpNO4BdzIC1qiyIuA-KFFrrY!vwJ!s`bo`jD8pvtxx&Cf z!~IILU`OQ|Y1T$0!5Uez=&gGZgpwvtG=`_t1ZEVLF?UPk;uWg8^hWsH*w+y?@t5y9 zD7O|?1=ABIAtvQy8OuEi>hDIZ%w5Utyb~$3NM777I%BPZ5@=#=RT?mzyV90sKEST8 z&HL!KZSg{Pfkaab;sHIn2Lihlp2$gw_1}nd{I;XsPy}eYxZj1@VP17wik%e+~&#Uh~*b6$z+&g%sn=} zJZHkyFoLq{(MSSvyN$+nQ#^R|>>*p#aRcw*g(c5>+aouQ_#e!Kn6}aH2;DsNKoh!2 z=+(toFq(huxBL9m8KasJ;9D7u+{YZX~>Go zl2MSqweQ*fM^a%^g!MxeQx=*tFg4)K>=a|ep3Zs@z=li|=`$zXX~AoaB4#eR^s&^` zyvhEP4-xe&{lh&1g{`7KfcM9>J0@jMI8F4t4lh<3yw?*FeG!sy?@|F2b;5gDeWDeP zN1<(!F#*(%^m6tyM>W>BwMvp!=O8s*;@cNDkVbgOI%==y)bv9v>yCj8q2$Z#>lD;o zJF$@QZnTt4@{G&94AmHp2W=JUX58mUwE2ULPDqQ2WJH!`21$kLBvorenvlos3SzdY-;QL)nAvF7n;smjF zlYBl0vJpt1z8;~t6+rMdrDkjIGP#>A{_*w8YpmwN>+(v9t)$2Au3{E{nOt=%x;FMTzXs|Qcx+I-G5g9&7VXKp-tRvKmX| z*HRdHy{T$HWF}J(CCBrE{LK=EmSmcr{rx8M0ZGV)!|9HNxs*i_ac`9_ z#(v^@ds}luiQDLA8f$fFC(oBZopI$s!u|g61?0@L*Bs}GEaNfGwlm#DtimwuMimmo zmb5}hk#cmai3v|%R8VN63PI@B-2rI48w80qi1F~QAiKQabY0^opmy#+!P%@mmC*3v z;j)ku(>21gA7fQwQhKzwZ!Kl6B{Hg$Z*_tK|F6bS2tHrUCDYgxr zTF+gKPpwOKH3YcP;5V}PIIATyj|OLPKVu`oSuE{?r;L2>xKrGXX6UJ9U-O9=hf|0; zhEknGd~29t=?6Xp5=ai*k3v*g22r2R!=I*g8n%4$@~Nd1y>V)7I>nvNBNxYZs$Ogz zdYaUFhdRDA{sM5dQ|8x;MgLdq{~6?G7;S(V3WocteuRSItzh46%1{(ImwYb_ z%7zEr5T*xQdO2~v=q?ykkPP&31A|?sxQjh7C_OnAr>0H|eC|8-2Yi4*Z_r@<#UF%l z{GM(Y6rcGNO9|XlWdb;QDE@r~az!&hDOs@N$7m8D8_mOUlETTeKpdE@JShZn@k|OX za4gtY8~*Ra(_oNyxj;VyaK8IAzg83sYQc}iZlZW`!NAZkXsXCRlSLDe07mH3;Df+G zgGI4pWl9u4V>bmhkTXvWX9A%WKNUKiP!tq!xCZ(d0P}7pEV(Y+Y$cNn0uf*W+Zi%S z6H9jDVg!)?UDhw)@|Brj{ghq2Sb;vu2MV#^<{uD2Ai`$^bj`3pmtJDP)PNQc?!|>W zA2MXh1_D{ZcHs;`+!84372`Om_!IwsD~kFIDAqEr4~{(_z|k-a+GYt#%z?25&{ z8x+Tiikn(T=YnF(VB=fnxRb+h zEI9Iplv5xGCI`W?XTStrfKJ;Lz^xCbiXc#;Uuz z2Tzw@9u%<70PZ!5oNNhJ#K_krDIN^_!}xN8#B(w-v$tRRu|6X9%s0Ab}Nt zIWzuSqhet3>olDTUBE@d3GTa3E4c61u&Gf0?a%}7ZwR=H5cV^I(01UcgH!0gw=xO% i`VRgTsQmBs58em=^V4bv21mK5#7+VOx1hBBWb8lMV3chD diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c5cc309a1e..01c15363e1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Jul 04 00:25:44 CEST 2017 +#Fri Jul 07 15:13:06 PDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-bin.zip From d27cbb4fc6293bb5a4adeb705ce74273a3dc3219 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 7 Jul 2017 15:43:32 -0700 Subject: [PATCH 0266/1581] benchmarks: update to jmh 1.19 (#435) --- benchmarks/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmarks/build.gradle b/benchmarks/build.gradle index 62fda00c2b..00f3f737fd 100644 --- a/benchmarks/build.gradle +++ b/benchmarks/build.gradle @@ -8,14 +8,14 @@ buildscript { } } dependencies { - classpath "me.champeau.gradle:jmh-gradle-plugin:0.3.1" + classpath "me.champeau.gradle:jmh-gradle-plugin:0.4.4" } } apply plugin: "me.champeau.gradle.jmh" jmh { - jmhVersion = '1.18' + jmhVersion = '1.19' warmupIterations = 10 iterations = 10 fork = 1 From ee9518de734fcc04270e83045554316361a6f7f0 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 7 Jul 2017 16:35:08 -0700 Subject: [PATCH 0267/1581] Fix Functions tests. (#437) --- api/src/test/java/io/opencensus/common/FunctionsTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/src/test/java/io/opencensus/common/FunctionsTest.java b/api/src/test/java/io/opencensus/common/FunctionsTest.java index 1c8df81998..2ab1ebca98 100644 --- a/api/src/test/java/io/opencensus/common/FunctionsTest.java +++ b/api/src/test/java/io/opencensus/common/FunctionsTest.java @@ -18,8 +18,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Tests for {@link Functions}. */ +@RunWith(JUnit4.class) public class FunctionsTest { @Rule public ExpectedException thrown = ExpectedException.none(); From c796e25737240ce4f209a045528f965b8819915a Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 7 Jul 2017 16:42:36 -0700 Subject: [PATCH 0268/1581] Add a section of known issues with the release. (#438) --- RELEASING.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/RELEASING.md b/RELEASING.md index e72eed5be9..b7f0de0205 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -167,3 +167,14 @@ the repository. If this completes successfully, the repository can then be Central (the staging repository will be destroyed in the process). You can see the complete process for releasing to Maven Central on the [OSSRH site](http://central.sonatype.org/pages/releasing-the-deployment.html). + +## Known Issues + +### Deployment for branch v0.5.x +For all releases on the branch v0.5.x to deploy to maven central use command +```bash +$ ./gradlew clean build && ./gradlew uploadArchives +``` + +If option `-Dorg.gradle.parallel=false` is used, you will hit [this bug](https://issues.sonatype.org/browse/OSSRH-19485) +caused by [this bug](https://github.com/gradle/gradle/issues/1827) in gradle 3.5. From 27cb1db953e7bb5c1e39b6ddae357572cba732f6 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 7 Jul 2017 16:42:52 -0700 Subject: [PATCH 0269/1581] github: add an issue template (#436) --- .github/ISSUE_TEMPLATE | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE new file mode 100644 index 0000000000..3118cd3722 --- /dev/null +++ b/.github/ISSUE_TEMPLATE @@ -0,0 +1,16 @@ +Please answer these questions before submitting your issue. + +### What version of OpenCensus are you using? + + +### What JVM are you using (`java -version`)? + + +### What did you do? +If possible, provide a recipe for reproducing the error. + + +### What did you expect to see? + + +### What did you see instead? \ No newline at end of file From 95974b9677f0209e94cbf4db835fc98c63ea52c6 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Mon, 10 Jul 2017 10:30:03 -0700 Subject: [PATCH 0270/1581] Rename Aggregation to Aggregate. (#431) --- ...gation.java => DistributionAggregate.java} | 34 ++++---- ...ggregation.java => IntervalAggregate.java} | 10 +-- .../java/io/opencensus/stats/ViewData.java | 16 ++-- ...st.java => DistributionAggregateTest.java} | 24 +++--- ...onTest.java => IntervalAggregateTest.java} | 10 +-- .../io/opencensus/stats/ViewDataTest.java | 40 ++++----- .../io/opencensus/stats/MutableViewData.java | 16 ++-- .../stats/MeasureToViewMapTest.java | 2 +- .../io/opencensus/stats/StatsContextTest.java | 6 +- .../io/opencensus/stats/StatsTestUtil.java | 54 ++++++------ .../opencensus/stats/ViewManagerImplTest.java | 82 +++++++++---------- 11 files changed, 147 insertions(+), 147 deletions(-) rename core/src/main/java/io/opencensus/stats/{DistributionAggregation.java => DistributionAggregate.java} (88%) rename core/src/main/java/io/opencensus/stats/{IntervalAggregation.java => IntervalAggregate.java} (88%) rename core/src/test/java/io/opencensus/stats/{DistributionAggregationTest.java => DistributionAggregateTest.java} (75%) rename core/src/test/java/io/opencensus/stats/{IntervalAggregationTest.java => IntervalAggregateTest.java} (88%) diff --git a/core/src/main/java/io/opencensus/stats/DistributionAggregation.java b/core/src/main/java/io/opencensus/stats/DistributionAggregate.java similarity index 88% rename from core/src/main/java/io/opencensus/stats/DistributionAggregation.java rename to core/src/main/java/io/opencensus/stats/DistributionAggregate.java index 64bc248576..8aab957c90 100644 --- a/core/src/main/java/io/opencensus/stats/DistributionAggregation.java +++ b/core/src/main/java/io/opencensus/stats/DistributionAggregate.java @@ -34,37 +34,37 @@ */ @Immutable @AutoValue -public abstract class DistributionAggregation { +public abstract class DistributionAggregate { /** - * Constructs a {@code DistributionAggregation} without bucket counts. + * Constructs a {@code DistributionAggregate} without bucket counts. * * @param count the number of values in the population. It must be non-negative. * @param mean the arithmetic mean of the values. If {@code count} is zero then this value must * also be zero. * @param sum the sum of the values. If {@code count} is zero then this value must also be zero. * @param range the range of the values. - * @param tags the {@code Tag}s associated with the {@code DistributionAggregation}. - * @return a {@code DistributionAggregation} without bucket counts. + * @param tags the {@code Tag}s associated with the {@code DistributionAggregate}. + * @return a {@code DistributionAggregate} without bucket counts. */ - public static DistributionAggregation create( + public static DistributionAggregate create( long count, double mean, double sum, Range range, List tags) { return createInternal(count, mean, sum, range, tags, null); } /** - * Constructs a {@code DistributionAggregation} with bucket counts. + * Constructs a {@code DistributionAggregate} with bucket counts. * * @param count the number of values in the population. It must be non-negative. * @param mean the arithmetic mean of the values. If {@code count} is zero then this value must * also be zero. * @param sum the sum of the values. If {@code count} is zero then this value must also be zero. * @param range the range of the values. - * @param tags the {@code Tag}s associated with the {@code DistributionAggregation}. + * @param tags the {@code Tag}s associated with the {@code DistributionAggregate}. * @param bucketCounts the bucket counts for the histogram associated with the {@code - * DistributionAggregation}. - * @return a {@code DistributionAggregation} with bucket counts. + * DistributionAggregate}. + * @return a {@code DistributionAggregate} with bucket counts. */ - public static DistributionAggregation create( + public static DistributionAggregate create( long count, double mean, double sum, Range range, List tags, List bucketCounts) { return createInternal( count, @@ -75,14 +75,14 @@ public static DistributionAggregation create( Collections.unmodifiableList(new ArrayList(bucketCounts))); } - private static DistributionAggregation createInternal( + private static DistributionAggregate createInternal( long count, double mean, double sum, Range range, List tags, List bucketCounts) { Preconditions.checkArgument(count >= 0, "Count must be non-negative."); if (count == 0) { Preconditions.checkArgument(mean == 0, "Mean must be 0 when the count is 0."); Preconditions.checkArgument(sum == 0, "Sum must be 0 when the count is 0."); } - return new AutoValue_DistributionAggregation(count, mean, sum, range, tags, bucketCounts); + return new AutoValue_DistributionAggregate(count, mean, sum, range, tags, bucketCounts); } /** @@ -115,14 +115,14 @@ private static DistributionAggregation createInternal( public abstract Range getRange(); /** - * Returns the {@code Tag}s associated with this {@code DistributionAggregation}. + * Returns the {@code Tag}s associated with this {@code DistributionAggregate}. * - * @return the {@code Tag}s associated with this {@code DistributionAggregation}. + * @return the {@code Tag}s associated with this {@code DistributionAggregate}. */ public abstract List getTags(); /** - * Returns the bucket counts, or {@code null} if this {@code DistributionAggregation}'s associated + * Returns the bucket counts, or {@code null} if this {@code DistributionAggregate}'s associated * {@link DistributionAggregationDescriptor} has no buckets. * *

            A Distribution may contain a histogram of the values in the population. The histogram is @@ -143,7 +143,7 @@ private static DistributionAggregation createInternal( *

            {@link #getBucketCounts()} will return null iff the associated {@link * DistributionAggregationDescriptor#getBucketBoundaries()} returns null. * - * @return the bucket counts, or {@code null} if this {@code DistributionAggregation}'s associated + * @return the bucket counts, or {@code null} if this {@code DistributionAggregate}'s associated * {@link DistributionAggregationDescriptor} has no buckets. */ @Nullable @@ -161,7 +161,7 @@ public abstract static class Range { * @return a {@code Range} with the given bounds. */ public static Range create(double min, double max) { - return new AutoValue_DistributionAggregation_Range(min, max); + return new AutoValue_DistributionAggregate_Range(min, max); } /** diff --git a/core/src/main/java/io/opencensus/stats/IntervalAggregation.java b/core/src/main/java/io/opencensus/stats/IntervalAggregate.java similarity index 88% rename from core/src/main/java/io/opencensus/stats/IntervalAggregation.java rename to core/src/main/java/io/opencensus/stats/IntervalAggregate.java index c7c548ca48..b8d2549cbc 100644 --- a/core/src/main/java/io/opencensus/stats/IntervalAggregation.java +++ b/core/src/main/java/io/opencensus/stats/IntervalAggregate.java @@ -22,13 +22,13 @@ /** * Contains summary stats over various time intervals. */ -public final class IntervalAggregation { +public final class IntervalAggregate { /** - * Constructs new {@link IntervalAggregation}. + * Constructs new {@link IntervalAggregate}. * TODO(dpo): Determine what we should do it intervals is empty. */ - public static final IntervalAggregation create(List tags, List intervals) { - return new IntervalAggregation(tags, intervals); + public static final IntervalAggregate create(List tags, List intervals) { + return new IntervalAggregate(tags, intervals); } /** @@ -51,7 +51,7 @@ public List getIntervals() { private final List tags; private final List intervals; - private IntervalAggregation(List tags, List intervals) { + private IntervalAggregate(List tags, List intervals) { this.tags = tags; this.intervals = Collections.unmodifiableList(new ArrayList(intervals)); } diff --git a/core/src/main/java/io/opencensus/stats/ViewData.java b/core/src/main/java/io/opencensus/stats/ViewData.java index 7e885324f6..9275394115 100644 --- a/core/src/main/java/io/opencensus/stats/ViewData.java +++ b/core/src/main/java/io/opencensus/stats/ViewData.java @@ -54,11 +54,11 @@ public abstract static class DistributionViewData extends ViewData { * Constructs a new {@link DistributionViewData}. */ public static DistributionViewData create(DistributionView distributionView, - List distributionAggregations, Timestamp start, Timestamp end) { + List distributionAggregates, Timestamp start, Timestamp end) { return new AutoValue_ViewData_DistributionViewData( distributionView, Collections.unmodifiableList( - new ArrayList(distributionAggregations)), + new ArrayList(distributionAggregates)), start, end); } @@ -67,12 +67,12 @@ public static DistributionViewData create(DistributionView distributionView, public abstract DistributionView getView(); /** - * The {@link DistributionAggregation}s associated with this {@link DistributionViewData}. + * The {@link DistributionAggregate}s associated with this {@link DistributionViewData}. * *

            Note: The returned list is unmodifiable, attempts to update it will throw an * UnsupportedOperationException. */ - public abstract List getDistributionAggregations(); + public abstract List getDistributionAggregates(); /** * Returns start timestamp for this aggregation. @@ -102,22 +102,22 @@ public abstract static class IntervalViewData extends ViewData { * Constructs a new {@link IntervalViewData}. */ public static IntervalViewData create(IntervalView intervalView, - List intervalAggregations) { + List intervalAggregates) { return new AutoValue_ViewData_IntervalViewData( intervalView, - Collections.unmodifiableList(new ArrayList(intervalAggregations))); + Collections.unmodifiableList(new ArrayList(intervalAggregates))); } @Override public abstract IntervalView getView(); /** - * The {@link IntervalAggregation}s associated with this {@link IntervalViewData}. + * The {@link IntervalAggregate}s associated with this {@link IntervalViewData}. * *

            Note: The returned list is unmodifiable, attempts to update it will throw an * UnsupportedOperationException. */ - public abstract List getIntervalAggregations(); + public abstract List getIntervalAggregates(); @Override public final T match( diff --git a/core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java b/core/src/test/java/io/opencensus/stats/DistributionAggregateTest.java similarity index 75% rename from core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java rename to core/src/test/java/io/opencensus/stats/DistributionAggregateTest.java index eceb9bb29c..5ace8204f3 100644 --- a/core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java +++ b/core/src/test/java/io/opencensus/stats/DistributionAggregateTest.java @@ -16,7 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; -import io.opencensus.stats.DistributionAggregation.Range; +import io.opencensus.stats.DistributionAggregate.Range; import java.util.Arrays; import java.util.List; import org.junit.Test; @@ -24,14 +24,14 @@ import org.junit.runners.JUnit4; /** - * Tests for class {@link DistributionAggregation}. + * Tests for class {@link DistributionAggregate}. */ @RunWith(JUnit4.class) -public final class DistributionAggregationTest { +public final class DistributionAggregateTest { @Test - public void testDistributionAggregationWithOutBuckets() { - DistributionAggregation aggr = DistributionAggregation.create(10, 5.0, 30.0, + public void testDistributionAggregateWithOutBuckets() { + DistributionAggregate aggr = DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS); assertThat(aggr.getCount()).isEqualTo(10); @@ -47,9 +47,9 @@ public void testDistributionAggregationWithOutBuckets() { } @Test - public void testDistributionAggregationWithBuckets() { + public void testDistributionAggregateWithBuckets() { List buckets = Arrays.asList(2L, 2L, 2L, 2L, 2L); - DistributionAggregation aggr = DistributionAggregation.create(10, 5.0, 30.0, + DistributionAggregate aggr = DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS, buckets); assertThat(aggr.getCount()).isEqualTo(10); @@ -69,15 +69,15 @@ public void testDistributionAggregationWithBuckets() { } @Test - public void testDistributionAggregationEquals() { + public void testDistributionAggregateEquals() { List buckets = Arrays.asList(1L, 2L, 3L); new EqualsTester() .addEqualityGroup( - DistributionAggregation.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS), - DistributionAggregation.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS)) + DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS), + DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS)) .addEqualityGroup( - DistributionAggregation.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS, buckets), - DistributionAggregation.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS, buckets)) + DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS, buckets), + DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS, buckets)) .testEquals(); } diff --git a/core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java b/core/src/test/java/io/opencensus/stats/IntervalAggregateTest.java similarity index 88% rename from core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java rename to core/src/test/java/io/opencensus/stats/IntervalAggregateTest.java index fe3d42e015..9d0210eb17 100644 --- a/core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java +++ b/core/src/test/java/io/opencensus/stats/IntervalAggregateTest.java @@ -16,7 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.Duration; -import io.opencensus.stats.IntervalAggregation.Interval; +import io.opencensus.stats.IntervalAggregate.Interval; import java.util.Arrays; import java.util.List; import org.junit.Test; @@ -24,16 +24,16 @@ import org.junit.runners.JUnit4; /** - * Tests for class {@link IntervalAggregation}. + * Tests for class {@link IntervalAggregate}. */ @RunWith(JUnit4.class) -public final class IntervalAggregationTest { +public final class IntervalAggregateTest { @Test - public void testIntervalAggregation() { + public void testIntervalAggregate() { List intervals = Arrays.asList( Interval.create(Duration.fromMillis(10), 100.0, 1000.0), Interval.create(Duration.fromMillis(11), 101.0, 1001.0)); - IntervalAggregation aggr = IntervalAggregation.create(TAGS, intervals); + IntervalAggregate aggr = IntervalAggregate.create(TAGS, intervals); assertThat(aggr.getTags()).hasSize(TAGS.size()); for (int i = 0; i < aggr.getTags().size(); i++) { diff --git a/core/src/test/java/io/opencensus/stats/ViewDataTest.java b/core/src/test/java/io/opencensus/stats/ViewDataTest.java index 6637252164..6390af6fa6 100644 --- a/core/src/test/java/io/opencensus/stats/ViewDataTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewDataTest.java @@ -20,8 +20,8 @@ import io.opencensus.common.Duration; import io.opencensus.common.Function; import io.opencensus.common.Timestamp; -import io.opencensus.stats.DistributionAggregation.Range; -import io.opencensus.stats.IntervalAggregation.Interval; +import io.opencensus.stats.DistributionAggregate.Range; +import io.opencensus.stats.IntervalAggregate.Interval; import io.opencensus.stats.ViewData.DistributionViewData; import io.opencensus.stats.ViewData.IntervalViewData; import io.opencensus.stats.View.DistributionView; @@ -43,10 +43,10 @@ public void testDistributionViewData() { final DistributionView view = DistributionView.create( name, description, measure, aggregationDescriptor, tagKeys); - final List aggregations = Arrays.asList( - DistributionAggregation.create(5, 5.0, 15.0, Range.create(1.0, 5.0), tags1, + final List aggregations = Arrays.asList( + DistributionAggregate.create(5, 5.0, 15.0, Range.create(1.0, 5.0), tags1, Arrays.asList(1L, 1L, 1L, 1L, 1L)), - DistributionAggregation.create(10, 5.0, 30.0, Range.create(1.0, 5.0), tags2, + DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), tags2, Arrays.asList(2L, 2L, 2L, 2L, 2L))); final Timestamp start = Timestamp.fromMillis(1000); final Timestamp end = Timestamp.fromMillis(2000); @@ -58,7 +58,7 @@ public void testDistributionViewData() { @Override public Boolean apply(DistributionViewData dViewData) { return dViewData == viewData && dViewData.getView().equals(view) - && shallowListEquals(dViewData.getDistributionAggregations(), aggregations) + && shallowListEquals(dViewData.getDistributionAggregates(), aggregations) && dViewData.getStart().equals(start) && dViewData.getEnd().equals(end); } @@ -77,10 +77,10 @@ public void testIntervalViewData() { final IntervalView view = IntervalView.create( name, description, measure, aggregationDescriptor, tagKeys); - final List aggregations = Arrays.asList( - IntervalAggregation.create(tags1, Arrays.asList( + final List aggregations = Arrays.asList( + IntervalAggregate.create(tags1, Arrays.asList( Interval.create(Duration.fromMillis(111), 10, 100))), - IntervalAggregation.create(tags2, Arrays.asList( + IntervalAggregate.create(tags2, Arrays.asList( Interval.create(Duration.fromMillis(111), 10, 100)))); final ViewData viewData = IntervalViewData.create(view, aggregations); @@ -95,7 +95,7 @@ public void testIntervalViewData() { @Override public Boolean apply(IntervalViewData iViewData) { return iViewData == viewData && iViewData.getView().equals(view) - && shallowListEquals(iViewData.getIntervalAggregations(), aggregations); + && shallowListEquals(iViewData.getIntervalAggregates(), aggregations); } })); } @@ -109,9 +109,9 @@ public void testViewDataEquals() { measure, DistributionAggregationDescriptor.create(Arrays.asList(10.0)), tagKeys); - List dAggregations = + List dAggregates = Arrays.asList( - DistributionAggregation.create( + DistributionAggregate.create( 5, 5.0, 15.0, Range.create(1.0, 5.0), tags1, Arrays.asList(1L))); IntervalView iView = IntervalView.create( @@ -120,34 +120,34 @@ public void testViewDataEquals() { measure, IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(111))), tagKeys); - List iAggregations = + List iAggregates = Arrays.asList( - IntervalAggregation.create( + IntervalAggregate.create( tags1, Arrays.asList(Interval.create(Duration.fromMillis(111), 10, 100)))); new EqualsTester() .addEqualityGroup( DistributionViewData.create( dView, - dAggregations, + dAggregates, Timestamp.fromMillis(1000), Timestamp.fromMillis(2000)), DistributionViewData.create( dView, - dAggregations, + dAggregates, Timestamp.fromMillis(1000), Timestamp.fromMillis(2000))) .addEqualityGroup( DistributionViewData.create( dView, - dAggregations, + dAggregates, Timestamp.fromMillis(1000), Timestamp.fromMillis(3000))) .addEqualityGroup( - IntervalViewData.create(iView, iAggregations), - IntervalViewData.create(iView, iAggregations)) + IntervalViewData.create(iView, iAggregates), + IntervalViewData.create(iView, iAggregates)) .addEqualityGroup( - IntervalViewData.create(iView, Collections.emptyList())) + IntervalViewData.create(iView, Collections.emptyList())) .testEquals(); } diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java index 0c0d7aee7f..ba954ec8d6 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java +++ b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java @@ -103,15 +103,15 @@ void record(StatsContextImpl context, double value) { @Override final ViewData toViewData(Clock clock) { - final List distributionAggregations = - new ArrayList(); + final List distributionAggregations = + new ArrayList(); for (Entry, MutableDistribution> entry : tagValueDistributionMap.entrySet()) { MutableDistribution distribution = entry.getValue(); - DistributionAggregation distributionAggregation = distribution.getBucketCounts() == null - ? DistributionAggregation.create(distribution.getCount(), distribution.getMean(), + DistributionAggregate distributionAggregation = distribution.getBucketCounts() == null + ? DistributionAggregate.create(distribution.getCount(), distribution.getMean(), distribution.getSum(), convertRange(distribution.getRange()), generateTags(entry.getKey())) - : DistributionAggregation.create(distribution.getCount(), distribution.getMean(), + : DistributionAggregate.create(distribution.getCount(), distribution.getMean(), distribution.getSum(), convertRange(distribution.getRange()), generateTags(entry.getKey()), distribution.getBucketCounts()); distributionAggregations.add(distributionAggregation); @@ -148,10 +148,10 @@ private final List generateTags(List tagValues) { return tags; } - // TODO(songya): remove DistributionAggregation.Range, then remove this method - private static final DistributionAggregation.Range convertRange( + // TODO(songya): remove DistributionAggregate.Range, then remove this method + private static final DistributionAggregate.Range convertRange( MutableDistribution.Range range) { - return DistributionAggregation.Range.create(range.getMin(), range.getMax()); + return DistributionAggregate.Range.create(range.getMin(), range.getMax()); } } diff --git a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java index e3d6534e31..1431e1b662 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java @@ -61,7 +61,7 @@ public Void apply(DistributionViewData view) { assertThat(view.getView()).isEqualTo(VIEW); assertThat(view.getStart()).isEqualTo(Timestamp.create(10, 20)); assertThat(view.getEnd()).isEqualTo(Timestamp.create(30, 40)); - assertThat(view.getDistributionAggregations()).isEmpty(); + assertThat(view.getDistributionAggregates()).isEmpty(); return null; } }, diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index bcb9b52fa5..15055408a3 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -126,7 +126,7 @@ public void testRecordDouble() { new Function() { @Override public Void apply(DistributionViewData view) { - assertThat(view.getDistributionAggregations()).isEmpty(); + assertThat(view.getDistributionAggregates()).isEmpty(); return null; } }, @@ -151,8 +151,8 @@ public Void apply(IntervalViewData view) { new Function() { @Override public Void apply(DistributionViewData view) { - assertThat(view.getDistributionAggregations()).hasSize(1); - DistributionAggregation agg = view.getDistributionAggregations().get(0); + assertThat(view.getDistributionAggregates()).hasSize(1); + DistributionAggregate agg = view.getDistributionAggregates().get(0); assertThat(agg.getTags()) .containsExactly( Tag.create( diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java index 6d2bfb9909..3eb5f933c7 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java @@ -53,93 +53,93 @@ private static StatsContextImpl createContext( } /** - * Creates a {@code DistributionAggregation} by adding the given values to a new {@link + * Creates a {@code DistributionAggregate} by adding the given values to a new {@link * MutableDistribution} that has {@code BucketBoundaries}. * - * @param tags the {@code DistributionAggregation}'s tags. + * @param tags the {@code DistributionAggregate}'s tags. * @param bucketBoundaries the bucket boundaries. * @param values the values to add to the distribution. - * @return the new {@code DistributionAggregation} + * @return the new {@code DistributionAggregate} */ - static DistributionAggregation createDistributionAggregation( + static DistributionAggregate createDistributionAggregate( List tags, BucketBoundaries bucketBoundaries, List values) { MutableDistribution mdist = MutableDistribution.create(bucketBoundaries); for (double value : values) { mdist.add(value); } MutableDistribution.Range range = mdist.getRange(); - return DistributionAggregation.create( + return DistributionAggregate.create( mdist.getCount(), mdist.getMean(), mdist.getSum(), - DistributionAggregation.Range.create(range.getMin(), range.getMax()), + DistributionAggregate.Range.create(range.getMin(), range.getMax()), tags, mdist.getBucketCounts()); } /** - * Creates a {@code DistributionAggregation} by adding the given values to a new {@link + * Creates a {@code DistributionAggregate} by adding the given values to a new {@link * MutableDistribution} that does not have {@code BucketBoundaries}. * - * @param tags the {@code DistributionAggregation}'s tags. + * @param tags the {@code DistributionAggregate}'s tags. * @param values the values to add to the distribution. - * @return the new {@code DistributionAggregation} + * @return the new {@code DistributionAggregate} */ - static DistributionAggregation createDistributionAggregation( + static DistributionAggregate createDistributionAggregate( List tags, List values) { MutableDistribution mdist = MutableDistribution.create(); for (double value : values) { mdist.add(value); } MutableDistribution.Range range = mdist.getRange(); - return DistributionAggregation.create( + return DistributionAggregate.create( mdist.getCount(), mdist.getMean(), mdist.getSum(), - DistributionAggregation.Range.create(range.getMin(), range.getMax()), + DistributionAggregate.Range.create(range.getMin(), range.getMax()), tags); } /** - * Asserts that the two sets of {@code DistributionAggregation}s are equivalent, with a given + * Asserts that the two sets of {@code DistributionAggregate}s are equivalent, with a given * tolerance. The tolerance is used when comparing the mean and sum of values. The order of the - * {@code DistributionAggregation}s has no effect. The expected parameter is last, because it is + * {@code DistributionAggregate}s has no effect. The expected parameter is last, because it is * likely to be a larger expression. * * @param tolerance the tolerance used for {@code double} comparison. * @param actual the actual test result. * @param expected the expected value. - * @throws AssertionError if the {@code DistributionAggregation}s don't match. + * @throws AssertionError if the {@code DistributionAggregate}s don't match. */ - static void assertDistributionAggregationsEquivalent( + static void assertDistributionAggregatesEquivalent( double tolerance, - Collection actual, - Collection expected) { - Function> getTagsFunction = - new Function>() { + Collection actual, + Collection expected) { + Function> getTagsFunction = + new Function>() { @Override - public List apply(DistributionAggregation agg) { + public List apply(DistributionAggregate agg) { return agg.getTags(); } }; Iterable> expectedTags = Iterables.transform(expected, getTagsFunction); Iterable> actualTags = Iterables.transform(actual, getTagsFunction); Truth.assertThat(actualTags).containsExactlyElementsIn(expectedTags); - for (DistributionAggregation expectedAgg : expected) { - DistributionAggregation actualAgg = + for (DistributionAggregate expectedAgg : expected) { + DistributionAggregate actualAgg = Iterables.find( actual, Predicates.compose(Predicates.equalTo(expectedAgg.getTags()), getTagsFunction)); - assertDistributionAggregationValuesEquivalent( - "DistributionAggregation tags=" + expectedAgg.getTags(), + assertDistributionAggregateValuesEquivalent( + "DistributionAggregate tags=" + expectedAgg.getTags(), tolerance, expectedAgg, actualAgg); } } - private static void assertDistributionAggregationValuesEquivalent( - String msg, double tolerance, DistributionAggregation agg1, DistributionAggregation agg2) { + private static void assertDistributionAggregateValuesEquivalent( + String msg, double tolerance, DistributionAggregate agg1, DistributionAggregate agg2) { Truth.assertWithMessage(msg + " count").that(agg1.getCount()).isEqualTo(agg2.getCount()); Truth.assertWithMessage(msg + " mean") .that(agg1.getMean()) diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index c5531d6031..1d74f5f9d4 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -171,10 +171,10 @@ public void testRecord() { assertThat(viewData.getView()).isEqualTo(view); assertThat(viewData.getStart()).isEqualTo(Timestamp.create(1, 2)); assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(3, 4)); - assertDistributionAggregationsEquivalent( - viewData.getDistributionAggregations(), + assertDistributionAggregatesEquivalent( + viewData.getDistributionAggregates(), Arrays.asList( - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(10.0, 20.0, 30.0, 40.0)))); @@ -196,10 +196,10 @@ public void getViewDoesNotClearStats() { DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(10, 0)); assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(11, 0)); - assertDistributionAggregationsEquivalent( - viewData1.getDistributionAggregations(), + assertDistributionAggregatesEquivalent( + viewData1.getDistributionAggregates(), Arrays.asList( - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(0.1)))); statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.2).build()); clock.setTime(Timestamp.create(12, 0)); @@ -209,10 +209,10 @@ public void getViewDoesNotClearStats() { // recorded values: assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(10, 0)); assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(12, 0)); - assertDistributionAggregationsEquivalent( - viewData2.getDistributionAggregations(), + assertDistributionAggregatesEquivalent( + viewData2.getDistributionAggregates(), Arrays.asList( - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(0.1, 0.2)))); @@ -236,12 +236,12 @@ public void testRecordMultipleTagValues() { createContext(factory, KEY, VALUE_2), MeasureMap.builder().set(MEASURE, 50.0).build()); DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertDistributionAggregationsEquivalent( - viewData.getDistributionAggregations(), + assertDistributionAggregatesEquivalent( + viewData.getDistributionAggregates(), Arrays.asList( - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(10.0)), - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList(Tag.create(KEY, VALUE_2)), BUCKET_BOUNDARIES, Arrays.asList(30.0, 50.0)))); @@ -268,10 +268,10 @@ public void testRecordWithEmptyStatsContext() { statsRecorder.record(factory.getDefault(), MeasureMap.builder().set(MEASURE, 10.0).build()); DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertDistributionAggregationsEquivalent( - viewData.getDistributionAggregations(), + assertDistributionAggregatesEquivalent( + viewData.getDistributionAggregates(), Arrays.asList( - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( // Tag is missing for associated measureValues, should use default tag value // "unknown/not set" Arrays.asList(Tag.create(KEY, MutableViewData.UNKNOWN_TAG_VALUE)), @@ -293,7 +293,7 @@ public void testRecordWithNonExistentMeasurementDescriptor() { statsRecorder.record(createContext(factory, KEY, VALUE), MeasureMap.builder().set(measure2, 10.0).build()); DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertThat(view.getDistributionAggregations()).isEmpty(); + assertThat(view.getDistributionAggregates()).isEmpty(); } @Test @@ -311,10 +311,10 @@ public void testRecordWithTagsThatDoNotMatchViewData() { createContext(factory, TagKey.create("another wrong key"), VALUE), MeasureMap.builder().set(MEASURE, 50.0).build()); DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertDistributionAggregationsEquivalent( - view.getDistributionAggregations(), + assertDistributionAggregatesEquivalent( + view.getDistributionAggregates(), Arrays.asList( - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( // Won't record the unregistered tag key, will use default tag instead: // "KEY" : "unknown/not set". Arrays.asList(Tag.create(KEY, MutableViewData.UNKNOWN_TAG_VALUE)), @@ -346,22 +346,22 @@ public void testViewDataWithMultipleTagKeys() { createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), MeasureMap.builder().set(MEASURE, 4.4).build()); DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertDistributionAggregationsEquivalent( - view.getDistributionAggregations(), + assertDistributionAggregatesEquivalent( + view.getDistributionAggregates(), Arrays.asList( - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList( Tag.create(key1, TagValue.create("v1")), Tag.create(key2, TagValue.create("v10"))), BUCKET_BOUNDARIES, Arrays.asList(1.1, 4.4)), - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList( Tag.create(key1, TagValue.create("v1")), Tag.create(key2, TagValue.create("v20"))), BUCKET_BOUNDARIES, Arrays.asList(2.2)), - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList( Tag.create(key1, TagValue.create("v2")), Tag.create(key2, TagValue.create("v10"))), @@ -390,9 +390,9 @@ public void testMultipleViewDatasSameMeasure() { statsRecorder.record( createContext(factory, KEY, VALUE), MeasureMap.builder().set(MEASURE, 5.0).build()); - List expectedAggs = + List expectedAggs = Arrays.asList( - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(5.0))); clock.setTime(Timestamp.create(3, 3)); DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); @@ -400,10 +400,10 @@ public void testMultipleViewDatasSameMeasure() { DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME_2); assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(1, 1)); assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(3, 3)); - assertDistributionAggregationsEquivalent(viewData1.getDistributionAggregations(), expectedAggs); + assertDistributionAggregatesEquivalent(viewData1.getDistributionAggregates(), expectedAggs); assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(2, 2)); assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(4, 4)); - assertDistributionAggregationsEquivalent(viewData2.getDistributionAggregations(), expectedAggs); + assertDistributionAggregatesEquivalent(viewData2.getDistributionAggregates(), expectedAggs); } @Test @@ -431,17 +431,17 @@ public void testMultipleViewsDifferentMeasures() { DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME_2); assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(1, 0)); assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(3, 0)); - assertDistributionAggregationsEquivalent( - viewData1.getDistributionAggregations(), + assertDistributionAggregatesEquivalent( + viewData1.getDistributionAggregates(), Arrays.asList( - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(1.1)))); assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(2, 0)); assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(4, 0)); - assertDistributionAggregationsEquivalent( - viewData2.getDistributionAggregations(), + assertDistributionAggregatesEquivalent( + viewData2.getDistributionAggregates(), Arrays.asList( - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(2.2)))); } @@ -460,17 +460,17 @@ public void testGetDistributionViewDataWithoutBucketBoundaries() { DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); assertThat(viewData.getStart()).isEqualTo(Timestamp.create(1, 0)); assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(3, 0)); - assertDistributionAggregationsEquivalent( - viewData.getDistributionAggregations(), + assertDistributionAggregatesEquivalent( + viewData.getDistributionAggregates(), Arrays.asList( - StatsTestUtil.createDistributionAggregation( + StatsTestUtil.createDistributionAggregate( Arrays.asList(Tag.create(KEY, VALUE)), Arrays.asList(1.1)))); } // TODO(sebright) Consider making this helper method work with larger ranges of double values and // moving it to StatsTestUtil. - private static void assertDistributionAggregationsEquivalent( - Collection actual, Collection expected) { - StatsTestUtil.assertDistributionAggregationsEquivalent(1e-6, actual, expected); + private static void assertDistributionAggregatesEquivalent( + Collection actual, Collection expected) { + StatsTestUtil.assertDistributionAggregatesEquivalent(1e-6, actual, expected); } } From 801f05ae8966cde13380cf5d823739c428f3e3ac Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 10 Jul 2017 10:37:25 -0700 Subject: [PATCH 0271/1581] Specify that the issue template only applies to bug reports. --- .github/ISSUE_TEMPLATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE index 3118cd3722..7d484c6290 100644 --- a/.github/ISSUE_TEMPLATE +++ b/.github/ISSUE_TEMPLATE @@ -1,4 +1,4 @@ -Please answer these questions before submitting your issue. +Please answer these questions before submitting a bug report. ### What version of OpenCensus are you using? From 48ccf074e5aa6c116675fe36b11d21d847995ac2 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Mon, 10 Jul 2017 11:59:04 -0700 Subject: [PATCH 0272/1581] Rename AggregationDescriptor to Aggregation. (#441) --- .../stats/DistributionAggregate.java | 12 +-- ...ptor.java => DistributionAggregation.java} | 14 ++-- ...scriptor.java => IntervalAggregation.java} | 14 ++-- .../io/opencensus/stats/RpcViewConstants.java | 80 +++++++++---------- .../main/java/io/opencensus/stats/View.java | 24 +++--- ....java => DistributionAggregationTest.java} | 32 ++++---- ...Test.java => IntervalAggregationTest.java} | 40 +++++----- .../io/opencensus/stats/ViewDataTest.java | 16 ++-- .../java/io/opencensus/stats/ViewTest.java | 32 ++++---- .../io/opencensus/stats/MutableViewData.java | 2 +- .../stats/MeasureToViewMapTest.java | 2 +- .../io/opencensus/stats/StatsContextTest.java | 2 +- .../opencensus/stats/ViewManagerImplTest.java | 14 ++-- 13 files changed, 142 insertions(+), 142 deletions(-) rename core/src/main/java/io/opencensus/stats/{DistributionAggregationDescriptor.java => DistributionAggregation.java} (81%) rename core/src/main/java/io/opencensus/stats/{IntervalAggregationDescriptor.java => IntervalAggregation.java} (84%) rename core/src/test/java/io/opencensus/stats/{DistributionAggregationDescriptorTest.java => DistributionAggregationTest.java} (52%) rename core/src/test/java/io/opencensus/stats/{IntervalAggregationDescriptorTest.java => IntervalAggregationTest.java} (54%) diff --git a/core/src/main/java/io/opencensus/stats/DistributionAggregate.java b/core/src/main/java/io/opencensus/stats/DistributionAggregate.java index 8aab957c90..a2eabb0430 100644 --- a/core/src/main/java/io/opencensus/stats/DistributionAggregate.java +++ b/core/src/main/java/io/opencensus/stats/DistributionAggregate.java @@ -27,7 +27,7 @@ * *

            A distribution contains summary statistics for a population of values and, optionally, a * histogram representing the distribution of those values across a specified set of histogram - * buckets, as defined in {@link DistributionAggregationDescriptor#getBucketBoundaries()}. + * buckets, as defined in {@link DistributionAggregation#getBucketBoundaries()}. * *

            Although not forbidden, it is generally a bad idea to include non-finite values (infinities or * NaNs) in the population of values, as this will render the {@code mean} meaningless. @@ -123,12 +123,12 @@ private static DistributionAggregate createInternal( /** * Returns the bucket counts, or {@code null} if this {@code DistributionAggregate}'s associated - * {@link DistributionAggregationDescriptor} has no buckets. + * {@link DistributionAggregation} has no buckets. * *

            A Distribution may contain a histogram of the values in the population. The histogram is * given in {@link #getBucketCounts()} as counts of values that fall into one of a sequence of * non-overlapping buckets, described by {@link - * DistributionAggregationDescriptor#getBucketBoundaries()}. The sum of the values in {@link + * DistributionAggregation#getBucketBoundaries()}. The sum of the values in {@link * #getBucketCounts()} must equal the value in {@link #getCount()}. * *

            Bucket counts are given in order under the numbering scheme described in the link above (the @@ -136,15 +136,15 @@ private static DistributionAggregate createInternal( * overflow bucket has number N-1). * *

            The size of {@link #getBucketCounts()} must be no greater than N as defined in {@link - * DistributionAggregationDescriptor#getBucketBoundaries()}. + * DistributionAggregation#getBucketBoundaries()}. * *

            Any suffix of trailing buckets containing only zero may be omitted. * *

            {@link #getBucketCounts()} will return null iff the associated {@link - * DistributionAggregationDescriptor#getBucketBoundaries()} returns null. + * DistributionAggregation#getBucketBoundaries()} returns null. * * @return the bucket counts, or {@code null} if this {@code DistributionAggregate}'s associated - * {@link DistributionAggregationDescriptor} has no buckets. + * {@link DistributionAggregation} has no buckets. */ @Nullable public abstract List getBucketCounts(); diff --git a/core/src/main/java/io/opencensus/stats/DistributionAggregationDescriptor.java b/core/src/main/java/io/opencensus/stats/DistributionAggregation.java similarity index 81% rename from core/src/main/java/io/opencensus/stats/DistributionAggregationDescriptor.java rename to core/src/main/java/io/opencensus/stats/DistributionAggregation.java index 88b2bfea4e..120fc27cc1 100644 --- a/core/src/main/java/io/opencensus/stats/DistributionAggregationDescriptor.java +++ b/core/src/main/java/io/opencensus/stats/DistributionAggregation.java @@ -38,26 +38,26 @@ */ @Immutable @AutoValue -public abstract class DistributionAggregationDescriptor { +public abstract class DistributionAggregation { /** - * Constructs a new {@link DistributionAggregationDescriptor} with the optional + * Constructs a new {@link DistributionAggregation} with the optional * histogram bucket boundaries. */ - public static DistributionAggregationDescriptor create(List bucketBoundaries) { + public static DistributionAggregation create(List bucketBoundaries) { return createInternal(BucketBoundaries.create(bucketBoundaries)); } /** - * Constructs a new {@link DistributionAggregationDescriptor} without the optional + * Constructs a new {@link DistributionAggregation} without the optional * histogram bucket boundaries. */ - public static DistributionAggregationDescriptor create() { + public static DistributionAggregation create() { return createInternal(null); } - private static DistributionAggregationDescriptor createInternal( + private static DistributionAggregation createInternal( @Nullable BucketBoundaries bucketBoundaries) { - return new AutoValue_DistributionAggregationDescriptor(bucketBoundaries); + return new AutoValue_DistributionAggregation(bucketBoundaries); } /** diff --git a/core/src/main/java/io/opencensus/stats/IntervalAggregationDescriptor.java b/core/src/main/java/io/opencensus/stats/IntervalAggregation.java similarity index 84% rename from core/src/main/java/io/opencensus/stats/IntervalAggregationDescriptor.java rename to core/src/main/java/io/opencensus/stats/IntervalAggregation.java index 01477f399d..0562969b3c 100644 --- a/core/src/main/java/io/opencensus/stats/IntervalAggregationDescriptor.java +++ b/core/src/main/java/io/opencensus/stats/IntervalAggregation.java @@ -22,16 +22,16 @@ /** * Describes data aggregations based on time intervals. */ -public final class IntervalAggregationDescriptor { +public final class IntervalAggregation { /** - * Constructs a new {@link IntervalAggregationDescriptor}. + * Constructs a new {@link IntervalAggregation}. * *

            The given {@code numSubIntervals} must be in the range [2, 20], see * {@link #getNumSubIntervals()} for more details. * *

            The given {@code intervalSizes} must have at least one entry. */ - public static IntervalAggregationDescriptor create( + public static IntervalAggregation create( int numSubIntervals, List intervalSizes) { if (numSubIntervals < 2 || numSubIntervals > 20) { throw new IllegalArgumentException( @@ -40,16 +40,16 @@ public static IntervalAggregationDescriptor create( if (intervalSizes.isEmpty()) { throw new IllegalArgumentException("There must be at least one interval size."); } - return new IntervalAggregationDescriptor( + return new IntervalAggregation( numSubIntervals, Collections.unmodifiableList(new ArrayList(intervalSizes))); } /** - * Constructs a new {@link IntervalAggregationDescriptor} with the number of sub intervals set + * Constructs a new {@link IntervalAggregation} with the number of sub intervals set * to the default value of 5. */ - public static IntervalAggregationDescriptor create(List intervalSizes) { + public static IntervalAggregation create(List intervalSizes) { return create(5, intervalSizes); } @@ -79,7 +79,7 @@ public List getIntervalSizes() { private final int numSubIntervals; private final List intervalSizes; - private IntervalAggregationDescriptor(int numSubIntervals, List intervalSizes) { + private IntervalAggregation(int numSubIntervals, List intervalSizes) { this.numSubIntervals = numSubIntervals; this.intervalSizes = intervalSizes; } diff --git a/core/src/main/java/io/opencensus/stats/RpcViewConstants.java b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java index db518c1e6e..a861867654 100644 --- a/core/src/main/java/io/opencensus/stats/RpcViewConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java @@ -68,63 +68,63 @@ public final class RpcViewConstants { "grpc.io/client/error_count/distribution_cumulative", "RPC Errors", RPC_CLIENT_ERROR_COUNT, - DistributionAggregationDescriptor.create(), + DistributionAggregation.create(), Arrays.asList(RPC_STATUS, RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW = DistributionView.create( "grpc.io/client/roundtrip_latency/distribution_cumulative", "Latency in msecs", RPC_CLIENT_ROUNDTRIP_LATENCY, - DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_SERVER_ELAPSED_TIME_VIEW = DistributionView.create( "grpc.io/client/server_elapsed_time/distribution_cumulative", "Server elapsed time in msecs", RPC_CLIENT_SERVER_ELAPSED_TIME, - DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_REQUEST_BYTES_VIEW = DistributionView.create( "grpc.io/client/request_bytes/distribution_cumulative", "Request bytes", RPC_CLIENT_REQUEST_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_RESPONSE_BYTES_VIEW = DistributionView.create( "grpc.io/client/response_bytes/distribution_cumulative", "Response bytes", RPC_CLIENT_RESPONSE_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_VIEW = DistributionView.create( "grpc.io/client/uncompressed_request_bytes/distribution_cumulative", "Uncompressed Request bytes", RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_VIEW = DistributionView.create( "grpc.io/client/uncompressed_response_bytes/distribution_cumulative", "Uncompressed Response bytes", RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_REQUEST_COUNT_VIEW = DistributionView.create( "grpc.io/client/request_count/distribution_cumulative", "Count of request messages per client RPC", RPC_CLIENT_REQUEST_COUNT, - DistributionAggregationDescriptor.create(), + DistributionAggregation.create(), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_RESPONSE_COUNT_VIEW = DistributionView.create( "grpc.io/client/response_count/distribution_cumulative", "Count of response messages per client RPC", RPC_CLIENT_RESPONSE_COUNT, - DistributionAggregationDescriptor.create(), + DistributionAggregation.create(), Arrays.asList(RPC_CLIENT_METHOD)); @@ -134,63 +134,63 @@ public final class RpcViewConstants { "grpc.io/server/error_count/distribution_cumulative", "RPC Errors", RPC_SERVER_ERROR_COUNT, - DistributionAggregationDescriptor.create(), + DistributionAggregation.create(), Arrays.asList(RPC_STATUS, RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_SERVER_LATENCY_VIEW = DistributionView.create( "grpc.io/server/server_latency/distribution_cumulative", "Latency in msecs", RPC_SERVER_SERVER_LATENCY, - DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_SERVER_ELAPSED_TIME_VIEW = DistributionView.create( "grpc.io/server/elapsed_time/distribution_cumulative", "Server elapsed time in msecs", RPC_SERVER_SERVER_ELAPSED_TIME, - DistributionAggregationDescriptor.create(RPC_MILLIS_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_REQUEST_BYTES_VIEW = DistributionView.create( "grpc.io/server/request_bytes/distribution_cumulative", "Request bytes", RPC_SERVER_REQUEST_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_RESPONSE_BYTES_VIEW = DistributionView.create( "grpc.io/server/response_bytes/distribution_cumulative", "Response bytes", RPC_SERVER_RESPONSE_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_VIEW = DistributionView.create( "grpc.io/server/uncompressed_request_bytes/distribution_cumulative", "Uncompressed Request bytes", RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_VIEW = DistributionView.create( "grpc.io/server/uncompressed_response_bytes/distribution_cumulative", "Uncompressed Response bytes", RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, - DistributionAggregationDescriptor.create(RPC_BYTES_BUCKET_BOUNDARIES), + DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_REQUEST_COUNT_VIEW = DistributionView.create( "grpc.io/server/request_count/distribution_cumulative", "Count of request messages per server RPC", RPC_SERVER_REQUEST_COUNT, - DistributionAggregationDescriptor.create(), + DistributionAggregation.create(), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_RESPONSE_COUNT_VIEW = DistributionView.create( "grpc.io/server/response_count/distribution_cumulative", "Count of response messages per server RPC", RPC_SERVER_RESPONSE_COUNT, - DistributionAggregationDescriptor.create(), + DistributionAggregation.create(), Arrays.asList(RPC_SERVER_METHOD)); // Interval Stats @@ -203,7 +203,7 @@ public final class RpcViewConstants { "grpc.io/client/roundtrip_latency/interval", "Minute and Hour stats for latency in msecs", RPC_CLIENT_ROUNDTRIP_LATENCY, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); public static final IntervalView RPC_CLIENT_REQUEST_BYTES_INTERVAL_VIEW = @@ -211,7 +211,7 @@ public final class RpcViewConstants { "grpc.io/client/request_bytes/interval", "Minute and Hour stats for request size in bytes", RPC_CLIENT_REQUEST_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); public static final IntervalView RPC_CLIENT_RESPONSE_BYTES_INTERVAL_VIEW = @@ -219,7 +219,7 @@ public final class RpcViewConstants { "grpc.io/client/response_bytes/interval", "Minute and Hour stats for response size in bytes", RPC_CLIENT_RESPONSE_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); public static final IntervalView RPC_CLIENT_ERROR_COUNT_INTERVAL_VIEW = @@ -227,7 +227,7 @@ public final class RpcViewConstants { "grpc.io/client/error_count/interval", "Minute and Hour stats for rpc errors", RPC_CLIENT_ERROR_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); public static final IntervalView RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = @@ -235,7 +235,7 @@ public final class RpcViewConstants { "grpc.io/client/uncompressed_request_bytes/interval", "Minute and Hour stats for uncompressed request size in bytes", RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); public static final IntervalView RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = @@ -243,7 +243,7 @@ public final class RpcViewConstants { "grpc.io/client/uncompressed_response_bytes/interval", "Minute and Hour stats for uncompressed response size in bytes", RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); public static final IntervalView RPC_CLIENT_SERVER_ELAPSED_TIME_INTERVAL_VIEW = @@ -251,7 +251,7 @@ public final class RpcViewConstants { "grpc.io/client/server_elapsed_time/interval", "Minute and Hour stats for server elapsed time in msecs", RPC_CLIENT_SERVER_ELAPSED_TIME, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); public static final IntervalView RPC_CLIENT_STARTED_COUNT_INTERVAL_VIEW = @@ -259,7 +259,7 @@ public final class RpcViewConstants { "grpc.io/client/started_count/interval", "Minute and Hour stats on the number of client RPCs started", RPC_CLIENT_STARTED_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); public static final IntervalView RPC_CLIENT_FINISHED_COUNT_INTERVAL_VIEW = @@ -267,7 +267,7 @@ public final class RpcViewConstants { "grpc.io/client/finished_count/interval", "Minute and Hour stats on the number of client RPCs finished", RPC_CLIENT_FINISHED_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); public static final IntervalView RPC_CLIENT_REQUEST_COUNT_INTERVAL_VIEW = @@ -275,7 +275,7 @@ public final class RpcViewConstants { "grpc.io/client/request_count/interval", "Minute and Hour stats on the count of request messages per client RPC", RPC_CLIENT_REQUEST_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); public static final IntervalView RPC_CLIENT_RESPONSE_COUNT_INTERVAL_VIEW = @@ -283,7 +283,7 @@ public final class RpcViewConstants { "grpc.io/client/response_count/interval", "Minute and Hour stats on the count of response messages per client RPC", RPC_CLIENT_RESPONSE_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_CLIENT_METHOD)); // RPC server {@link IntervalView}s. @@ -292,7 +292,7 @@ public final class RpcViewConstants { "grpc.io/server/server_latency/interval", "Minute and Hour stats for server latency in msecs", RPC_SERVER_SERVER_LATENCY, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); public static final IntervalView RPC_SERVER_REQUEST_BYTES_INTERVAL_VIEW = @@ -300,7 +300,7 @@ public final class RpcViewConstants { "grpc.io/server/request_bytes/interval", "Minute and Hour stats for request size in bytes", RPC_SERVER_REQUEST_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); public static final IntervalView RPC_SERVER_RESPONSE_BYTES_INTERVAL_VIEW = @@ -308,7 +308,7 @@ public final class RpcViewConstants { "grpc.io/server/response_bytes/interval", "Minute and Hour stats for response size in bytes", RPC_SERVER_RESPONSE_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); public static final IntervalView RPC_SERVER_ERROR_COUNT_INTERVAL_VIEW = @@ -316,7 +316,7 @@ public final class RpcViewConstants { "grpc.io/server/error_count/interval", "Minute and Hour stats for rpc errors", RPC_SERVER_ERROR_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); public static final IntervalView RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = @@ -324,7 +324,7 @@ public final class RpcViewConstants { "grpc.io/server/uncompressed_request_bytes/interval", "Minute and Hour stats for uncompressed request size in bytes", RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); public static final IntervalView RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = @@ -332,7 +332,7 @@ public final class RpcViewConstants { "grpc.io/server/uncompressed_response_bytes/interval", "Minute and Hour stats for uncompressed response size in bytes", RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); public static final IntervalView RPC_SERVER_SERVER_ELAPSED_TIME_INTERVAL_VIEW = @@ -340,7 +340,7 @@ public final class RpcViewConstants { "grpc.io/server/server_elapsed_time/interval", "Minute and Hour stats for server elapsed time in msecs", RPC_SERVER_SERVER_ELAPSED_TIME, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); public static final IntervalView RPC_SERVER_STARTED_COUNT_INTERVAL_VIEW = @@ -348,7 +348,7 @@ public final class RpcViewConstants { "grpc.io/server/started_count/interval", "Minute and Hour stats on the number of server RPCs started", RPC_SERVER_STARTED_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); public static final IntervalView RPC_SERVER_FINISHED_COUNT_INTERVAL_VIEW = @@ -356,7 +356,7 @@ public final class RpcViewConstants { "grpc.io/server/finished_count/interval", "Minute and Hour stats on the number of server RPCs finished", RPC_SERVER_FINISHED_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); public static final IntervalView RPC_SERVER_REQUEST_COUNT_INTERVAL_VIEW = @@ -364,7 +364,7 @@ public final class RpcViewConstants { "grpc.io/server/request_count/interval", "Minute and Hour stats on the count of request messages per server RPC", RPC_SERVER_REQUEST_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); public static final IntervalView RPC_SERVER_RESPONSE_COUNT_INTERVAL_VIEW = @@ -372,7 +372,7 @@ public final class RpcViewConstants { "grpc.io/server/response_count/interval", "Minute and Hour stats on the count of response messages per server RPC", RPC_SERVER_RESPONSE_COUNT, - IntervalAggregationDescriptor.create(Arrays.asList(MINUTE, HOUR)), + IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), Arrays.asList(RPC_SERVER_METHOD)); // Visible for testing. diff --git a/core/src/main/java/io/opencensus/stats/View.java b/core/src/main/java/io/opencensus/stats/View.java index 1a431ac13b..d50053c927 100644 --- a/core/src/main/java/io/opencensus/stats/View.java +++ b/core/src/main/java/io/opencensus/stats/View.java @@ -105,13 +105,13 @@ public static DistributionView create( String name, String description, Measure measure, - DistributionAggregationDescriptor distributionAggregationDescriptor, + DistributionAggregation distributionAggregation, List tagKeys) { return create( Name.create(name), description, measure, - distributionAggregationDescriptor, + distributionAggregation, tagKeys); } @@ -122,21 +122,21 @@ public static DistributionView create( Name name, String description, Measure measure, - DistributionAggregationDescriptor distributionAggregationDescriptor, + DistributionAggregation distributionAggregation, List tagKeys) { return new AutoValue_View_DistributionView( name, description, measure, Collections.unmodifiableList(new ArrayList(tagKeys)), - distributionAggregationDescriptor); + distributionAggregation); } /** - * The {@link DistributionAggregationDescriptor} associated with this + * The {@link DistributionAggregation} associated with this * {@link DistributionView}. */ - public abstract DistributionAggregationDescriptor getDistributionAggregationDescriptor(); + public abstract DistributionAggregation getDistributionAggregation(); @Override public T match( @@ -159,13 +159,13 @@ public static IntervalView create( String name, String description, Measure measure, - IntervalAggregationDescriptor intervalAggregationDescriptor, + IntervalAggregation intervalAggregation, List tagKeys) { return create( Name.create(name), description, measure, - intervalAggregationDescriptor, + intervalAggregation, tagKeys); } @@ -176,21 +176,21 @@ public static IntervalView create( Name name, String description, Measure measure, - IntervalAggregationDescriptor intervalAggregationDescriptor, + IntervalAggregation intervalAggregation, List tagKeys) { return new AutoValue_View_IntervalView( name, description, measure, Collections.unmodifiableList(new ArrayList(tagKeys)), - intervalAggregationDescriptor); + intervalAggregation); } /** - * The {@link IntervalAggregationDescriptor} associated with this + * The {@link IntervalAggregation} associated with this * {@link IntervalView}. */ - public abstract IntervalAggregationDescriptor getIntervalAggregationDescriptor(); + public abstract IntervalAggregation getIntervalAggregation(); @Override public T match( diff --git a/core/src/test/java/io/opencensus/stats/DistributionAggregationDescriptorTest.java b/core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java similarity index 52% rename from core/src/test/java/io/opencensus/stats/DistributionAggregationDescriptorTest.java rename to core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java index 065c6bb5f4..8d9ac23eed 100644 --- a/core/src/test/java/io/opencensus/stats/DistributionAggregationDescriptorTest.java +++ b/core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java @@ -22,38 +22,38 @@ import org.junit.runners.JUnit4; /** - * Tests for {@link DistributionAggregationDescriptor} + * Tests for {@link DistributionAggregation} */ @RunWith(JUnit4.class) -public final class DistributionAggregationDescriptorTest { +public final class DistributionAggregationTest { @Test - public void testDistributionAggregationDescriptorEmpty() { - DistributionAggregationDescriptor dDescriptor = DistributionAggregationDescriptor.create(); - assertThat(dDescriptor.getBucketBoundaries()).isNull(); + public void testDistributionAggregationEmpty() { + DistributionAggregation d = DistributionAggregation.create(); + assertThat(d.getBucketBoundaries()).isNull(); } @Test - public void testDistributionAggregationDescriptor() { + public void testDistributionAggregation() { Double[] buckets = new Double[] { 0.1, 2.2, 33.3 }; - DistributionAggregationDescriptor dDescriptor = - DistributionAggregationDescriptor.create(Arrays.asList(buckets)); - assertThat(dDescriptor.getBucketBoundaries()).isNotNull(); - assertThat(dDescriptor.getBucketBoundaries()).hasSize(buckets.length); + DistributionAggregation d = + DistributionAggregation.create(Arrays.asList(buckets)); + assertThat(d.getBucketBoundaries()).isNotNull(); + assertThat(d.getBucketBoundaries()).hasSize(buckets.length); for (int i = 0; i < buckets.length; i++) { - assertThat(dDescriptor.getBucketBoundaries().get(i)) + assertThat(d.getBucketBoundaries().get(i)) .isWithin(0.00000001).of(buckets[i]); } } @Test - public void testDistributionAggregationDescriptorEquals() { + public void testDistributionAggregationEquals() { new EqualsTester() .addEqualityGroup( - DistributionAggregationDescriptor.create(Arrays.asList(1.0, 2.0, 5.0)), - DistributionAggregationDescriptor.create(Arrays.asList(1.0, 2.0, 5.0))) + DistributionAggregation.create(Arrays.asList(1.0, 2.0, 5.0)), + DistributionAggregation.create(Arrays.asList(1.0, 2.0, 5.0))) .addEqualityGroup( - DistributionAggregationDescriptor.create(), - DistributionAggregationDescriptor.create()) + DistributionAggregation.create(), + DistributionAggregation.create()) .testEquals(); } } diff --git a/core/src/test/java/io/opencensus/stats/IntervalAggregationDescriptorTest.java b/core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java similarity index 54% rename from core/src/test/java/io/opencensus/stats/IntervalAggregationDescriptorTest.java rename to core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java index 62b658f0d6..0c7029ed8e 100644 --- a/core/src/test/java/io/opencensus/stats/IntervalAggregationDescriptorTest.java +++ b/core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java @@ -22,56 +22,56 @@ import org.junit.runners.JUnit4; /** - * Tests for {@link IntervalAggregationDescriptor} + * Tests for {@link IntervalAggregation} */ @RunWith(JUnit4.class) -public final class IntervalAggregationDescriptorTest { +public final class IntervalAggregationTest { @Test - public void testIntervalAggregationDescriptor() { + public void testIntervalAggregation() { Duration[] intervals = new Duration[] { Duration.fromMillis(1), Duration.fromMillis(22), Duration.fromMillis(333)}; - IntervalAggregationDescriptor iDescriptor = - IntervalAggregationDescriptor.create(12, Arrays.asList(intervals)); - assertThat(iDescriptor.getNumSubIntervals()).isEqualTo(12); - assertThat(iDescriptor.getIntervalSizes()).isNotNull(); - assertThat(iDescriptor.getIntervalSizes()).hasSize(intervals.length); + IntervalAggregation intervalAggregation = + IntervalAggregation.create(12, Arrays.asList(intervals)); + assertThat(intervalAggregation.getNumSubIntervals()).isEqualTo(12); + assertThat(intervalAggregation.getIntervalSizes()).isNotNull(); + assertThat(intervalAggregation.getIntervalSizes()).hasSize(intervals.length); for (int i = 0; i < intervals.length; i++) { - assertThat(iDescriptor.getIntervalSizes().get(i)).isEqualTo(intervals[i]); + assertThat(intervalAggregation.getIntervalSizes().get(i)).isEqualTo(intervals[i]); } } @Test - public void testIntervalAggregationDescriptorWithDefaultNumSubIntervals() { + public void testIntervalAggregationWithDefaultNumSubIntervals() { assertThat( - IntervalAggregationDescriptor.create( + IntervalAggregation.create( Arrays.asList(Duration.fromMillis(1))).getNumSubIntervals()) .isEqualTo(5); } @Test - public void testIntervalAggregationDescriptorNumSubIntervalsRange() { + public void testIntervalAggregationNumSubIntervalsRange() { assertThat( - IntervalAggregationDescriptor.create( + IntervalAggregation.create( 2, Arrays.asList(Duration.fromMillis(1))).getNumSubIntervals()) .isEqualTo(2); assertThat( - IntervalAggregationDescriptor.create( + IntervalAggregation.create( 20, Arrays.asList(Duration.fromMillis(1))).getNumSubIntervals()) .isEqualTo(20); } @Test(expected = IllegalArgumentException.class) - public void testIntervalAggregationDescriptorLowNumSubIntervals() { - IntervalAggregationDescriptor.create(1, Arrays.asList(Duration.fromMillis(1))); + public void testIntervalAggregationLowNumSubIntervals() { + IntervalAggregation.create(1, Arrays.asList(Duration.fromMillis(1))); } @Test(expected = IllegalArgumentException.class) - public void testIntervalAggregationDescriptorHighNumSubIntervals() { - IntervalAggregationDescriptor.create(21, Arrays.asList(Duration.fromMillis(1))); + public void testIntervalAggregationHighNumSubIntervals() { + IntervalAggregation.create(21, Arrays.asList(Duration.fromMillis(1))); } @Test(expected = IllegalArgumentException.class) - public void testIntervalAggregationDescriptorEmptyIntervalSizes() { - IntervalAggregationDescriptor.create(Arrays.asList(new Duration[] { })); + public void testIntervalAggregationEmptyIntervalSizes() { + IntervalAggregation.create(Arrays.asList(new Duration[] { })); } } diff --git a/core/src/test/java/io/opencensus/stats/ViewDataTest.java b/core/src/test/java/io/opencensus/stats/ViewDataTest.java index 6390af6fa6..877643495b 100644 --- a/core/src/test/java/io/opencensus/stats/ViewDataTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewDataTest.java @@ -38,11 +38,11 @@ public final class ViewDataTest { @Test public void testDistributionViewData() { - DistributionAggregationDescriptor aggregationDescriptor = - DistributionAggregationDescriptor.create(Arrays.asList(10.0, 20.0, 30.0, 40.0)); + DistributionAggregation aggregation = + DistributionAggregation.create(Arrays.asList(10.0, 20.0, 30.0, 40.0)); final DistributionView view = DistributionView.create( - name, description, measure, aggregationDescriptor, tagKeys); + name, description, measure, aggregation, tagKeys); final List aggregations = Arrays.asList( DistributionAggregate.create(5, 5.0, 15.0, Range.create(1.0, 5.0), tags1, Arrays.asList(1L, 1L, 1L, 1L, 1L)), @@ -72,11 +72,11 @@ && shallowListEquals(dViewData.getDistributionAggregates(), aggregations) @Test public void testIntervalViewData() { - IntervalAggregationDescriptor aggregationDescriptor = - IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(111))); + IntervalAggregation aggregation = + IntervalAggregation.create(Arrays.asList(Duration.fromMillis(111))); final IntervalView view = IntervalView.create( - name, description, measure, aggregationDescriptor, tagKeys); + name, description, measure, aggregation, tagKeys); final List aggregations = Arrays.asList( IntervalAggregate.create(tags1, Arrays.asList( Interval.create(Duration.fromMillis(111), 10, 100))), @@ -107,7 +107,7 @@ public void testViewDataEquals() { name, description, measure, - DistributionAggregationDescriptor.create(Arrays.asList(10.0)), + DistributionAggregation.create(Arrays.asList(10.0)), tagKeys); List dAggregates = Arrays.asList( @@ -118,7 +118,7 @@ public void testViewDataEquals() { name, description, measure, - IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(111))), + IntervalAggregation.create(Arrays.asList(Duration.fromMillis(111))), tagKeys); List iAggregates = Arrays.asList( diff --git a/core/src/test/java/io/opencensus/stats/ViewTest.java b/core/src/test/java/io/opencensus/stats/ViewTest.java index 43562aa94d..7deab08f3b 100644 --- a/core/src/test/java/io/opencensus/stats/ViewTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewTest.java @@ -32,9 +32,9 @@ public final class ViewTest { @Test public void testDistributionView() { - DistributionAggregationDescriptor dAggrDescriptor = DistributionAggregationDescriptor.create(); + DistributionAggregation dAggr = DistributionAggregation.create(); final View view = DistributionView.create( - name, description, measure, dAggrDescriptor, keys); + name, description, measure, dAggr, keys); assertThat(view.getViewName()).isEqualTo(name); assertThat(view.getName()).isEqualTo(name.asString()); @@ -58,10 +58,10 @@ public void testDistributionView() { @Test public void testIntervalView() { - IntervalAggregationDescriptor iAggrDescriptor = IntervalAggregationDescriptor.create( + IntervalAggregation iAggr = IntervalAggregation.create( Arrays.asList(Duration.fromMillis(1), Duration.fromMillis(22), Duration.fromMillis(333))); final View view = IntervalView.create( - name, description, measure, iAggrDescriptor, keys); + name, description, measure, iAggr, keys); assertThat(view.getViewName()).isEqualTo(name); assertThat(view.getName()).isEqualTo(name.asString()); @@ -86,26 +86,26 @@ public void testIntervalView() { @Test public void testViewEquals() { - DistributionAggregationDescriptor dAggrDescriptor = DistributionAggregationDescriptor.create(); - IntervalAggregationDescriptor iAggrDescriptor = IntervalAggregationDescriptor.create( + DistributionAggregation dAggr = DistributionAggregation.create(); + IntervalAggregation iAggr = IntervalAggregation.create( Arrays.asList(Duration.fromMillis(1), Duration.fromMillis(22), Duration.fromMillis(333))); new EqualsTester() .addEqualityGroup( DistributionView.create( - name, description, measure, dAggrDescriptor, keys), + name, description, measure, dAggr, keys), DistributionView.create( - name, description, measure, dAggrDescriptor, keys)) + name, description, measure, dAggr, keys)) .addEqualityGroup( DistributionView.create( - name, description + 2, measure, dAggrDescriptor, keys)) + name, description + 2, measure, dAggr, keys)) .addEqualityGroup( IntervalView.create( - name, description, measure, iAggrDescriptor, keys), + name, description, measure, iAggr, keys), IntervalView.create( - name, description, measure, iAggrDescriptor, keys)) + name, description, measure, iAggr, keys)) .addEqualityGroup( IntervalView.create( - name, description + 2, measure, iAggrDescriptor, keys)) + name, description + 2, measure, iAggr, keys)) .testEquals(); } @@ -115,7 +115,7 @@ public void preventNullDistributionViewName() { (View.Name) null, description, measure, - DistributionAggregationDescriptor.create(), + DistributionAggregation.create(), keys); } @@ -125,7 +125,7 @@ public void preventNullDistributionViewStringName() { (String) null, description, measure, - DistributionAggregationDescriptor.create(), + DistributionAggregation.create(), keys); } @@ -135,7 +135,7 @@ public void preventNullIntervalViewName() { (View.Name) null, description, measure, - IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(1))), + IntervalAggregation.create(Arrays.asList(Duration.fromMillis(1))), keys); } @@ -145,7 +145,7 @@ public void preventNullIntervalViewStringName() { (String) null, description, measure, - IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(1))), + IntervalAggregation.create(Arrays.asList(Duration.fromMillis(1))), keys); } diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java index ba954ec8d6..d8458a2254 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java +++ b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java @@ -91,7 +91,7 @@ void record(StatsContextImpl context, double value) { if (!tagValueDistributionMap.containsKey(tagValues)) { final List bucketBoundaries = - this.distributionView.getDistributionAggregationDescriptor() + this.distributionView.getDistributionAggregation() .getBucketBoundaries(); final MutableDistribution distribution = bucketBoundaries == null ? MutableDistribution.create() diff --git a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java index 1431e1b662..5eaa34ca41 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java @@ -44,7 +44,7 @@ public class MeasureToViewMapTest { VIEW_NAME, "view description", MEASURE, - DistributionAggregationDescriptor.create(), + DistributionAggregation.create(), Arrays.asList(TagKey.create("my key"))); @Test diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index 15055408a3..7297b563aa 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -175,7 +175,7 @@ public Void apply(IntervalViewData view) { public void testRecordLong() { MeasureLong measure = MeasureLong.create("long measure", "description", "1"); viewManager.registerView(View.DistributionView - .create("name", "description", measure, DistributionAggregationDescriptor.create(), + .create("name", "description", measure, DistributionAggregation.create(), Arrays.asList(K1))); thrown.expect(UnsupportedOperationException.class); defaultStatsContext.with(K1, V1).record(MeasureMap.builder().set(measure,1L).build()); diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index 1d74f5f9d4..6341daa473 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -67,8 +67,8 @@ public class ViewManagerImplTest { Arrays.asList( 0.0, 0.2, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0)); - private static final DistributionAggregationDescriptor DISTRIBUTION_AGGREGATION_DESCRIPTOR = - DistributionAggregationDescriptor.create(BUCKET_BOUNDARIES.getBoundaries()); + private static final DistributionAggregation DISTRIBUTION_AGGREGATION_DESCRIPTOR = + DistributionAggregation.create(BUCKET_BOUNDARIES.getBoundaries()); private final TestClock clock = TestClock.create(); @@ -87,9 +87,9 @@ private static DistributionView createDistributionView() { private static DistributionView createDistributionView( View.Name name, Measure measure, - DistributionAggregationDescriptor aggDescr, + DistributionAggregation distributionAggregation, List keys) { - return DistributionView.create(name, VIEW_DESCRIPTION, measure, aggDescr, keys); + return DistributionView.create(name, VIEW_DESCRIPTION, measure, distributionAggregation, keys); } @Test @@ -106,7 +106,7 @@ public void preventRegisteringIntervalView() { VIEW_NAME, VIEW_DESCRIPTION, MEASURE, - IntervalAggregationDescriptor.create(Arrays.asList(Duration.fromMillis(1000))), + IntervalAggregation.create(Arrays.asList(Duration.fromMillis(1000))), Arrays.asList(KEY)); thrown.expect(UnsupportedOperationException.class); viewManager.registerView(intervalView); @@ -281,7 +281,7 @@ public void testRecordWithEmptyStatsContext() { } @Test - public void testRecordWithNonExistentMeasurementDescriptor() { + public void testRecordWithNonExistentMeasurement() { viewManager.registerView( createDistributionView( VIEW_NAME, @@ -449,7 +449,7 @@ public void testMultipleViewsDifferentMeasures() { public void testGetDistributionViewDataWithoutBucketBoundaries() { View view = createDistributionView( - VIEW_NAME, MEASURE, DistributionAggregationDescriptor.create(), + VIEW_NAME, MEASURE, DistributionAggregation.create(), Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); viewManager.registerView(view); From 6684c2b2e84495dac225cb4b80d08a6e57e53e35 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 10 Jul 2017 13:59:40 -0700 Subject: [PATCH 0273/1581] Update releasing known issues. (#444) --- RELEASING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index b7f0de0205..80977a2947 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -170,8 +170,8 @@ site](http://central.sonatype.org/pages/releasing-the-deployment.html). ## Known Issues -### Deployment for branch v0.5.x -For all releases on the branch v0.5.x to deploy to maven central use command +### Deployment for tag v0.5.0 +To rebuild the releases on the tag v0.5.0 use: ```bash $ ./gradlew clean build && ./gradlew uploadArchives ``` From 0b7c39b3203d0531419536236ba3f22ad64ee984 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 10 Jul 2017 15:42:42 -0700 Subject: [PATCH 0274/1581] Make Tag.match and TagKey.match final in subclasses. --- core/src/main/java/io/opencensus/tags/Tag.java | 6 +++--- core/src/main/java/io/opencensus/tags/TagKey.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index 337af90ec4..c9dd9cfd69 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -120,7 +120,7 @@ public static TagString create(TagKeyString key, TagValueString value) { public abstract TagValueString getValue(); @Override - public T match( + public final T match( Function stringFunction, Function longFunction, Function booleanFunction, @@ -158,7 +158,7 @@ static TagLong create(TagKeyLong key, long value) { public abstract long getValue(); @Override - public T match( + public final T match( Function stringFunction, Function longFunction, Function booleanFunction, @@ -196,7 +196,7 @@ static TagBoolean create(TagKeyBoolean key, boolean value) { public abstract boolean getValue(); @Override - public T match( + public final T match( Function stringFunction, Function longFunction, Function booleanFunction, diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index 3ab6a4c7eb..9d90235939 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -125,7 +125,7 @@ public static TagKeyString create(String name) { } @Override - public T match( + public final T match( Function stringFunction, Function longFunction, Function booleanFunction, @@ -160,7 +160,7 @@ static TagKeyLong create(String name) { } @Override - public T match( + public final T match( Function stringFunction, Function longFunction, Function booleanFunction, @@ -195,7 +195,7 @@ static TagKeyBoolean create(String name) { } @Override - public T match( + public final T match( Function stringFunction, Function longFunction, Function booleanFunction, From 5dc723375964ec01b0c8e7ce16a4f2be9e6e03da Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 7 Jul 2017 13:53:21 -0700 Subject: [PATCH 0275/1581] Remove the View.getName() method that returns a String. Previously, View.getName() returned a String, and View.getViewName() returned a View.Name. This commit removes View.getName() and renames View.getViewName() to View.getName(), so that there is only one way to get a view name. --- core/src/main/java/io/opencensus/stats/View.java | 9 +-------- core/src/test/java/io/opencensus/stats/ViewTest.java | 6 ++---- .../main/java/io/opencensus/stats/MeasureToViewMap.java | 6 +++--- .../main/java/io/opencensus/stats/ViewManagerImpl.java | 2 +- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/io/opencensus/stats/View.java b/core/src/main/java/io/opencensus/stats/View.java index d50053c927..fdb20a9847 100644 --- a/core/src/main/java/io/opencensus/stats/View.java +++ b/core/src/main/java/io/opencensus/stats/View.java @@ -29,14 +29,7 @@ public abstract class View { /** * Name of view. Must be unique. */ - public abstract Name getViewName(); - - /** - * Name of view, as a {@code String}. - */ - public final String getName() { - return getViewName().asString(); - } + public abstract Name getName(); /** * More detailed description, for documentation purposes. diff --git a/core/src/test/java/io/opencensus/stats/ViewTest.java b/core/src/test/java/io/opencensus/stats/ViewTest.java index 7deab08f3b..2a4fe69650 100644 --- a/core/src/test/java/io/opencensus/stats/ViewTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewTest.java @@ -36,8 +36,7 @@ public void testDistributionView() { final View view = DistributionView.create( name, description, measure, dAggr, keys); - assertThat(view.getViewName()).isEqualTo(name); - assertThat(view.getName()).isEqualTo(name.asString()); + assertThat(view.getName()).isEqualTo(name); assertThat(view.getDescription()).isEqualTo(description); assertThat(view.getMeasure().getName()).isEqualTo(measure.getName()); assertThat(view.getDimensions()).hasSize(2); @@ -63,8 +62,7 @@ public void testIntervalView() { final View view = IntervalView.create( name, description, measure, iAggr, keys); - assertThat(view.getViewName()).isEqualTo(name); - assertThat(view.getName()).isEqualTo(name.asString()); + assertThat(view.getName()).isEqualTo(name); assertThat(view.getDescription()).isEqualTo(description); assertThat(view.getMeasure().getName()) .isEqualTo(measure.getName()); diff --git a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java index 0880514213..3a78faca9b 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java +++ b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java @@ -63,7 +63,7 @@ private synchronized MutableViewData getMutableViewData(View.Name viewName) { Collection views = mutableMap.get(view.getMeasure().getName()); for (MutableViewData viewData : views) { - if (viewData.getView().getViewName().equals(viewName)) { + if (viewData.getView().getName().equals(viewName)) { return viewData; } } @@ -73,7 +73,7 @@ private synchronized MutableViewData getMutableViewData(View.Name viewName) { /** Enable stats collection for the given {@link View}. */ synchronized void registerView(View view, Clock clock) { - View existing = registeredViews.get(view.getViewName()); + View existing = registeredViews.get(view.getName()); if (existing != null) { if (existing.equals(view)) { // Ignore views that are already registered. @@ -83,7 +83,7 @@ synchronized void registerView(View view, Clock clock) { "A different view with the same name is already registered: " + existing); } } - registeredViews.put(view.getViewName(), view); + registeredViews.put(view.getName(), view); MutableViewData mutableViewData = view.match( new CreateMutableDistributionViewDataFunction(clock), diff --git a/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java b/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java index ea56d7bd24..708f35ee5e 100644 --- a/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java +++ b/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java @@ -34,6 +34,6 @@ ViewData getView(View.Name viewName) { // TODO(sebright): Replace this method with the View.Name version. @Override public ViewData getView(View view) { - return statsManager.getView(view.getViewName()); + return statsManager.getView(view.getName()); } } From 78b70d1be85c9bcb997689860fd9b31496e96eb0 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 7 Jul 2017 14:02:55 -0700 Subject: [PATCH 0276/1581] Remove View factory methods that take Strings for view name. The remaining View factory methods take View.Name. --- .../io/opencensus/stats/RpcViewConstants.java | 80 +++++++++---------- .../main/java/io/opencensus/stats/View.java | 34 -------- .../io/opencensus/stats/ViewDataTest.java | 2 +- .../java/io/opencensus/stats/ViewTest.java | 24 +----- .../io/opencensus/stats/StatsContextTest.java | 8 +- 5 files changed, 49 insertions(+), 99 deletions(-) diff --git a/core/src/main/java/io/opencensus/stats/RpcViewConstants.java b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java index a861867654..c105ad3cf0 100644 --- a/core/src/main/java/io/opencensus/stats/RpcViewConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java @@ -65,63 +65,63 @@ public final class RpcViewConstants { // Rpc client {@link View}s. public static final DistributionView RPC_CLIENT_ERROR_COUNT_VIEW = DistributionView.create( - "grpc.io/client/error_count/distribution_cumulative", + View.Name.create("grpc.io/client/error_count/distribution_cumulative"), "RPC Errors", RPC_CLIENT_ERROR_COUNT, DistributionAggregation.create(), Arrays.asList(RPC_STATUS, RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW = DistributionView.create( - "grpc.io/client/roundtrip_latency/distribution_cumulative", + View.Name.create("grpc.io/client/roundtrip_latency/distribution_cumulative"), "Latency in msecs", RPC_CLIENT_ROUNDTRIP_LATENCY, DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_SERVER_ELAPSED_TIME_VIEW = DistributionView.create( - "grpc.io/client/server_elapsed_time/distribution_cumulative", + View.Name.create("grpc.io/client/server_elapsed_time/distribution_cumulative"), "Server elapsed time in msecs", RPC_CLIENT_SERVER_ELAPSED_TIME, DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_REQUEST_BYTES_VIEW = DistributionView.create( - "grpc.io/client/request_bytes/distribution_cumulative", + View.Name.create("grpc.io/client/request_bytes/distribution_cumulative"), "Request bytes", RPC_CLIENT_REQUEST_BYTES, DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_RESPONSE_BYTES_VIEW = DistributionView.create( - "grpc.io/client/response_bytes/distribution_cumulative", + View.Name.create("grpc.io/client/response_bytes/distribution_cumulative"), "Response bytes", RPC_CLIENT_RESPONSE_BYTES, DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_VIEW = DistributionView.create( - "grpc.io/client/uncompressed_request_bytes/distribution_cumulative", + View.Name.create("grpc.io/client/uncompressed_request_bytes/distribution_cumulative"), "Uncompressed Request bytes", RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_VIEW = DistributionView.create( - "grpc.io/client/uncompressed_response_bytes/distribution_cumulative", + View.Name.create("grpc.io/client/uncompressed_response_bytes/distribution_cumulative"), "Uncompressed Response bytes", RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_REQUEST_COUNT_VIEW = DistributionView.create( - "grpc.io/client/request_count/distribution_cumulative", + View.Name.create("grpc.io/client/request_count/distribution_cumulative"), "Count of request messages per client RPC", RPC_CLIENT_REQUEST_COUNT, DistributionAggregation.create(), Arrays.asList(RPC_CLIENT_METHOD)); public static final DistributionView RPC_CLIENT_RESPONSE_COUNT_VIEW = DistributionView.create( - "grpc.io/client/response_count/distribution_cumulative", + View.Name.create("grpc.io/client/response_count/distribution_cumulative"), "Count of response messages per client RPC", RPC_CLIENT_RESPONSE_COUNT, DistributionAggregation.create(), @@ -131,63 +131,63 @@ public final class RpcViewConstants { // Rpc server {@link View}s. public static final DistributionView RPC_SERVER_ERROR_COUNT_VIEW = DistributionView.create( - "grpc.io/server/error_count/distribution_cumulative", + View.Name.create("grpc.io/server/error_count/distribution_cumulative"), "RPC Errors", RPC_SERVER_ERROR_COUNT, DistributionAggregation.create(), Arrays.asList(RPC_STATUS, RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_SERVER_LATENCY_VIEW = DistributionView.create( - "grpc.io/server/server_latency/distribution_cumulative", + View.Name.create("grpc.io/server/server_latency/distribution_cumulative"), "Latency in msecs", RPC_SERVER_SERVER_LATENCY, DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_SERVER_ELAPSED_TIME_VIEW = DistributionView.create( - "grpc.io/server/elapsed_time/distribution_cumulative", + View.Name.create("grpc.io/server/elapsed_time/distribution_cumulative"), "Server elapsed time in msecs", RPC_SERVER_SERVER_ELAPSED_TIME, DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_REQUEST_BYTES_VIEW = DistributionView.create( - "grpc.io/server/request_bytes/distribution_cumulative", + View.Name.create("grpc.io/server/request_bytes/distribution_cumulative"), "Request bytes", RPC_SERVER_REQUEST_BYTES, DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_RESPONSE_BYTES_VIEW = DistributionView.create( - "grpc.io/server/response_bytes/distribution_cumulative", + View.Name.create("grpc.io/server/response_bytes/distribution_cumulative"), "Response bytes", RPC_SERVER_RESPONSE_BYTES, DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_VIEW = DistributionView.create( - "grpc.io/server/uncompressed_request_bytes/distribution_cumulative", + View.Name.create("grpc.io/server/uncompressed_request_bytes/distribution_cumulative"), "Uncompressed Request bytes", RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_VIEW = DistributionView.create( - "grpc.io/server/uncompressed_response_bytes/distribution_cumulative", + View.Name.create("grpc.io/server/uncompressed_response_bytes/distribution_cumulative"), "Uncompressed Response bytes", RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_REQUEST_COUNT_VIEW = DistributionView.create( - "grpc.io/server/request_count/distribution_cumulative", + View.Name.create("grpc.io/server/request_count/distribution_cumulative"), "Count of request messages per server RPC", RPC_SERVER_REQUEST_COUNT, DistributionAggregation.create(), Arrays.asList(RPC_SERVER_METHOD)); public static final DistributionView RPC_SERVER_RESPONSE_COUNT_VIEW = DistributionView.create( - "grpc.io/server/response_count/distribution_cumulative", + View.Name.create("grpc.io/server/response_count/distribution_cumulative"), "Count of response messages per server RPC", RPC_SERVER_RESPONSE_COUNT, DistributionAggregation.create(), @@ -200,7 +200,7 @@ public final class RpcViewConstants { // RPC client {@link IntervalView}s. public static final IntervalView RPC_CLIENT_ROUNDTRIP_LATENCY_INTERVAL_VIEW = IntervalView.create( - "grpc.io/client/roundtrip_latency/interval", + View.Name.create("grpc.io/client/roundtrip_latency/interval"), "Minute and Hour stats for latency in msecs", RPC_CLIENT_ROUNDTRIP_LATENCY, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -208,7 +208,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_CLIENT_REQUEST_BYTES_INTERVAL_VIEW = IntervalView.create( - "grpc.io/client/request_bytes/interval", + View.Name.create("grpc.io/client/request_bytes/interval"), "Minute and Hour stats for request size in bytes", RPC_CLIENT_REQUEST_BYTES, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -216,7 +216,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_CLIENT_RESPONSE_BYTES_INTERVAL_VIEW = IntervalView.create( - "grpc.io/client/response_bytes/interval", + View.Name.create("grpc.io/client/response_bytes/interval"), "Minute and Hour stats for response size in bytes", RPC_CLIENT_RESPONSE_BYTES, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -224,7 +224,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_CLIENT_ERROR_COUNT_INTERVAL_VIEW = IntervalView.create( - "grpc.io/client/error_count/interval", + View.Name.create("grpc.io/client/error_count/interval"), "Minute and Hour stats for rpc errors", RPC_CLIENT_ERROR_COUNT, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -232,7 +232,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = IntervalView.create( - "grpc.io/client/uncompressed_request_bytes/interval", + View.Name.create("grpc.io/client/uncompressed_request_bytes/interval"), "Minute and Hour stats for uncompressed request size in bytes", RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -240,7 +240,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = IntervalView.create( - "grpc.io/client/uncompressed_response_bytes/interval", + View.Name.create("grpc.io/client/uncompressed_response_bytes/interval"), "Minute and Hour stats for uncompressed response size in bytes", RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -248,7 +248,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_CLIENT_SERVER_ELAPSED_TIME_INTERVAL_VIEW = IntervalView.create( - "grpc.io/client/server_elapsed_time/interval", + View.Name.create("grpc.io/client/server_elapsed_time/interval"), "Minute and Hour stats for server elapsed time in msecs", RPC_CLIENT_SERVER_ELAPSED_TIME, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -256,7 +256,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_CLIENT_STARTED_COUNT_INTERVAL_VIEW = IntervalView.create( - "grpc.io/client/started_count/interval", + View.Name.create("grpc.io/client/started_count/interval"), "Minute and Hour stats on the number of client RPCs started", RPC_CLIENT_STARTED_COUNT, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -264,7 +264,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_CLIENT_FINISHED_COUNT_INTERVAL_VIEW = IntervalView.create( - "grpc.io/client/finished_count/interval", + View.Name.create("grpc.io/client/finished_count/interval"), "Minute and Hour stats on the number of client RPCs finished", RPC_CLIENT_FINISHED_COUNT, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -272,7 +272,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_CLIENT_REQUEST_COUNT_INTERVAL_VIEW = IntervalView.create( - "grpc.io/client/request_count/interval", + View.Name.create("grpc.io/client/request_count/interval"), "Minute and Hour stats on the count of request messages per client RPC", RPC_CLIENT_REQUEST_COUNT, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -280,7 +280,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_CLIENT_RESPONSE_COUNT_INTERVAL_VIEW = IntervalView.create( - "grpc.io/client/response_count/interval", + View.Name.create("grpc.io/client/response_count/interval"), "Minute and Hour stats on the count of response messages per client RPC", RPC_CLIENT_RESPONSE_COUNT, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -289,7 +289,7 @@ public final class RpcViewConstants { // RPC server {@link IntervalView}s. public static final IntervalView RPC_SERVER_SERVER_LATENCY_INTERVAL_VIEW = IntervalView.create( - "grpc.io/server/server_latency/interval", + View.Name.create("grpc.io/server/server_latency/interval"), "Minute and Hour stats for server latency in msecs", RPC_SERVER_SERVER_LATENCY, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -297,7 +297,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_SERVER_REQUEST_BYTES_INTERVAL_VIEW = IntervalView.create( - "grpc.io/server/request_bytes/interval", + View.Name.create("grpc.io/server/request_bytes/interval"), "Minute and Hour stats for request size in bytes", RPC_SERVER_REQUEST_BYTES, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -305,7 +305,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_SERVER_RESPONSE_BYTES_INTERVAL_VIEW = IntervalView.create( - "grpc.io/server/response_bytes/interval", + View.Name.create("grpc.io/server/response_bytes/interval"), "Minute and Hour stats for response size in bytes", RPC_SERVER_RESPONSE_BYTES, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -313,7 +313,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_SERVER_ERROR_COUNT_INTERVAL_VIEW = IntervalView.create( - "grpc.io/server/error_count/interval", + View.Name.create("grpc.io/server/error_count/interval"), "Minute and Hour stats for rpc errors", RPC_SERVER_ERROR_COUNT, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -321,7 +321,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = IntervalView.create( - "grpc.io/server/uncompressed_request_bytes/interval", + View.Name.create("grpc.io/server/uncompressed_request_bytes/interval"), "Minute and Hour stats for uncompressed request size in bytes", RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -329,7 +329,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = IntervalView.create( - "grpc.io/server/uncompressed_response_bytes/interval", + View.Name.create("grpc.io/server/uncompressed_response_bytes/interval"), "Minute and Hour stats for uncompressed response size in bytes", RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -337,7 +337,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_SERVER_SERVER_ELAPSED_TIME_INTERVAL_VIEW = IntervalView.create( - "grpc.io/server/server_elapsed_time/interval", + View.Name.create("grpc.io/server/server_elapsed_time/interval"), "Minute and Hour stats for server elapsed time in msecs", RPC_SERVER_SERVER_ELAPSED_TIME, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -345,7 +345,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_SERVER_STARTED_COUNT_INTERVAL_VIEW = IntervalView.create( - "grpc.io/server/started_count/interval", + View.Name.create("grpc.io/server/started_count/interval"), "Minute and Hour stats on the number of server RPCs started", RPC_SERVER_STARTED_COUNT, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -353,7 +353,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_SERVER_FINISHED_COUNT_INTERVAL_VIEW = IntervalView.create( - "grpc.io/server/finished_count/interval", + View.Name.create("grpc.io/server/finished_count/interval"), "Minute and Hour stats on the number of server RPCs finished", RPC_SERVER_FINISHED_COUNT, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -361,7 +361,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_SERVER_REQUEST_COUNT_INTERVAL_VIEW = IntervalView.create( - "grpc.io/server/request_count/interval", + View.Name.create("grpc.io/server/request_count/interval"), "Minute and Hour stats on the count of request messages per server RPC", RPC_SERVER_REQUEST_COUNT, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), @@ -369,7 +369,7 @@ public final class RpcViewConstants { public static final IntervalView RPC_SERVER_RESPONSE_COUNT_INTERVAL_VIEW = IntervalView.create( - "grpc.io/server/response_count/interval", + View.Name.create("grpc.io/server/response_count/interval"), "Minute and Hour stats on the count of response messages per server RPC", RPC_SERVER_RESPONSE_COUNT, IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), diff --git a/core/src/main/java/io/opencensus/stats/View.java b/core/src/main/java/io/opencensus/stats/View.java index fdb20a9847..72ffc389a6 100644 --- a/core/src/main/java/io/opencensus/stats/View.java +++ b/core/src/main/java/io/opencensus/stats/View.java @@ -91,23 +91,6 @@ public static Name create(String name) { @Immutable @AutoValue public abstract static class DistributionView extends View { - /** - * Constructs a new {@link DistributionView}. - */ - public static DistributionView create( - String name, - String description, - Measure measure, - DistributionAggregation distributionAggregation, - List tagKeys) { - return create( - Name.create(name), - description, - measure, - distributionAggregation, - tagKeys); - } - /** * Constructs a new {@link DistributionView}. */ @@ -145,23 +128,6 @@ public T match( @Immutable @AutoValue public abstract static class IntervalView extends View { - /** - * Constructs a new {@link IntervalView}. - */ - public static IntervalView create( - String name, - String description, - Measure measure, - IntervalAggregation intervalAggregation, - List tagKeys) { - return create( - Name.create(name), - description, - measure, - intervalAggregation, - tagKeys); - } - /** * Constructs a new {@link IntervalView}. */ diff --git a/core/src/test/java/io/opencensus/stats/ViewDataTest.java b/core/src/test/java/io/opencensus/stats/ViewDataTest.java index 877643495b..d4213ff1c9 100644 --- a/core/src/test/java/io/opencensus/stats/ViewDataTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewDataTest.java @@ -167,7 +167,7 @@ public void testViewDataEquals() { List tags2 = Arrays.asList(Tag.create(K1, V10), Tag.create(K2, V20)); // name - private final String name = "test-view"; + private final View.Name name = View.Name.create("test-view"); // description private final String description = "test-view-descriptor description"; // measurement descriptor diff --git a/core/src/test/java/io/opencensus/stats/ViewTest.java b/core/src/test/java/io/opencensus/stats/ViewTest.java index 2a4fe69650..afd92ac045 100644 --- a/core/src/test/java/io/opencensus/stats/ViewTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewTest.java @@ -110,17 +110,7 @@ public void testViewEquals() { @Test(expected = NullPointerException.class) public void preventNullDistributionViewName() { DistributionView.create( - (View.Name) null, - description, - measure, - DistributionAggregation.create(), - keys); - } - - @Test(expected = NullPointerException.class) - public void preventNullDistributionViewStringName() { - DistributionView.create( - (String) null, + null, description, measure, DistributionAggregation.create(), @@ -130,17 +120,7 @@ public void preventNullDistributionViewStringName() { @Test(expected = NullPointerException.class) public void preventNullIntervalViewName() { IntervalView.create( - (View.Name) null, - description, - measure, - IntervalAggregation.create(Arrays.asList(Duration.fromMillis(1))), - keys); - } - - @Test(expected = NullPointerException.class) - public void preventNullIntervalViewStringName() { - IntervalView.create( - (String) null, + null, description, measure, IntervalAggregation.create(Arrays.asList(Duration.fromMillis(1))), diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index 7297b563aa..a81b826eb4 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -174,8 +174,12 @@ public Void apply(IntervalViewData view) { @Test public void testRecordLong() { MeasureLong measure = MeasureLong.create("long measure", "description", "1"); - viewManager.registerView(View.DistributionView - .create("name", "description", measure, DistributionAggregation.create(), + viewManager.registerView( + View.DistributionView.create( + View.Name.create("name"), + "description", + measure, + DistributionAggregation.create(), Arrays.asList(K1))); thrown.expect(UnsupportedOperationException.class); defaultStatsContext.with(K1, V1).record(MeasureMap.builder().set(measure,1L).build()); From c44e6b11b9a3801797acaa533f213b3c2d894277 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Mon, 10 Jul 2017 16:24:29 -0700 Subject: [PATCH 0277/1581] Change *_COUNT RPC constants to MeasureLong, add TODO to support long value. (#443) --- .../java/io/opencensus/stats/Measure.java | 1 - .../opencensus/stats/RpcMeasureConstants.java | 42 +++++++++---------- .../io/opencensus/stats/MeasureToViewMap.java | 15 +++++-- .../io/opencensus/stats/MutableViewData.java | 18 +++++++- 4 files changed, 50 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/io/opencensus/stats/Measure.java b/core/src/main/java/io/opencensus/stats/Measure.java index d4b8abc9d1..adec7879ee 100644 --- a/core/src/main/java/io/opencensus/stats/Measure.java +++ b/core/src/main/java/io/opencensus/stats/Measure.java @@ -90,7 +90,6 @@ public T match(Function p0, Function views = mutableMap.get(measurement.getMeasure().getName()); for (MutableViewData view : views) { - measurement.match(new RecordDoubleValueFunc(tags, view), new RecordLongValueFunc()); + measurement.match( + new RecordDoubleValueFunc(tags, view), new RecordLongValueFunc(tags, view)); } } } @@ -146,8 +147,16 @@ private RecordDoubleValueFunc(StatsContextImpl tags, MutableViewData view) { private static final class RecordLongValueFunc implements Function { @Override public Void apply(MeasurementLong arg) { - // TODO: determine if we want to support LongMeasure in v0.1 - throw new UnsupportedOperationException("Long measurements not supported."); + view.record(tags, arg.getValue()); + return null; + } + + private final StatsContextImpl tags; + private final MutableViewData view; + + private RecordLongValueFunc(StatsContextImpl tags, MutableViewData view) { + this.tags = tags; + this.view = view; } } } diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java index d8458a2254..15ff1d032c 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java +++ b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java @@ -40,10 +40,15 @@ abstract class MutableViewData { abstract View getView(); /** - * Record stats with the given tags. + * Record double stats with the given tags. */ abstract void record(StatsContextImpl tags, double value); + /** + * Record long stats with the given tags. + */ + abstract void record(StatsContextImpl tags, long value); + /** * Convert this {@link MutableViewData} to {@link ViewData}. */ @@ -101,6 +106,12 @@ void record(StatsContextImpl context, double value) { tagValueDistributionMap.get(tagValues).add(value); } + @Override + void record(StatsContextImpl tags, long value) { + // TODO(songya): modify MutableDistribution to support long values. + throw new UnsupportedOperationException("Not implemented."); + } + @Override final ViewData toViewData(Clock clock) { final List distributionAggregations = @@ -177,6 +188,11 @@ void record(StatsContextImpl tags, double value) { throw new UnsupportedOperationException("Not implemented."); } + @Override + void record(StatsContextImpl tags, long value) { + throw new UnsupportedOperationException("Not implemented."); + } + @Override final ViewData toViewData(Clock clock) { throw new UnsupportedOperationException("Not implemented."); From f8ed87aa289da7baa4760f825b1de169ba3e197a Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 10 Jul 2017 20:41:46 -0700 Subject: [PATCH 0278/1581] Move stats Context key to io.opencensus.tags.unsafe package. This commit starts refactoring the stats io.grpc.Context key so that it can be used to access a TagContext. It also organizes the classes that interact with the Context to be more similar to the tracing package. The commit renames the constant from STATS_CONTEXT_KEY to TAG_CONTEXT_KEY and moves it from io.opencensus.stats.ContextUtils to io.opencensus.tags.unsafe.ContextUtils. It also renames the io.opencensus.stats.ContextUtils class to CurrentTagsUtils and makes it package-private, since the only public member was the Context key. The Context key still has type Context.Key, for now. --- ...ontextUtils.java => CurrentTagsUtils.java} | 20 +++------- .../opencensus/stats/StatsContextFactory.java | 4 +- .../opencensus/tags/unsafe/ContextUtils.java | 37 +++++++++++++++++++ ...ilsTest.java => CurrentTagsUtilsTest.java} | 22 +++++------ .../stats/StatsContextFactoryTest.java | 7 ++-- 5 files changed, 60 insertions(+), 30 deletions(-) rename core/src/main/java/io/opencensus/stats/{ContextUtils.java => CurrentTagsUtils.java} (77%) create mode 100644 core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java rename core/src/test/java/io/opencensus/stats/{ContextUtilsTest.java => CurrentTagsUtilsTest.java} (67%) diff --git a/core/src/main/java/io/opencensus/stats/ContextUtils.java b/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java similarity index 77% rename from core/src/main/java/io/opencensus/stats/ContextUtils.java rename to core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java index 6705945e50..5af499479a 100644 --- a/core/src/main/java/io/opencensus/stats/ContextUtils.java +++ b/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java @@ -14,25 +14,17 @@ package io.opencensus.stats; import io.grpc.Context; + import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.tags.unsafe.ContextUtils; /** * Util methods/functionality to interact with the {@link io.grpc.Context}. - * - *

            Users must interact with the current Context via the public APIs in {@link - * StatsContextFactory} and avoid usages of the {@link #STATS_CONTEXT_KEY} directly. */ -public final class ContextUtils { - - /** - * The {@link io.grpc.Context.Key} used to interact with {@link io.grpc.Context}. - */ - // TODO(songya): Discourage the usage of STATS_CONTEXT_KEY for normal users if needed. - public static final Context.Key STATS_CONTEXT_KEY = Context.key( - "instrumentation-stats-key"); +final class CurrentTagsUtils { // Static class. - private ContextUtils() { + private CurrentTagsUtils() { } /** @@ -41,7 +33,7 @@ private ContextUtils() { * @return The {@code StatsContext} from the current context. */ static StatsContext getCurrentStatsContext() { - return STATS_CONTEXT_KEY.get(Context.current()); + return ContextUtils.TAG_CONTEXT_KEY.get(Context.current()); } /** @@ -56,7 +48,7 @@ static StatsContext getCurrentStatsContext() { * current context. */ static NonThrowingCloseable withStatsContext(StatsContext statsContext) { - return new WithStatsContext(statsContext, STATS_CONTEXT_KEY); + return new WithStatsContext(statsContext, ContextUtils.TAG_CONTEXT_KEY); } // Supports try-with-resources idiom. diff --git a/core/src/main/java/io/opencensus/stats/StatsContextFactory.java b/core/src/main/java/io/opencensus/stats/StatsContextFactory.java index 75b5026d96..cee9f253d0 100644 --- a/core/src/main/java/io/opencensus/stats/StatsContextFactory.java +++ b/core/src/main/java/io/opencensus/stats/StatsContextFactory.java @@ -48,7 +48,7 @@ public abstract class StatsContextFactory { * {@code io.grpc.Context}. */ public final StatsContext getCurrentStatsContext() { - StatsContext statsContext = ContextUtils.getCurrentStatsContext(); + StatsContext statsContext = CurrentTagsUtils.getCurrentStatsContext(); return statsContext != null ? statsContext : getDefault(); } @@ -99,6 +99,6 @@ public final StatsContext getCurrentStatsContext() { * @throws NullPointerException if statsContext is null. */ public final NonThrowingCloseable withStatsContext(StatsContext statsContext) { - return ContextUtils.withStatsContext(checkNotNull(statsContext, "statsContext")); + return CurrentTagsUtils.withStatsContext(checkNotNull(statsContext, "statsContext")); } } diff --git a/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java b/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java new file mode 100644 index 0000000000..2c97a4ade5 --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java @@ -0,0 +1,37 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags.unsafe; + +import io.grpc.Context; +import io.opencensus.stats.StatsContext; +import io.opencensus.tags.TagContext; + +/** + * Utility methods for accessing the {@link TagContext} contained in the {@link io.grpc.Context}. + * + *

            Most code should interact with the current context via the public APIs in {@link + * io.opencensus.stats.StatsContextFactory} and avoid accessing {@link #TAG_CONTEXT_KEY} directly. + */ +// TODO(sebright): Update this Javadoc to reference the class in the tags package that provides +// methods for interacting with the current context, once TAG_CONTEXT_KEY uses TagContext. +public final class ContextUtils { + private ContextUtils() {} + + /** + * The {@link io.grpc.Context.Key} used to interact with the {@code TagContext} contained in the + * {@link io.grpc.Context}. + */ + public static final Context.Key TAG_CONTEXT_KEY = + Context.key("opencensus-tag-context-key"); +} diff --git a/core/src/test/java/io/opencensus/stats/ContextUtilsTest.java b/core/src/test/java/io/opencensus/stats/CurrentTagsUtilsTest.java similarity index 67% rename from core/src/test/java/io/opencensus/stats/ContextUtilsTest.java rename to core/src/test/java/io/opencensus/stats/CurrentTagsUtilsTest.java index 48e1504d62..46e5675b8c 100644 --- a/core/src/test/java/io/opencensus/stats/ContextUtilsTest.java +++ b/core/src/test/java/io/opencensus/stats/CurrentTagsUtilsTest.java @@ -25,10 +25,10 @@ import org.mockito.MockitoAnnotations; /** - * Unit tests for {@link ContextUtils}. + * Unit tests for {@link CurrentTagsUtils}. */ @RunWith(JUnit4.class) -public class ContextUtilsTest { +public class CurrentTagsUtilsTest { @Mock private StatsContext statsContext; @@ -40,38 +40,38 @@ public void setUp() { @Test public void testGetCurrentStatsContext_WhenNoContext() { - assertThat(ContextUtils.getCurrentStatsContext()).isNull(); + assertThat(CurrentTagsUtils.getCurrentStatsContext()).isNull(); } @Test public void testWithStatsContext() { - assertThat(ContextUtils.getCurrentStatsContext()).isNull(); - NonThrowingCloseable scopedStatsCtx = ContextUtils.withStatsContext(statsContext); + assertThat(CurrentTagsUtils.getCurrentStatsContext()).isNull(); + NonThrowingCloseable scopedStatsCtx = CurrentTagsUtils.withStatsContext(statsContext); try { - assertThat(ContextUtils.getCurrentStatsContext()).isSameAs(statsContext); + assertThat(CurrentTagsUtils.getCurrentStatsContext()).isSameAs(statsContext); } finally { scopedStatsCtx.close(); } - assertThat(ContextUtils.getCurrentStatsContext()).isNull(); + assertThat(CurrentTagsUtils.getCurrentStatsContext()).isNull(); } @Test public void testWithStatsContextUsingWrap() { Runnable runnable; - NonThrowingCloseable scopedStatsCtx = ContextUtils.withStatsContext(statsContext); + NonThrowingCloseable scopedStatsCtx = CurrentTagsUtils.withStatsContext(statsContext); try { - assertThat(ContextUtils.getCurrentStatsContext()).isSameAs(statsContext); + assertThat(CurrentTagsUtils.getCurrentStatsContext()).isSameAs(statsContext); runnable = Context.current().wrap( new Runnable() { @Override public void run() { - assertThat(ContextUtils.getCurrentStatsContext()).isSameAs(statsContext); + assertThat(CurrentTagsUtils.getCurrentStatsContext()).isSameAs(statsContext); } }); } finally { scopedStatsCtx.close(); } - assertThat(ContextUtils.getCurrentStatsContext()).isNull(); + assertThat(CurrentTagsUtils.getCurrentStatsContext()).isNull(); // When we run the runnable we will have the statsContext in the current Context. runnable.run(); } diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java index 8a4e43f5b8..8185f68a5d 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java @@ -15,11 +15,12 @@ import static com.google.common.truth.Truth.assertThat; +import io.grpc.Context; import io.opencensus.common.NonThrowingCloseable; import io.opencensus.internal.SimpleEventQueue; -import io.opencensus.testing.common.TestClock; import io.opencensus.internal.VarInt; -import io.grpc.Context; +import io.opencensus.tags.unsafe.ContextUtils; +import io.opencensus.testing.common.TestClock; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -146,7 +147,7 @@ public void testGetDefaultForCurrentStatsContextWhenNotSet() { public void testGetCurrentStatsContext() { assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); Context origContext = Context.current().withValue( - ContextUtils.STATS_CONTEXT_KEY, statsContext) + ContextUtils.TAG_CONTEXT_KEY, statsContext) .attach(); // Make sure context is detached even if test fails. try { From 5593a73cad0cc5954e68541dfb18e668d65f4fba Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 06:24:36 -0700 Subject: [PATCH 0279/1581] Add a TODO. --- core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java b/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java index 5af499479a..e22f372bec 100644 --- a/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java +++ b/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java @@ -21,6 +21,7 @@ /** * Util methods/functionality to interact with the {@link io.grpc.Context}. */ +// TODO(sebright): Move this into the tags package. final class CurrentTagsUtils { // Static class. From 4a90bd0a421b1b4f4a509bec586ab9dba1c95020 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 10 Jul 2017 17:26:13 -0700 Subject: [PATCH 0280/1581] Add Scope as interface for NonThrowingCloseables that work with current context. This interface allows users to write a shorter, more descriptive type name when using scoped tags or spans. --- .../main/java/io/opencensus/common/Scope.java | 20 +++++++++++++++++++ .../io/opencensus/trace/CurrentSpanUtils.java | 6 +++--- .../io/opencensus/trace/ScopedSpanHandle.java | 6 +++--- .../java/io/opencensus/trace/SpanBuilder.java | 12 +++++------ .../main/java/io/opencensus/trace/Tracer.java | 10 +++++----- .../trace/propagation/BinaryFormat.java | 4 ++-- .../trace/CurrentSpanUtilsTest.java | 6 +++--- .../trace/ScopedSpanHandleTest.java | 4 ++-- .../java/io/opencensus/trace/TracerTest.java | 10 +++++----- .../io/opencensus/stats/CurrentTagsUtils.java | 7 +++---- .../opencensus/stats/StatsContextFactory.java | 8 ++++---- .../stats/CurrentTagsUtilsTest.java | 6 +++--- .../stats/StatsContextFactoryTest.java | 6 +++--- .../examples/stats/StatsRunner.java | 6 +++--- .../trace/MultiSpansContextTracing.java | 6 +++--- .../trace/MultiSpansScopedTracing.java | 7 +++---- 16 files changed, 71 insertions(+), 53 deletions(-) create mode 100644 api/src/main/java/io/opencensus/common/Scope.java diff --git a/api/src/main/java/io/opencensus/common/Scope.java b/api/src/main/java/io/opencensus/common/Scope.java new file mode 100644 index 0000000000..929fbd237d --- /dev/null +++ b/api/src/main/java/io/opencensus/common/Scope.java @@ -0,0 +1,20 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.common; + +/** + * A {@link NonThrowingCloseable} that represents a change to the current context over a scope of + * code. + */ +public interface Scope extends NonThrowingCloseable {} diff --git a/api/src/main/java/io/opencensus/trace/CurrentSpanUtils.java b/api/src/main/java/io/opencensus/trace/CurrentSpanUtils.java index 884fd636ad..57909f372b 100644 --- a/api/src/main/java/io/opencensus/trace/CurrentSpanUtils.java +++ b/api/src/main/java/io/opencensus/trace/CurrentSpanUtils.java @@ -14,7 +14,7 @@ package io.opencensus.trace; import io.grpc.Context; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import io.opencensus.trace.unsafe.ContextUtils; /** @@ -43,12 +43,12 @@ static Span getCurrentSpan() { * @return An object that defines a scope where the given {@code Span} is set to the current * context. */ - static NonThrowingCloseable withSpan(Span span) { + static Scope withSpan(Span span) { return new WithSpan(span, ContextUtils.CONTEXT_SPAN_KEY); } // Defines an arbitrary scope of code as a traceable operation. Supports try-with-resources idiom. - private static final class WithSpan implements NonThrowingCloseable { + private static final class WithSpan implements Scope { private final Context origContext; /** diff --git a/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java b/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java index e2cf1710e9..81493a2ec7 100644 --- a/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java +++ b/api/src/main/java/io/opencensus/trace/ScopedSpanHandle.java @@ -13,7 +13,7 @@ package io.opencensus.trace; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; /** * Defines a scope of code where the given {@link Span} is in the current context. The scope is @@ -22,9 +22,9 @@ * *

            Supports try-with-resource idiom. */ -final class ScopedSpanHandle implements NonThrowingCloseable { +final class ScopedSpanHandle implements Scope { private final Span span; - private final NonThrowingCloseable withSpan; + private final Scope withSpan; /** * Creates a {@code ScopedSpanHandle} diff --git a/api/src/main/java/io/opencensus/trace/SpanBuilder.java b/api/src/main/java/io/opencensus/trace/SpanBuilder.java index e61318ea3e..1d427b9c63 100644 --- a/api/src/main/java/io/opencensus/trace/SpanBuilder.java +++ b/api/src/main/java/io/opencensus/trace/SpanBuilder.java @@ -15,7 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import java.util.List; import javax.annotation.Nullable; @@ -31,7 +31,7 @@ * private static final Tracer tracer = Tracing.getTracer(); * void doWork { * // Create a Span as a child of the current Span. - * try (NonThrowingCloseable ss = tracer.spanBuilder("MyChildSpan").startScopedSpan()) { + * try (Scope ss = tracer.spanBuilder("MyChildSpan").startScopedSpan()) { * tracer.getCurrentSpan().addAnnotation("my annotation"); * doSomeWork(); // Here the new span is in the current Context, so it can be used * // implicitly anywhere down the stack. @@ -57,7 +57,7 @@ * } * * public void onExecuteHandler(ServerCallHandler serverCallHandler) { - * try (NonThrowingCloseable ws = tracer.withSpan(mySpan)) { + * try (Scope ws = tracer.withSpan(mySpan)) { * tracer.getCurrentSpan().addAnnotation("Start rpc execution."); * serverCallHandler.run(); // Here the new span is in the current Context, so it can be * // used implicitly anywhere down the stack. @@ -178,7 +178,7 @@ public abstract class SpanBuilder { * private static final Tracer tracer = Tracing.getTracer(); * void doWork { * // Create a Span as a child of the current Span. - * try (NonThrowingCloseable ss = tracer.spanBuilder("MyChildSpan").startScopedSpan()) { + * try (Scope ss = tracer.spanBuilder("MyChildSpan").startScopedSpan()) { * tracer.getCurrentSpan().addAnnotation("my annotation"); * doSomeWork(); // Here the new span is in the current Context, so it can be used * // implicitly anywhere down the stack. Anytime in this closure the span @@ -199,7 +199,7 @@ public abstract class SpanBuilder { * private static Tracer tracer = Tracing.getTracer(); * void doWork { * // Create a Span as a child of the current Span. - * NonThrowingCloseable ss = tracer.spanBuilder("MyChildSpan").startScopedSpan(); + * Scope ss = tracer.spanBuilder("MyChildSpan").startScopedSpan(); * try { * tracer.getCurrentSpan().addAnnotation("my annotation"); * doSomeWork(); // Here the new span is in the current Context, so it can be used @@ -215,7 +215,7 @@ public abstract class SpanBuilder { * @return an object that defines a scope where the newly created {@code Span} will be set to the * current Context. */ - public final NonThrowingCloseable startScopedSpan() { + public final Scope startScopedSpan() { return new ScopedSpanHandle(startSpan()); } diff --git a/api/src/main/java/io/opencensus/trace/Tracer.java b/api/src/main/java/io/opencensus/trace/Tracer.java index b9f7b67b53..55a48aa0f6 100644 --- a/api/src/main/java/io/opencensus/trace/Tracer.java +++ b/api/src/main/java/io/opencensus/trace/Tracer.java @@ -15,7 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import io.opencensus.trace.SpanBuilder.NoopSpanBuilder; import javax.annotation.Nullable; @@ -36,7 +36,7 @@ * class MyClass { * private static final Tracer tracer = Tracing.getTracer(); * void doWork() { - * try(NonThrowingCloseable ss = tracer.spanBuilder("MyClass.DoWork").startScopedSpan) { + * try(Scope ss = tracer.spanBuilder("MyClass.DoWork").startScopedSpan) { * tracer.getCurrentSpan().addAnnotation("Starting the work."); * doWorkInternal(); * tracer.getCurrentSpan().addAnnotation("Finished working."); @@ -107,7 +107,7 @@ public final Span getCurrentSpan() { * void doWork() { * // Create a Span as a child of the current Span. * Span span = tracer.spanBuilder("my span").startSpan(); - * try (NonThrowingCloseable ws = tracer.withSpan(span)) { + * try (Scope ws = tracer.withSpan(span)) { * tracer.getCurrentSpan().addAnnotation("my annotation"); * doSomeOtherWork(); // Here "span" is the current Span. * } @@ -125,7 +125,7 @@ public final Span getCurrentSpan() { * void doWork() { * // Create a Span as a child of the current Span. * Span span = tracer.spanBuilder("my span").startSpan(); - * NonThrowingCloseable ws = tracer.withSpan(span); + * Scope ws = tracer.withSpan(span); * try { * tracer.getCurrentSpan().addAnnotation("my annotation"); * doSomeOtherWork(); // Here "span" is the current Span. @@ -141,7 +141,7 @@ public final Span getCurrentSpan() { * Context. * @throws NullPointerException if {@code span} is {@code null}. */ - public final NonThrowingCloseable withSpan(Span span) { + public final Scope withSpan(Span span) { return CurrentSpanUtils.withSpan(checkNotNull(span, "span")); } diff --git a/api/src/main/java/io/opencensus/trace/propagation/BinaryFormat.java b/api/src/main/java/io/opencensus/trace/propagation/BinaryFormat.java index 284576ec85..ab3ad5f218 100644 --- a/api/src/main/java/io/opencensus/trace/propagation/BinaryFormat.java +++ b/api/src/main/java/io/opencensus/trace/propagation/BinaryFormat.java @@ -28,7 +28,7 @@ * private static final BinaryFormat binaryFormat = * Tracing.getPropagationComponent().getBinaryFormat(); * void onSendRequest() { - * try (NonThrowingCloseable ss = tracer.spanBuilder("Sent.MyRequest").startScopedSpan()) { + * try (Scope ss = tracer.spanBuilder("Sent.MyRequest").startScopedSpan()) { * byte[] binaryValue = binaryFormat.toBinaryValue(tracer.getCurrentContext().context()); * // Send the request including the binaryValue and wait for the response. * } @@ -51,7 +51,7 @@ * } catch (ParseException e) { * // Maybe log the exception. * } - * try (NonThrowingCloseable ss = + * try (Scope ss = * tracer.spanBuilderWithRemoteParent("Recv.MyRequest", spanContext).startScopedSpan()) { * // Handle request and send response back. * } diff --git a/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java b/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java index 9d82bd2c3c..9b8f63281d 100644 --- a/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java +++ b/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java @@ -16,7 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.grpc.Context; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import io.opencensus.trace.unsafe.ContextUtils; import org.junit.Before; import org.junit.Test; @@ -56,7 +56,7 @@ public void getCurrentSpan() { @Test public void withSpan() { assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); - NonThrowingCloseable ws = CurrentSpanUtils.withSpan(span); + Scope ws = CurrentSpanUtils.withSpan(span); try { assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); } finally { @@ -68,7 +68,7 @@ public void withSpan() { @Test public void propagationViaRunnable() { Runnable runnable = null; - NonThrowingCloseable ws = CurrentSpanUtils.withSpan(span); + Scope ws = CurrentSpanUtils.withSpan(span); try { assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); runnable = diff --git a/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java b/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java index 8922f4c2d2..7299911505 100644 --- a/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java +++ b/api/src/test/java/io/opencensus/trace/ScopedSpanHandleTest.java @@ -17,7 +17,7 @@ import static org.mockito.Matchers.same; import static org.mockito.Mockito.verify; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -39,7 +39,7 @@ public void setUp() { @Test public void initAttachesSpan_CloseDetachesAndEndsSpan() { assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); - NonThrowingCloseable ss = new ScopedSpanHandle(span); + Scope ss = new ScopedSpanHandle(span); try { assertThat(tracer.getCurrentSpan()).isSameAs(span); } finally { diff --git a/api/src/test/java/io/opencensus/trace/TracerTest.java b/api/src/test/java/io/opencensus/trace/TracerTest.java index a0830428ee..96116bc2ec 100644 --- a/api/src/test/java/io/opencensus/trace/TracerTest.java +++ b/api/src/test/java/io/opencensus/trace/TracerTest.java @@ -18,7 +18,7 @@ import static org.mockito.Mockito.when; import io.grpc.Context; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -56,7 +56,7 @@ public void withSpan_NullSpan() { @Test public void getCurrentSpan_WithSpan() { assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); - NonThrowingCloseable ws = noopTracer.withSpan(span); + Scope ws = noopTracer.withSpan(span); try { assertThat(noopTracer.getCurrentSpan()).isSameAs(span); } finally { @@ -68,7 +68,7 @@ public void getCurrentSpan_WithSpan() { @Test public void propagationViaRunnable() { Runnable runnable; - NonThrowingCloseable ws = noopTracer.withSpan(span); + Scope ws = noopTracer.withSpan(span); try { assertThat(noopTracer.getCurrentSpan()).isSameAs(span); runnable = @@ -129,7 +129,7 @@ public void defaultSpanBuilderWithRemoteParent() { @Test public void startSpanWithParentFromContext() { - NonThrowingCloseable ws = tracer.withSpan(span); + Scope ws = tracer.withSpan(span); try { assertThat(tracer.getCurrentSpan()).isSameAs(span); when(tracer.spanBuilderWithExplicitParent(same(SPAN_NAME), same(span))) @@ -142,7 +142,7 @@ public void startSpanWithParentFromContext() { @Test public void startSpanWithInvalidParentFromContext() { - NonThrowingCloseable ws = tracer.withSpan(BlankSpan.INSTANCE); + Scope ws = tracer.withSpan(BlankSpan.INSTANCE); try { assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); when(tracer.spanBuilderWithExplicitParent(same(SPAN_NAME), same(BlankSpan.INSTANCE))) diff --git a/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java b/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java index e22f372bec..96022561b5 100644 --- a/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java +++ b/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java @@ -14,8 +14,7 @@ package io.opencensus.stats; import io.grpc.Context; - -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import io.opencensus.tags.unsafe.ContextUtils; /** @@ -48,12 +47,12 @@ static StatsContext getCurrentStatsContext() { * @return An object that defines a scope where the given {@code StatsContext} is set to the * current context. */ - static NonThrowingCloseable withStatsContext(StatsContext statsContext) { + static Scope withStatsContext(StatsContext statsContext) { return new WithStatsContext(statsContext, ContextUtils.TAG_CONTEXT_KEY); } // Supports try-with-resources idiom. - private static final class WithStatsContext implements NonThrowingCloseable { + private static final class WithStatsContext implements Scope { private final Context origContext; diff --git a/core/src/main/java/io/opencensus/stats/StatsContextFactory.java b/core/src/main/java/io/opencensus/stats/StatsContextFactory.java index cee9f253d0..833d6d3da8 100644 --- a/core/src/main/java/io/opencensus/stats/StatsContextFactory.java +++ b/core/src/main/java/io/opencensus/stats/StatsContextFactory.java @@ -15,7 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import java.io.IOException; import java.io.InputStream; @@ -67,7 +67,7 @@ public final StatsContext getCurrentStatsContext() { * void doWork() { * // Construct a new StatsContext with required tags to be set into current context. * StatsContext statsCtx = statsCtxFactory.getCurrentStatsContext().with(tagKey, tagValue); - * try (NonThrowingCloseable scopedStatsCtx = statsCtxFactory.withStatsContext(statsCtx)) { + * try (Scope scopedStatsCtx = statsCtxFactory.withStatsContext(statsCtx)) { * doSomeOtherWork(); // Here "scopedStatsCtx" is the current StatsContext. * } * } @@ -84,7 +84,7 @@ public final StatsContext getCurrentStatsContext() { * void doWork() { * // Construct a new StatsContext with required tags to be set into current context. * StatsContext statsCtx = statsCtxFactory.getCurrentStatsContext().with(tagKey, tagValue); - * NonThrowingCloseable scopedStatsCtx = statsCtxFactory.withStatsContext(statsCtx); + * Scope scopedStatsCtx = statsCtxFactory.withStatsContext(statsCtx); * try { * doSomeOtherWork(); // Here "scopedStatsCtx" is the current StatsContext. * } finally { @@ -98,7 +98,7 @@ public final StatsContext getCurrentStatsContext() { * current Context. * @throws NullPointerException if statsContext is null. */ - public final NonThrowingCloseable withStatsContext(StatsContext statsContext) { + public final Scope withStatsContext(StatsContext statsContext) { return CurrentTagsUtils.withStatsContext(checkNotNull(statsContext, "statsContext")); } } diff --git a/core/src/test/java/io/opencensus/stats/CurrentTagsUtilsTest.java b/core/src/test/java/io/opencensus/stats/CurrentTagsUtilsTest.java index 46e5675b8c..0e3060d957 100644 --- a/core/src/test/java/io/opencensus/stats/CurrentTagsUtilsTest.java +++ b/core/src/test/java/io/opencensus/stats/CurrentTagsUtilsTest.java @@ -16,7 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.grpc.Context; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -46,7 +46,7 @@ public void testGetCurrentStatsContext_WhenNoContext() { @Test public void testWithStatsContext() { assertThat(CurrentTagsUtils.getCurrentStatsContext()).isNull(); - NonThrowingCloseable scopedStatsCtx = CurrentTagsUtils.withStatsContext(statsContext); + Scope scopedStatsCtx = CurrentTagsUtils.withStatsContext(statsContext); try { assertThat(CurrentTagsUtils.getCurrentStatsContext()).isSameAs(statsContext); } finally { @@ -58,7 +58,7 @@ public void testWithStatsContext() { @Test public void testWithStatsContextUsingWrap() { Runnable runnable; - NonThrowingCloseable scopedStatsCtx = CurrentTagsUtils.withStatsContext(statsContext); + Scope scopedStatsCtx = CurrentTagsUtils.withStatsContext(statsContext); try { assertThat(CurrentTagsUtils.getCurrentStatsContext()).isSameAs(statsContext); runnable = Context.current().wrap( diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java index 8185f68a5d..eb353b0e57 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java @@ -16,7 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.grpc.Context; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.internal.VarInt; import io.opencensus.tags.unsafe.ContextUtils; @@ -166,7 +166,7 @@ public void testWithNullStatsContext() { @Test public void testWithStatsContext() { assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - NonThrowingCloseable scopedStatsCtx = factory.withStatsContext(statsContext); + Scope scopedStatsCtx = factory.withStatsContext(statsContext); try { assertThat(factory.getCurrentStatsContext()).isEqualTo(statsContext); } finally { @@ -178,7 +178,7 @@ public void testWithStatsContext() { @Test public void testWithStatsContextUsingWrap() { Runnable runnable; - NonThrowingCloseable scopedStatsCtx = factory.withStatsContext(statsContext); + Scope scopedStatsCtx = factory.withStatsContext(statsContext); try { assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); runnable = Context.current().wrap( diff --git a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java index 307f254d60..3c6e4f4e6c 100644 --- a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java +++ b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java @@ -13,7 +13,7 @@ package io.opencensus.examples.stats; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import io.opencensus.stats.Measure.MeasureDouble; import io.opencensus.stats.MeasureMap; import io.opencensus.stats.Stats; @@ -56,12 +56,12 @@ public static void main(String[] args) { System.out.println("Default Tags: " + DEFAULT); System.out.println("Current Tags: " + factory.getCurrentStatsContext()); StatsContext tags1 = DEFAULT.with(K1, V1, K2, V2); - try (NonThrowingCloseable scopedStatsCtx1 = factory.withStatsContext(tags1)) { + try (Scope scopedStatsCtx1 = factory.withStatsContext(tags1)) { System.out.println(" Current Tags: " + factory.getCurrentStatsContext()); System.out.println( " Current == Default + tags1: " + factory.getCurrentStatsContext().equals(tags1)); StatsContext tags2 = tags1.with(K3, V3, K4, V4); - try (NonThrowingCloseable scopedStatsCtx2 = factory.withStatsContext(tags2)) { + try (Scope scopedStatsCtx2 = factory.withStatsContext(tags2)) { System.out.println(" Current Tags: " + factory.getCurrentStatsContext()); System.out.println( " Current == Default + tags1 + tags2: " diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java index 9e0667169f..262b100006 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansContextTracing.java @@ -13,7 +13,7 @@ package io.opencensus.examples.trace; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import io.opencensus.trace.Span; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; @@ -34,7 +34,7 @@ private static void doSomeOtherWork() { private static void doSomeMoreWork() { // Create a child Span of the current Span. Span span = tracer.spanBuilder("MyChildSpan").startSpan(); - try (NonThrowingCloseable ws = tracer.withSpan(span)) { + try (Scope ws = tracer.withSpan(span)) { doSomeOtherWork(); } span.end(); @@ -54,7 +54,7 @@ private static void doWork() { public static void main(String[] args) { LoggingExportHandler.register(Tracing.getExportComponent().getSpanExporter()); Span span = tracer.spanBuilderWithExplicitParent("MyRootSpan", null).startSpan(); - try (NonThrowingCloseable ws = tracer.withSpan(span)) { + try (Scope ws = tracer.withSpan(span)) { doWork(); } span.end(); diff --git a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java index e663ae1121..415cec9a87 100644 --- a/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java +++ b/examples/src/main/java/io/opencensus/examples/trace/MultiSpansScopedTracing.java @@ -13,7 +13,7 @@ package io.opencensus.examples.trace; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import io.opencensus.trace.Span; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; @@ -33,7 +33,7 @@ private static void doSomeOtherWork() { private static void doSomeMoreWork() { // Create a child Span of the current Span. - try (NonThrowingCloseable ss = tracer.spanBuilder("MyChildSpan").startScopedSpan()) { + try (Scope ss = tracer.spanBuilder("MyChildSpan").startScopedSpan()) { doSomeOtherWork(); } } @@ -51,8 +51,7 @@ private static void doWork() { */ public static void main(String[] args) { LoggingExportHandler.register(Tracing.getExportComponent().getSpanExporter()); - try (NonThrowingCloseable ss = - tracer.spanBuilderWithExplicitParent("MyRootSpan", null).startScopedSpan()) { + try (Scope ss = tracer.spanBuilderWithExplicitParent("MyRootSpan", null).startScopedSpan()) { doWork(); } } From 19a146d219c7e1aca0a48cfcc0c79181f24473c6 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 10 Jul 2017 17:55:16 -0700 Subject: [PATCH 0281/1581] Deprecate NonThrowingCloseable in favor of Scope. --- .../common/NonThrowingCloseable.java | 3 +++ .../main/java/io/opencensus/common/Scope.java | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/io/opencensus/common/NonThrowingCloseable.java b/api/src/main/java/io/opencensus/common/NonThrowingCloseable.java index 1dac89f857..81d1166c74 100644 --- a/api/src/main/java/io/opencensus/common/NonThrowingCloseable.java +++ b/api/src/main/java/io/opencensus/common/NonThrowingCloseable.java @@ -28,7 +28,10 @@ * ... * } *

            + * + * @deprecated {@link Scope} is a better match for operations involving the current context. */ +@Deprecated public interface NonThrowingCloseable extends Closeable { @Override void close(); diff --git a/api/src/main/java/io/opencensus/common/Scope.java b/api/src/main/java/io/opencensus/common/Scope.java index 929fbd237d..edcc6b9cf4 100644 --- a/api/src/main/java/io/opencensus/common/Scope.java +++ b/api/src/main/java/io/opencensus/common/Scope.java @@ -14,7 +14,19 @@ package io.opencensus.common; /** - * A {@link NonThrowingCloseable} that represents a change to the current context over a scope of - * code. + * A {@link java.io.Closeable} that represents a change to the current context over a scope of code. + * {@link Scope#close} cannot throw a checked exception. + * + *

            Example of usage: + * + *

            + *   try (Scope ctx = tryEnter()) {
            + *     ...
            + *   }
            + * 
            */ -public interface Scope extends NonThrowingCloseable {} +@SuppressWarnings("deprecation") +public interface Scope extends NonThrowingCloseable { + @Override + void close(); +} From 969f95088a3a1e490460ad53931b24e46e6ca907 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 11:14:25 -0700 Subject: [PATCH 0282/1581] Remove Scope.close() method. --- api/src/main/java/io/opencensus/common/Scope.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/api/src/main/java/io/opencensus/common/Scope.java b/api/src/main/java/io/opencensus/common/Scope.java index edcc6b9cf4..5c06974892 100644 --- a/api/src/main/java/io/opencensus/common/Scope.java +++ b/api/src/main/java/io/opencensus/common/Scope.java @@ -26,7 +26,4 @@ *
*/ @SuppressWarnings("deprecation") -public interface Scope extends NonThrowingCloseable { - @Override - void close(); -} +public interface Scope extends NonThrowingCloseable {} From a112d081d9bccc93ebf524d3eb8689012ae5ecf2 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 12:53:21 -0700 Subject: [PATCH 0283/1581] Revert "Remove Scope.close() method." This reverts commit 969f95088a3a1e490460ad53931b24e46e6ca907. The close() override is necessary to suppress a deprecation warning from NonThrowingCloseable.close(). --- api/src/main/java/io/opencensus/common/Scope.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/io/opencensus/common/Scope.java b/api/src/main/java/io/opencensus/common/Scope.java index 5c06974892..edcc6b9cf4 100644 --- a/api/src/main/java/io/opencensus/common/Scope.java +++ b/api/src/main/java/io/opencensus/common/Scope.java @@ -26,4 +26,7 @@ *
*/ @SuppressWarnings("deprecation") -public interface Scope extends NonThrowingCloseable {} +public interface Scope extends NonThrowingCloseable { + @Override + void close(); +} From f2909b30a8922ab78b4647da6895123ffa53a678 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 08:08:58 -0700 Subject: [PATCH 0284/1581] Clean up TagContextTest.java. --- .../java/io/opencensus/tags/TagContextTest.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/core/src/test/java/io/opencensus/tags/TagContextTest.java b/core/src/test/java/io/opencensus/tags/TagContextTest.java index 91da5a63c0..116af83bf3 100644 --- a/core/src/test/java/io/opencensus/tags/TagContextTest.java +++ b/core/src/test/java/io/opencensus/tags/TagContextTest.java @@ -19,9 +19,7 @@ import io.opencensus.tags.TagKey.TagKeyBoolean; import io.opencensus.tags.TagKey.TagKeyLong; import io.opencensus.tags.TagKey.TagKeyString; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -30,8 +28,6 @@ @RunWith(JUnit4.class) public class TagContextTest { - @Rule public final ExpectedException thrown = ExpectedException.none(); - private static final TagKeyString KS1 = TagKeyString.create("k1"); private static final TagKeyString KS2 = TagKeyString.create("k2"); @@ -40,7 +36,7 @@ public class TagContextTest { @Test public void applyBuilderOperationsInOrder() { - assertThat(newBuilder().set(KS1, V1).set(KS1, V2).build().getTags()) + assertThat(TagContext.newBuilder().set(KS1, V1).set(KS1, V2).build().getTags()) .containsExactly(KS1, V2); } @@ -50,7 +46,7 @@ public void allowMutlipleKeysWithSameNameButDifferentTypes() { TagKeyLong longKey = TagKeyLong.create("key"); TagKeyBoolean boolKey = TagKeyBoolean.create("key"); assertThat( - newBuilder() + TagContext.newBuilder() .set(stringKey, TagValueString.create("value")) .set(longKey, 123) .set(boolKey, true) @@ -63,8 +59,7 @@ public void allowMutlipleKeysWithSameNameButDifferentTypes() { public void testSet() { TagContext tags = singletonTagContext(KS1, V1); assertThat(tags.toBuilder().set(KS1, V2).build().getTags()).containsExactly(KS1, V2); - assertThat(tags.toBuilder().set(KS2, V2).build().getTags()) - .containsExactly(KS1, V1, KS2, V2); + assertThat(tags.toBuilder().set(KS2, V2).build().getTags()).containsExactly(KS1, V1, KS2, V2); } @Test @@ -74,10 +69,6 @@ public void testClear() { assertThat(tags.toBuilder().clear(KS2).build().getTags()).containsExactly(KS1, V1); } - private static TagContext.Builder newBuilder() { - return new TagContext.Builder(); - } - private static TagContext singletonTagContext(TagKey key, Object value) { return new TagContext(ImmutableMap.of(key, value)); } From 69e6a4c11a92594dc193f017188db3483b01f838 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 07:37:25 -0700 Subject: [PATCH 0285/1581] Add back STATS_CONTEXT_KEY and rename CurrentTagsUtils to CurrentStatsContextUtils. I realized that we still need STATS_CONTEXT_KEY during the migration from StatsContext to TagContext. STATS_CONTEXT_KEY and TAG_CONTEXT_KEY should have different types, and we can only remove STATS_CONTEXT_KEY when we remove the uses of StatsContext. --- ...ils.java => CurrentStatsContextUtils.java} | 16 +++++++++----- .../opencensus/stats/StatsContextFactory.java | 4 ++-- ...java => CurrentStatsContextUtilsTest.java} | 22 +++++++++---------- .../stats/StatsContextFactoryTest.java | 3 +-- 4 files changed, 25 insertions(+), 20 deletions(-) rename core/src/main/java/io/opencensus/stats/{CurrentTagsUtils.java => CurrentStatsContextUtils.java} (83%) rename core/src/test/java/io/opencensus/stats/{CurrentTagsUtilsTest.java => CurrentStatsContextUtilsTest.java} (67%) diff --git a/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java b/core/src/main/java/io/opencensus/stats/CurrentStatsContextUtils.java similarity index 83% rename from core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java rename to core/src/main/java/io/opencensus/stats/CurrentStatsContextUtils.java index 96022561b5..cde5abad88 100644 --- a/core/src/main/java/io/opencensus/stats/CurrentTagsUtils.java +++ b/core/src/main/java/io/opencensus/stats/CurrentStatsContextUtils.java @@ -15,25 +15,31 @@ import io.grpc.Context; import io.opencensus.common.Scope; -import io.opencensus.tags.unsafe.ContextUtils; /** * Util methods/functionality to interact with the {@link io.grpc.Context}. */ // TODO(sebright): Move this into the tags package. -final class CurrentTagsUtils { +final class CurrentStatsContextUtils { // Static class. - private CurrentTagsUtils() { + private CurrentStatsContextUtils() { } + /** + * The {@link io.grpc.Context.Key} used to interact with the {@code StatsContext} contained in the + * {@link io.grpc.Context}. + */ + public static final Context.Key STATS_CONTEXT_KEY = + Context.key("opencensus-stats-context-key"); + /** * Returns The {@link StatsContext} from the current context. * * @return The {@code StatsContext} from the current context. */ static StatsContext getCurrentStatsContext() { - return ContextUtils.TAG_CONTEXT_KEY.get(Context.current()); + return STATS_CONTEXT_KEY.get(Context.current()); } /** @@ -48,7 +54,7 @@ static StatsContext getCurrentStatsContext() { * current context. */ static Scope withStatsContext(StatsContext statsContext) { - return new WithStatsContext(statsContext, ContextUtils.TAG_CONTEXT_KEY); + return new WithStatsContext(statsContext, STATS_CONTEXT_KEY); } // Supports try-with-resources idiom. diff --git a/core/src/main/java/io/opencensus/stats/StatsContextFactory.java b/core/src/main/java/io/opencensus/stats/StatsContextFactory.java index 833d6d3da8..9abe675da9 100644 --- a/core/src/main/java/io/opencensus/stats/StatsContextFactory.java +++ b/core/src/main/java/io/opencensus/stats/StatsContextFactory.java @@ -48,7 +48,7 @@ public abstract class StatsContextFactory { * {@code io.grpc.Context}. */ public final StatsContext getCurrentStatsContext() { - StatsContext statsContext = CurrentTagsUtils.getCurrentStatsContext(); + StatsContext statsContext = CurrentStatsContextUtils.getCurrentStatsContext(); return statsContext != null ? statsContext : getDefault(); } @@ -99,6 +99,6 @@ public final StatsContext getCurrentStatsContext() { * @throws NullPointerException if statsContext is null. */ public final Scope withStatsContext(StatsContext statsContext) { - return CurrentTagsUtils.withStatsContext(checkNotNull(statsContext, "statsContext")); + return CurrentStatsContextUtils.withStatsContext(checkNotNull(statsContext, "statsContext")); } } diff --git a/core/src/test/java/io/opencensus/stats/CurrentTagsUtilsTest.java b/core/src/test/java/io/opencensus/stats/CurrentStatsContextUtilsTest.java similarity index 67% rename from core/src/test/java/io/opencensus/stats/CurrentTagsUtilsTest.java rename to core/src/test/java/io/opencensus/stats/CurrentStatsContextUtilsTest.java index 0e3060d957..0c154cb7a4 100644 --- a/core/src/test/java/io/opencensus/stats/CurrentTagsUtilsTest.java +++ b/core/src/test/java/io/opencensus/stats/CurrentStatsContextUtilsTest.java @@ -25,10 +25,10 @@ import org.mockito.MockitoAnnotations; /** - * Unit tests for {@link CurrentTagsUtils}. + * Unit tests for {@link CurrentStatsContextUtils}. */ @RunWith(JUnit4.class) -public class CurrentTagsUtilsTest { +public class CurrentStatsContextUtilsTest { @Mock private StatsContext statsContext; @@ -40,38 +40,38 @@ public void setUp() { @Test public void testGetCurrentStatsContext_WhenNoContext() { - assertThat(CurrentTagsUtils.getCurrentStatsContext()).isNull(); + assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isNull(); } @Test public void testWithStatsContext() { - assertThat(CurrentTagsUtils.getCurrentStatsContext()).isNull(); - Scope scopedStatsCtx = CurrentTagsUtils.withStatsContext(statsContext); + assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isNull(); + Scope scopedStatsCtx = CurrentStatsContextUtils.withStatsContext(statsContext); try { - assertThat(CurrentTagsUtils.getCurrentStatsContext()).isSameAs(statsContext); + assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isSameAs(statsContext); } finally { scopedStatsCtx.close(); } - assertThat(CurrentTagsUtils.getCurrentStatsContext()).isNull(); + assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isNull(); } @Test public void testWithStatsContextUsingWrap() { Runnable runnable; - Scope scopedStatsCtx = CurrentTagsUtils.withStatsContext(statsContext); + Scope scopedStatsCtx = CurrentStatsContextUtils.withStatsContext(statsContext); try { - assertThat(CurrentTagsUtils.getCurrentStatsContext()).isSameAs(statsContext); + assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isSameAs(statsContext); runnable = Context.current().wrap( new Runnable() { @Override public void run() { - assertThat(CurrentTagsUtils.getCurrentStatsContext()).isSameAs(statsContext); + assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isSameAs(statsContext); } }); } finally { scopedStatsCtx.close(); } - assertThat(CurrentTagsUtils.getCurrentStatsContext()).isNull(); + assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isNull(); // When we run the runnable we will have the statsContext in the current Context. runnable.run(); } diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java index eb353b0e57..f900412a29 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java @@ -19,7 +19,6 @@ import io.opencensus.common.Scope; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.internal.VarInt; -import io.opencensus.tags.unsafe.ContextUtils; import io.opencensus.testing.common.TestClock; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -147,7 +146,7 @@ public void testGetDefaultForCurrentStatsContextWhenNotSet() { public void testGetCurrentStatsContext() { assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); Context origContext = Context.current().withValue( - ContextUtils.TAG_CONTEXT_KEY, statsContext) + CurrentStatsContextUtils.STATS_CONTEXT_KEY, statsContext) .attach(); // Make sure context is detached even if test fails. try { From 93f722d141353d24a39cdbe0f01801046378d62c Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 09:00:25 -0700 Subject: [PATCH 0286/1581] Change type of TAG_CONTEXT_KEY to Context.Key. --- .../main/java/io/opencensus/tags/unsafe/ContextUtils.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java b/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java index 2c97a4ade5..f10e66dc26 100644 --- a/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java +++ b/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java @@ -14,7 +14,6 @@ package io.opencensus.tags.unsafe; import io.grpc.Context; -import io.opencensus.stats.StatsContext; import io.opencensus.tags.TagContext; /** @@ -32,6 +31,6 @@ private ContextUtils() {} * The {@link io.grpc.Context.Key} used to interact with the {@code TagContext} contained in the * {@link io.grpc.Context}. */ - public static final Context.Key TAG_CONTEXT_KEY = - Context.key("opencensus-tag-context-key"); + public static final Context.Key TAG_CONTEXT_KEY = + Context.keyWithDefault("opencensus-tag-context-key", TagContext.empty()); } From 0553db6512efbe79bb6e648ce61d7e78117c0f6b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 07:50:59 -0700 Subject: [PATCH 0287/1581] Expose TagContext.EMPTY. --- .../main/java/io/opencensus/tags/TagContext.java | 14 ++++---------- .../io/opencensus/tags/unsafe/ContextUtils.java | 2 +- .../java/io/opencensus/tags/TagContextTest.java | 5 +++++ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java index ccfc94d35b..065f860b83 100644 --- a/core/src/main/java/io/opencensus/tags/TagContext.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -33,7 +33,10 @@ @Immutable public final class TagContext { - private static final TagContext EMPTY = newBuilder().build(); + /** + * The empty {@code TagContext}. + */ + public static final TagContext EMPTY = newBuilder().build(); // The types of the TagKey and value must match for each entry. private final Map tags; @@ -55,15 +58,6 @@ public Builder toBuilder() { return new Builder(getTags()); } - /** - * Returns an empty {@code TagContext}. - * - * @return an empty {@code TagContext}. - */ - public static TagContext empty() { - return EMPTY; - } - /** * Returns an empty {@code Builder}. * diff --git a/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java b/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java index f10e66dc26..8e11a6aedc 100644 --- a/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java +++ b/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java @@ -32,5 +32,5 @@ private ContextUtils() {} * {@link io.grpc.Context}. */ public static final Context.Key TAG_CONTEXT_KEY = - Context.keyWithDefault("opencensus-tag-context-key", TagContext.empty()); + Context.keyWithDefault("opencensus-tag-context-key", TagContext.EMPTY); } diff --git a/core/src/test/java/io/opencensus/tags/TagContextTest.java b/core/src/test/java/io/opencensus/tags/TagContextTest.java index 116af83bf3..b20b9307d5 100644 --- a/core/src/test/java/io/opencensus/tags/TagContextTest.java +++ b/core/src/test/java/io/opencensus/tags/TagContextTest.java @@ -34,6 +34,11 @@ public class TagContextTest { private static final TagValueString V1 = TagValueString.create("v1"); private static final TagValueString V2 = TagValueString.create("v2"); + @Test + public void testEmpty() { + assertThat(TagContext.EMPTY.getTags()).isEmpty(); + } + @Test public void applyBuilderOperationsInOrder() { assertThat(TagContext.newBuilder().set(KS1, V1).set(KS1, V2).build().getTags()) From 400e3f07cb9c220300b0944afb8f6d7b3b72dc31 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 08:52:40 -0700 Subject: [PATCH 0288/1581] Add io.opencensus.tags.CurrentTagsUtils. CurrentTagsUtils is based on CurrentStatsContextUtils. --- .../io/opencensus/tags/CurrentTagsUtils.java | 67 +++++++++++++++++ .../opencensus/tags/CurrentTagsUtilsTest.java | 73 +++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java create mode 100644 core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java diff --git a/core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java b/core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java new file mode 100644 index 0000000000..7f65276e48 --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java @@ -0,0 +1,67 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import io.grpc.Context; +import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.tags.unsafe.ContextUtils; + +/** + * Utility methods for accessing the {@link TagContext} contained in the {@link io.grpc.Context}. + */ +final class CurrentTagsUtils { + + private CurrentTagsUtils() {} + + /** + * Returns the {@link TagContext} from the current context. + * + * @return the {@code TagContext} from the current context. + */ + static TagContext getCurrentTagContext() { + return ContextUtils.TAG_CONTEXT_KEY.get(Context.current()); + } + + /** + * Enters the scope of code where the given {@link TagContext} is in the current context and + * returns an object that represents that scope. The scope is exited when the returned object is + * closed. + * + * @param tags the {@code TagContext} to be set to the current context. + * @return an object that defines a scope where the given {@code TagContext} is set to the current + * context. + */ + static NonThrowingCloseable withTagContext(TagContext tags) { + return new WithTagContext(tags); + } + + private static final class WithTagContext implements NonThrowingCloseable { + + private final Context orig; + + /** + * Constructs a new {@link WithTagContext}. + * + * @param tags the {@code TagContext} to be added to the current {@code Context}. + */ + private WithTagContext(TagContext tags) { + orig = Context.current().withValue(ContextUtils.TAG_CONTEXT_KEY, tags).attach(); + } + + @Override + public void close() { + Context.current().detach(orig); + } + } +} diff --git a/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java b/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java new file mode 100644 index 0000000000..6587ba7e54 --- /dev/null +++ b/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import io.grpc.Context; +import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.tags.TagKey.TagKeyString; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link CurrentTagsUtils}. */ +@RunWith(JUnit4.class) +public class CurrentTagsUtilsTest { + + private static final TagContext TAG_CONTEXT = + TagContext.newBuilder() + .set(TagKeyString.create("Key"), TagValueString.create("Value")) + .build(); + + @Test + public void testGetCurrentTagContext_WhenNoContext() { + assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); + } + + @Test + public void testWithTagContext() { + assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); + NonThrowingCloseable scopedTags = CurrentTagsUtils.withTagContext(TAG_CONTEXT); + try { + assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); + } finally { + scopedTags.close(); + } + assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); + } + + @Test + public void testWithTagContextUsingWrap() { + Runnable runnable; + NonThrowingCloseable scopedTags = CurrentTagsUtils.withTagContext(TAG_CONTEXT); + try { + assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); + runnable = + Context.current() + .wrap( + new Runnable() { + @Override + public void run() { + assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); + } + }); + } finally { + scopedTags.close(); + } + assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); + // When we run the runnable we will have the TagContext in the current Context. + runnable.run(); + } +} From e7e0137d4790d9453e01a0146d7023c8f8c65486 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 08:54:46 -0700 Subject: [PATCH 0289/1581] Add APIs for working with the current TagContext. --- .../java/io/opencensus/tags/TagContext.java | 43 ++++++++++++++++--- .../opencensus/tags/CurrentTagsUtilsTest.java | 2 +- .../io/opencensus/tags/TagContextTest.java | 4 +- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java index 065f860b83..998bf905a8 100644 --- a/core/src/main/java/io/opencensus/tags/TagContext.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -15,6 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import io.opencensus.common.NonThrowingCloseable; import io.opencensus.tags.TagKey.TagKeyBoolean; import io.opencensus.tags.TagKey.TagKeyLong; import io.opencensus.tags.TagKey.TagKeyString; @@ -33,10 +34,8 @@ @Immutable public final class TagContext { - /** - * The empty {@code TagContext}. - */ - public static final TagContext EMPTY = newBuilder().build(); + /** The empty {@code TagContext}. */ + public static final TagContext EMPTY = emptyBuilder().build(); // The types of the TagKey and value must match for each entry. private final Map tags; @@ -59,14 +58,32 @@ public Builder toBuilder() { } /** - * Returns an empty {@code Builder}. + * Returns a new empty {@code Builder}. * - * @return an empty {@code Builder}. + * @return a new empty {@code Builder}. */ - public static Builder newBuilder() { + public static Builder emptyBuilder() { return new Builder(); } + /** + * Returns the current {@code TagContext}. + * + * @return the current {@code TagContext}. + */ + public static TagContext getCurrentTags() { + return CurrentTagsUtils.getCurrentTagContext(); + } + + /** + * Returns a new {@code Builder} created from the current {@code TagContext}. + * + * @return a new {@code Builder} created from the current {@code TagContext}. + */ + public static Builder currentBuilder() { + return getCurrentTags().toBuilder(); + } + /** Builder for the {@link TagContext} class. */ public static final class Builder { private final Map tags; @@ -141,5 +158,17 @@ public Builder clear(TagKey key) { public TagContext build() { return new TagContext(tags); } + + /** + * Enters the scope of code where the {@link TagContext} created from this builder is in the + * current context and returns an object that represents that scope. The scope is exited when + * the returned object is closed. + * + * @return an object that defines a scope where the {@code TagContext} created from this builder + * is set to the current context. + */ + public NonThrowingCloseable buildScoped() { + return CurrentTagsUtils.withTagContext(build()); + } } } diff --git a/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java b/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java index 6587ba7e54..b787444ff1 100644 --- a/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java +++ b/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java @@ -27,7 +27,7 @@ public class CurrentTagsUtilsTest { private static final TagContext TAG_CONTEXT = - TagContext.newBuilder() + TagContext.emptyBuilder() .set(TagKeyString.create("Key"), TagValueString.create("Value")) .build(); diff --git a/core/src/test/java/io/opencensus/tags/TagContextTest.java b/core/src/test/java/io/opencensus/tags/TagContextTest.java index b20b9307d5..bb19bd65e4 100644 --- a/core/src/test/java/io/opencensus/tags/TagContextTest.java +++ b/core/src/test/java/io/opencensus/tags/TagContextTest.java @@ -41,7 +41,7 @@ public void testEmpty() { @Test public void applyBuilderOperationsInOrder() { - assertThat(TagContext.newBuilder().set(KS1, V1).set(KS1, V2).build().getTags()) + assertThat(TagContext.emptyBuilder().set(KS1, V1).set(KS1, V2).build().getTags()) .containsExactly(KS1, V2); } @@ -51,7 +51,7 @@ public void allowMutlipleKeysWithSameNameButDifferentTypes() { TagKeyLong longKey = TagKeyLong.create("key"); TagKeyBoolean boolKey = TagKeyBoolean.create("key"); assertThat( - TagContext.newBuilder() + TagContext.emptyBuilder() .set(stringKey, TagValueString.create("value")) .set(longKey, 123) .set(boolKey, true) From f8d9c8e2639eda2f083fa9ae932a88b72ab3fbe6 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 09:04:24 -0700 Subject: [PATCH 0290/1581] Change TagContext method order. --- .../java/io/opencensus/tags/TagContext.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java index 998bf905a8..4c2a295d38 100644 --- a/core/src/main/java/io/opencensus/tags/TagContext.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -49,12 +49,12 @@ Map getTags() { } /** - * Returns a builder based on this {@code TagContext}. + * Returns the current {@code TagContext}. * - * @return a builder based on this {@code TagContext}. + * @return the current {@code TagContext}. */ - public Builder toBuilder() { - return new Builder(getTags()); + public static TagContext getCurrentTags() { + return CurrentTagsUtils.getCurrentTagContext(); } /** @@ -67,21 +67,21 @@ public static Builder emptyBuilder() { } /** - * Returns the current {@code TagContext}. + * Returns a new {@code Builder} created from the current {@code TagContext}. * - * @return the current {@code TagContext}. + * @return a new {@code Builder} created from the current {@code TagContext}. */ - public static TagContext getCurrentTags() { - return CurrentTagsUtils.getCurrentTagContext(); + public static Builder currentBuilder() { + return getCurrentTags().toBuilder(); } /** - * Returns a new {@code Builder} created from the current {@code TagContext}. + * Returns a builder based on this {@code TagContext}. * - * @return a new {@code Builder} created from the current {@code TagContext}. + * @return a builder based on this {@code TagContext}. */ - public static Builder currentBuilder() { - return getCurrentTags().toBuilder(); + public Builder toBuilder() { + return new Builder(getTags()); } /** Builder for the {@link TagContext} class. */ From e63d4d3ea1f6c53a71453824334056b7541046ef Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 11:21:10 -0700 Subject: [PATCH 0291/1581] Remove obsolete TODOs. --- .../java/io/opencensus/stats/CurrentStatsContextUtils.java | 1 - .../src/main/java/io/opencensus/tags/unsafe/ContextUtils.java | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/core/src/main/java/io/opencensus/stats/CurrentStatsContextUtils.java b/core/src/main/java/io/opencensus/stats/CurrentStatsContextUtils.java index cde5abad88..2db58c950f 100644 --- a/core/src/main/java/io/opencensus/stats/CurrentStatsContextUtils.java +++ b/core/src/main/java/io/opencensus/stats/CurrentStatsContextUtils.java @@ -19,7 +19,6 @@ /** * Util methods/functionality to interact with the {@link io.grpc.Context}. */ -// TODO(sebright): Move this into the tags package. final class CurrentStatsContextUtils { // Static class. diff --git a/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java b/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java index 8e11a6aedc..e8a5e0da73 100644 --- a/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java +++ b/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java @@ -20,10 +20,8 @@ * Utility methods for accessing the {@link TagContext} contained in the {@link io.grpc.Context}. * *

Most code should interact with the current context via the public APIs in {@link - * io.opencensus.stats.StatsContextFactory} and avoid accessing {@link #TAG_CONTEXT_KEY} directly. + * io.opencensus.tags.TagContext} and avoid accessing {@link #TAG_CONTEXT_KEY} directly. */ -// TODO(sebright): Update this Javadoc to reference the class in the tags package that provides -// methods for interacting with the current context, once TAG_CONTEXT_KEY uses TagContext. public final class ContextUtils { private ContextUtils() {} From 3279bf8342180aef083b13010c17ed42fb8cac82 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 12:36:19 -0700 Subject: [PATCH 0292/1581] Use Scope interface in 'tags' package. --- core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java | 6 +++--- core/src/main/java/io/opencensus/tags/TagContext.java | 4 ++-- .../test/java/io/opencensus/tags/CurrentTagsUtilsTest.java | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java b/core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java index 7f65276e48..36989cb3ed 100644 --- a/core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java +++ b/core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java @@ -14,7 +14,7 @@ package io.opencensus.tags; import io.grpc.Context; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import io.opencensus.tags.unsafe.ContextUtils; /** @@ -42,11 +42,11 @@ static TagContext getCurrentTagContext() { * @return an object that defines a scope where the given {@code TagContext} is set to the current * context. */ - static NonThrowingCloseable withTagContext(TagContext tags) { + static Scope withTagContext(TagContext tags) { return new WithTagContext(tags); } - private static final class WithTagContext implements NonThrowingCloseable { + private static final class WithTagContext implements Scope { private final Context orig; diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java index 4c2a295d38..efdf8175c4 100644 --- a/core/src/main/java/io/opencensus/tags/TagContext.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -15,7 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import io.opencensus.tags.TagKey.TagKeyBoolean; import io.opencensus.tags.TagKey.TagKeyLong; import io.opencensus.tags.TagKey.TagKeyString; @@ -167,7 +167,7 @@ public TagContext build() { * @return an object that defines a scope where the {@code TagContext} created from this builder * is set to the current context. */ - public NonThrowingCloseable buildScoped() { + public Scope buildScoped() { return CurrentTagsUtils.withTagContext(build()); } } diff --git a/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java b/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java index b787444ff1..cc9e337c20 100644 --- a/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java +++ b/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java @@ -16,7 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import io.grpc.Context; -import io.opencensus.common.NonThrowingCloseable; +import io.opencensus.common.Scope; import io.opencensus.tags.TagKey.TagKeyString; import org.junit.Test; import org.junit.runner.RunWith; @@ -39,7 +39,7 @@ public void testGetCurrentTagContext_WhenNoContext() { @Test public void testWithTagContext() { assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); - NonThrowingCloseable scopedTags = CurrentTagsUtils.withTagContext(TAG_CONTEXT); + Scope scopedTags = CurrentTagsUtils.withTagContext(TAG_CONTEXT); try { assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); } finally { @@ -51,7 +51,7 @@ public void testWithTagContext() { @Test public void testWithTagContextUsingWrap() { Runnable runnable; - NonThrowingCloseable scopedTags = CurrentTagsUtils.withTagContext(TAG_CONTEXT); + Scope scopedTags = CurrentTagsUtils.withTagContext(TAG_CONTEXT); try { assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); runnable = From 9d8f5de53e1e415289252345f6d0246c71659fcb Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 11 Jul 2017 12:38:47 -0700 Subject: [PATCH 0293/1581] Rename CurrentTagsUtils to CurrentTagContextUtils. --- ...Utils.java => CurrentTagContextUtils.java} | 4 ++-- .../java/io/opencensus/tags/TagContext.java | 4 ++-- ...t.java => CurrentTagContextUtilsTest.java} | 23 ++++++++++--------- 3 files changed, 16 insertions(+), 15 deletions(-) rename core/src/main/java/io/opencensus/tags/{CurrentTagsUtils.java => CurrentTagContextUtils.java} (96%) rename core/src/test/java/io/opencensus/tags/{CurrentTagsUtilsTest.java => CurrentTagContextUtilsTest.java} (65%) diff --git a/core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java b/core/src/main/java/io/opencensus/tags/CurrentTagContextUtils.java similarity index 96% rename from core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java rename to core/src/main/java/io/opencensus/tags/CurrentTagContextUtils.java index 36989cb3ed..9c2f06d56b 100644 --- a/core/src/main/java/io/opencensus/tags/CurrentTagsUtils.java +++ b/core/src/main/java/io/opencensus/tags/CurrentTagContextUtils.java @@ -20,9 +20,9 @@ /** * Utility methods for accessing the {@link TagContext} contained in the {@link io.grpc.Context}. */ -final class CurrentTagsUtils { +final class CurrentTagContextUtils { - private CurrentTagsUtils() {} + private CurrentTagContextUtils() {} /** * Returns the {@link TagContext} from the current context. diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java index efdf8175c4..dd4fe2083f 100644 --- a/core/src/main/java/io/opencensus/tags/TagContext.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -54,7 +54,7 @@ Map getTags() { * @return the current {@code TagContext}. */ public static TagContext getCurrentTags() { - return CurrentTagsUtils.getCurrentTagContext(); + return CurrentTagContextUtils.getCurrentTagContext(); } /** @@ -168,7 +168,7 @@ public TagContext build() { * is set to the current context. */ public Scope buildScoped() { - return CurrentTagsUtils.withTagContext(build()); + return CurrentTagContextUtils.withTagContext(build()); } } } diff --git a/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java b/core/src/test/java/io/opencensus/tags/CurrentTagContextUtilsTest.java similarity index 65% rename from core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java rename to core/src/test/java/io/opencensus/tags/CurrentTagContextUtilsTest.java index cc9e337c20..0a867094e9 100644 --- a/core/src/test/java/io/opencensus/tags/CurrentTagsUtilsTest.java +++ b/core/src/test/java/io/opencensus/tags/CurrentTagContextUtilsTest.java @@ -22,9 +22,9 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@link CurrentTagsUtils}. */ +/** Unit tests for {@link CurrentTagContextUtils}. */ @RunWith(JUnit4.class) -public class CurrentTagsUtilsTest { +public class CurrentTagContextUtilsTest { private static final TagContext TAG_CONTEXT = TagContext.emptyBuilder() @@ -33,40 +33,41 @@ public class CurrentTagsUtilsTest { @Test public void testGetCurrentTagContext_WhenNoContext() { - assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); } @Test public void testWithTagContext() { - assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); - Scope scopedTags = CurrentTagsUtils.withTagContext(TAG_CONTEXT); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); + Scope scopedTags = CurrentTagContextUtils.withTagContext(TAG_CONTEXT); try { - assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); } finally { scopedTags.close(); } - assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); } @Test public void testWithTagContextUsingWrap() { Runnable runnable; - Scope scopedTags = CurrentTagsUtils.withTagContext(TAG_CONTEXT); + Scope scopedTags = CurrentTagContextUtils.withTagContext(TAG_CONTEXT); try { - assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); runnable = Context.current() .wrap( new Runnable() { @Override public void run() { - assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); + assertThat(CurrentTagContextUtils.getCurrentTagContext()) + .isEqualTo(TAG_CONTEXT); } }); } finally { scopedTags.close(); } - assertThat(CurrentTagsUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); // When we run the runnable we will have the TagContext in the current Context. runnable.run(); } From 4502e9b6164c1616f3448e9017a5b8331c986d85 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 11 Jul 2017 17:10:32 -0700 Subject: [PATCH 0294/1581] update to gradle 4.0.1 (#451) --- gradle/wrapper/gradle-wrapper.jar | Bin 54783 -> 54712 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- gradlew | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index cc735e8dbad162a0ef33399e06e521567d864b23..cb893cbb29f5c59f2f3e7b57739da6a3e81b1777 100644 GIT binary patch delta 17163 zcmY(KV{~Rgv$kW~wry)Bwr$(yo@A0IPA0a^iH(UT=ERuTw!it_b=EoS-M^}P-L-rF zsI|MR>#ENx$hIoTAH49()X|<_z`($?62w#yGmr3(@Ne9%-N3p+;k*zKerHCK!hnEE zMAM^cFmZ@)qO>*TrktLFaMS0F6W`%dTyJs}Q8J@d(t9*M17X7}os}{>%`d+5Iwl3p z@w|7~z9@>?&fRVXHR(BGm9^X-1YQI__V`bCU-sM|_C6m2(-6z_EO;`1JAzHSGzK=U zEpByJx|p)G_fA-kp0b0D2U%^OEFoc>@O-d)&Hid%`>woY7C(Egyn%w(t}{Vf3s?Fu znOAEt{ZGV@z0q4qlH$VVR4A}p@yn1YYg6(qpOM0zI%;|QJx2I&B#A!T#HLaEbBuw^> z9c)?LUN$_Vt^^qJe9~jTuo8bd{)PIG9^v(P`w4O;SPoC~2#7ZB+ocKp(ao?bqd~|= z0nq_RKtaW2c$8V5pblcO^E9>dNuxPIQe`FZnEeeH4iPAZa?ch=H+R@9N<_0P;^X0- zdZNz`!L(mW*-<#n4bd1nEDlX}M4XsKvpCHTX|?z9C^{?+)?~IRf$ zMPh*C)>DBvq&ey^j54YQWKA|g$$AEUR;L4zTX)6<{mp6%S?|>RBH8>RnH0>iM-*D^<2x6p!uPxthBOKX&Lp`%Bee5Qd&-4EBTF6A1%ER(uN#- zAhn0lq;hLgh8*fyRV|^%L@Ubx+)Z`ueteJvjmTfFQVzOuBZhTGO=#*mMl|o*)?zJl z*G)6=Y;x$&mog7kdHwl^wlu6|11n&Kcz<#CIw{kpgi5b%T8_4Cth>3W&|RyNX~RMR zd&HxTYdfFwoP%FM&({C37Tj8H`*m>Y4ssNLQCwqKH%SlJ$036}-2or}@`y3(OTX@(?DW?s5=>RtRpc!S-g`TMs>_vY4uw zM83gyo}5#2W!Worhi@EKOjCOBQy*+Zcjw$pW-f|kV=-xyzcAmSAW50bQk>W|#Uz=d z30Sdk=^K39oow2uzMS@+90!ERxR(Y|)SI^XgKIT8rdv{4VfQ1v6g|=l)jezr*RWcn zb4uI9*KK#;yM_i~ubb$-B0JNA5L9Q&zAh>y52Jjqx!%HCGL>M*A&0-9*RN$`ct%NJGQ^eVuEnv|Orqh^} z^3e|~vXg@pT;&Khn8GsXH$!n1(bFbvXYHdn8@ziRrW&?;P}86A->St_UKkvsV28vZ z(vTJz47EPIu?pH6 zafcwJ=?pWqTsJu?1=DET1I*Di$@+>~k(2~3cJnCRJ_TE*5`ci_x}ltBh~HHtK3na< zQ8MnuppyUiz+)_$L6I+0Cc{kW3aalqDO>=aO?!g1h_Q}G^Y>Q>Ret}9(>a4mdyZqO z4ivqfeb$LJg+7mO9kz=T?vSEodZa%koP(d;Y#Z5)WJdWrEv6fx+ho6MUnvUsu^&&@ z?z~zEoU{dTU%z{RLJ#guAuhTZ@YA5sWQl z8swDBj4J8`+M2p-n?qZYveIBI9r~_o}L`<7fi^a|q%#-o6)m+J; z=?P3L`2xSMrrTWVY3Yb-TVt@tbewo-oji-D1jxqL7bpxiU{sdeAfU^d$E=`Q>+rFx zJhmW6$^!d0Ex9=K^lj;hataMy7)j6ypEnQ*JOoUNpCyFQLYnF@`qOu^g%}Fi+4nd5 zR>Mg>bTMgZVC}kNHS(pfX)N(`a;_Ss5rsjD*roKw`{-_(mGi|TJ?H)*IzPn2DV$j? zFY=nZ(wo{iEm;};{ji$@rd6^YE_c|!o+I$e#{iLRNu_YsQn}3))nfvF8Yf*X7{fjb z(MEH$mE4&DE-DyWw>hKF70Fqt+~~x3S((k2MzhPJJEiXi&dKnsTaCrWo)1bE4jJy2 ze@SktGx#-2CVRG3pk2LJ~$onm) z*at-c-1XbgL1FAO|I(0AMq$xn@>iUIXM0)s63j7gtF@D5)2>cj&8u>2Z~IR>k>qj% zzv$3XL+7cR@i>(}HSD+_W&Jo*Y)IgQ6Hz8(_>h;miVdZG-F)b7!6_?B=oL3I_XPj>c47gw0asz<}+ioMVaW2Xoj}sGmmZ{#RBJA za%;oyEkz`)X3S3FP&Lb;#Bynd?ZnX?4lE}Py2Oog_d+GnXR*%h1ZY%TgLgZ&|o4z7xT7H3b{$Fq9R zFXVh_CVeO~cg8bxcWD-@>~C|l4M}8ZgUvB~Q?oQgw2rj=&&yegU>B-F%X)H*-)82@ zE{cpsbN(Lu9k#8ijb$xX%7#>UvyIDGTZZcQOb4~5?l`;v+9WFl!DiwR^Ab?cO|sb% zan9Phz`bP9^03gnQ0eR_f3CMKpnbb(J+t{Bs}Zi>xa=yYxax1mkJ%Ai_twNqn5KUs z64rtyKmgg+H9eKsk%WLp2_qbOpCeF?HmPEarm7PBRVSxw_s$`d96J za%lXCjWxHjkAZX>h>L^rZ~*IZ?(H=q`h9RI@a_^^paj={b_953j{uLsAZI5UhKgf* zg2A_uj;uD9m|-L42%&W)QcgO-WOK5LLkYKCt{7qTfereG(hW&EEEuU7i@~}Jd(HB7A0UT$>crpSPJW=< z&$YG~{{1TMgK9^AjWPW|vT#lHb4U8h2*0GT7L4}c#>I>kwv0hFy6j3s12J-sNLuB{ zM^r>?oGDl_jrCoqAzrm3bT9R^O?WePNU84tV9hlzZoc(BdkX#p@duD)O4ZXB2t7h`c1yvCBro~;tZTS z_OM1nI!@?yzgf*nOQe;dhx@g0Eek2`n-VJ$mJmL&OEQ%-y$>y~8OL}SS z%H=4bYg*k>l{XCt&|m4O2UBQ$KR%dHP`pE78~Ct94BqjHfKfA-V#)xGxOiy3IBi~2 zy5W^vu`;qg7aU6AJ{dBMy%U$N4&eZyXjP1ut`JP^-vmk3wBtII;Hr^bv@XQE*H@u2 zx9Y6wvN^wrc6-?mx<)i^d?bihOkTBWdyr3k%biM-NeZ1~o}$rR4nCg+U{-;`JJE{u~^fb)cZb}*1%Pa8d-!yj)zgCQN1AHk#qGLa6ftB!2hb9{IhD0Rn@n-=eIC* z;uPqz?5p^8qg*>|vD-H6$^%qC>ZmfC!>BTy&`LSuBU)Xsj?gb)=P`_1p{n*r14Eu@FUPw<|}l>A{g((v0@jqy!Y zvhjc#J2CY{M0aHzM&B2UKj*mAXSgefZh0GR!$uLwd1{HGvAUWR8m5^mD6t)Hy+$(q zPohaXxF5(t5p3v2FkoQ&h+trx|MEzjr0NkeAVo{x9rF-BNJMvT^^}_jg%5p%dq#p| zIpj`^p_59gPlL?8!F4zE>*8E^w@-6bt=2brWm);vVn;u@Rgl|!)&a$Qh7}Du+H|Nv zGiSF`S#N$?`>~?6pXy6MXF~#N8|L(rU{CmA;MSqPHt>EaO$x~ux+aj@-;N>_3D2zn z*zx_OjH5?3o=+I$Z}$CCQ@VCtm}#s=i@R{;$!(x9K#k1WI-oX=Pb^G#%%!4Jg)1RwD%?NFO-N$n`jqn zqYm3c6q40dobW64Ar}LG+!jpT2EESzMu<@u(pi*3?fCvw7`iAtA5*^{i@Bq%!Ix$L zj7Hr`nYOfE4@`y98*Qoe@7`9n=@Iuq{cXRBijn{3uV@|zt!?%Mo%@@ zj7=hF;YP3JZXpCIzNC4{yQiMYmEj1OVBIpPHeeHDHe!TDO;pZKTzr0)&NqCHj&U&3 z6LEf(IG~pi?%7Z6mcs(5S{zq^rFKnkt}^afmQEwgFCwcdEzXv*IF<62E3ND&38SOi zlnYC`6uQU`ZXk_}I%`A5^4A4Y(u|23#k+)QjmqD$Aj(Ez#_zHmuIpYzLuoA@pp;dE zdK@c@&1<_GhmF+W0grp(J9HxnNm^DxIeGoyk;Md4E=;2hR_@dG*V!|GP;Cqb3`%fQQkMm#HHrv14 z+;3>Sx@X}$Q-2KaiPDl-T-YxE^oW|;X-hf1BGQELYb z30tMqN&8e{w#}K>8+rC3UV9iLI2voar| z9kVHFP^nWNZ&PLz`S(%^qa1inoUrwzsp_B+0!bxZY$GRG>qUDYLw0|Q8B^2m{9Z4X z26|xtwd+X6r#~7?quC(_&$|j1M1x!tm2fZ_3AgbV z)eym|9O8d)U;mDBHbiqaFfYVT$sIsq91#Q=>Lk&o7H0++0O-brSQ~?5GWm#T(@Yd1 z-Mzts6p8cR`K~LQV$wgS3WBEu*_4oPcyN`62#-3##O*fkPz3(02O_>lA7wb5JUEqN zl=!E4kan`V!6(RbBr`*jl6lPwR7V;}SMIXnX<7%a>bJW3pzD{x`oCWMy*8jovH2Tm zz>(rWhK&G-Joz*D;;yN|qj1f7-LkawzW&9uG^_h_kMg3yLa@Bj8GZWBXhPH$z5&56 zJOs(fC8JTG2oZ2ZR`N-|)ZU|T_?|sWVY6=i@foQs$?Lw%%u|JLiH@1!(rY|9(Nwu) zUyUsjCR`j$(eGY8E~zzWHanhN-r&c*c&4d!sJI9mIuZ>#2H^KfqX56yHV5Dc7W4+` zgh>X<_~L+qZ$M+96@X_Wun z6%v=9sOAUDs+3jK zKba17o-{sUYJ>fkX|Gszh8}&1%1m%Kqz+zwz!_^1v0lGXII~=>bgi595SF>nk^VS$0c!Tr1H`~n75;kRJ`0oGVSnh$||T5Xq9iU0=2g$D-4@Sm;8fr1Kf z`0l_)f%FB8)gde)bUAdP9vRPq(81hH<}1o`og`IGf>Ml?Cl#@5R*MJC2B$2oto}-D z(vPX8W2MJU#tr}Y&rZSd29IyRJGAJ=>t^fHt5NRT^gulLG8s?BGN@D2VNibWMy$j)s;^%DAJnbv!=VwXZr(~hGM2ov*QsdN^o}CeG>;T18w^oCm zixJ|RN5Y^0^`X`)N9e8V-Oj{+LEaNj`g=c|At;oz>Ipum@~<@m%(Z*)D)IYyPC~8t zD@?}=>iOB}vA{yBbzSFAZ89`~zmjxmz*U%^fTT{Xe$OULOfoz}LEmqVU~U&*oJ>Pv zbA@|(llb^#;=001_2J_5f?(oH+GGe0dWuslwfQ1X@bf*gI7APMd+1yxMSbyXmMjsE z+V_|3Hu4m%BEJ9`<)OVz=$Gnx9X%7nL4{b5wEBz8I$WO2@$Rk^L)QSXdExCP?8hWq z6afE$z*H-$3p2W{BqZ$c8QZc;bEQA7`!;jdH{x3h7bdLJJcmU9oE^P&d9NvLzC*sP)=wUy|u zLbQ5RS?&F=9ZCeVF_suWEbhn0iq71*A#Krc6aSx=-!cWLP+E)Aal>ahNYy71u3Sc{ z-!@h7#=~lPo;h$9a0{My6=W-PScnrr*qcjRlbm1p$F0F(m8hA4cZ(^!V>#`K9|>}6 z26m;ESjjuCuzeMhp7D z1@_Pop0Z}sNFEq-(-z+DhYFZvZ7+=P6oxn^KyVvGpK`_QXd$=$wL+G5u>8IKaGkT6DH?TqvEGDyxkLV(9dnu zr=k#1+b7PC{^Csf@*F?EYH8A?EA2PMfvsy)WZU(MZLHjizJ5c5kBV*Mr`BI;sE?lG zJw)-1e}zy4CoxCcD&p&4`Dkgmgm7EsSwE~>)=KFgjuv$Qe*s6TWmR>I%U**chy`CV z{9r8h;QoSI*8H4Z!%Ti{!mRs!Yd5K86KcW2*2%?&pmTftXdwL+j zW~qFkJc;r`gE?CVT=(PasPY+!l5({{2t_6=a7hjOLMbM-K{LgLC~A*YU%SMQ+|jfT zg}Er|nDqicgR(rLB(qKCZW;HaxVx&Ou`0s&p?t()s!Gidltz89iJz<`L~FC~32z3@k)@N7XfE9w{SV>W2k(ZF`}S5Fw7v<7);2 z?&>#v*U`IJO(8nE3nEIFdm@%7A(pckM`UP!ehJHJua$d<`>-}Hulq1*c!qJkbz`4K z!3{h2SsAvn6^j;2=tuqfrS9;lu&@UB&W|o2rkf?~c=*y+plW0d0&Acpq?Gh-3{@F@ zs(aV>z>{^^jpc!862WlhsITEFcVko|a{Rh1liz0>zmD(w+4>*#YC+lq%l7UrCgdvZ zw1I+Dj^W)7A~`i%5{HUBb-eE3mX7v>xwlGuoA53^B0}4op{j4h`STu|%vEJo%#+JN ziP>U>3pvVAEuSc87xsC~4a6!k6V*1Aow$|go>QNepiadLc}Qb%=oZ_gI1P1?%RI{A zdyHc`=Ibll(+D%7b^!m}-`JfrUAzXrCgw3ww?#5sA45{si?g33sBNP^08UZ2hbge@ z6DG}u;y2?1?Un#rV<_$gp=++x_7V+%ZeUnD+>uU1tZnqwE`3=_Ql^_W)dOyFvmPDx ztAwA}F=pH7S;L2K50B2our{3}4YT{U&v^ppeLG^=S57Kk!h8-d`aRtT_HJWP+&>S) zmgqXo7X^9DGI_0r@xxyrk;QewVwYilg_D8m@&>NB*C)mC9|wH>Q(hr`UlD){)Pr+I zS@Jzd(CK|>C^@Wsez7aW&KJUcv?VpdHV9sqKSWSRd=pz766{}@Frw$Nw3U{3lhSc* zGY8*DSb8?;laZA3oBrV5Sr(k3zQ~b;0X{+b4kpXEDzFW7(_gc|wPjpNpf2;iV$zhjqbn|Tan=yI zT#_=i2tKQxL~u5w+hdh`S!~N8D z_iJew=^*jQ93p1EESQk0TZ<+g5ole4>kps_cYFg{w{_S5u=z|6yZ^T3&ooRo?uj?7 z$+KdUe-f0afh5-TxNr)9z;3ZJj1ySP7!;&XT(GrP&lij~6h19u_mYpf?-q*U%Ck*r z#)5yDx@ej9)4c)$tw#f?SC8zDFHl}_+oCLI1}+UBewwdH`Qf}V6d_|fKsPH?q$rGW zE1c2z@hbqveNV0I!QSki-kgpl&9TWdgE8&jjecxY5>F4@!W+vTA*N4-r0?JTLOi!A zaV@idBoT}}o*fp`#qq!R5}VYrel}TX><3^#a`OM(tB_=Y$7ix6pV;e1==?_Ijp*IJ z-rBa#SjHw(ik-|B92kc0sZNq6mlka@D_f2GiP}ibj0A_AgV-)cg$V}sKo15+_Meli z$tW_AqYEE^z27WK`*<)lIavq&wXK>GW0b^;i;f_Xte%|Al$~sc$~!S;oq8%q9^+Jt zR7>x?(6bfWySzkG1A~j9#dB#@ucl>j(b_)nyejag^RfR=XZlOP%E`$o@yoBhG-s=x z{pwHmp4&j*duL@~c?rblBD8x~F#^fVd@f&LF7#$*PrhjEunjHc#wU#SDPk*#MS?t+ z&OE7@9`4#AmqO7rqRdS-!fDrbE)+YLq>x@n{9szcN9%`mxDSdwLLNrpu@LWI*^SUK zed+;M*kQO0N<6A7d>W`cb$qYUAQQos;kG@h3fl;6FARY-5kFd-D=$svbB>HP>Cg>8 zfAqi?q?C{}z}&;W5#o%W-bo=B$(n}WuF=}oB-cYR!mCOuHOho3sMDj%Cfwtmn=ile zMF3cSD}FIzB%UM}2w#$I6d63cg$dLD+5{Sb^(_+Ol~u>zne39>M#OSTk<}M(ifauk z&tTQ?@sH38b>=k2+9SSkt>;QXI3)+{_IbkA#G7K*LWtlS(DzUhS~=r8m$7PC;BS)YFelibFT*XpJn~ za98>>b$71SRc2*>ss0Cb2w&TLjc1#D$XwRRBf(|a=-ALiL^pR-Ef89=?|V7p*WubY za*QucJYX?z#^<(MTZ^@Dt04iFh*v7R>9~m8!GA+faqX6NCmt6jD$kzIbMyBsmtx(95?@N(4w&oO*DoGV`EoH(AGXrsT5G+hBqFk2?VJqmMLrwJPovaz=fob~Vv zK%QE}2l|sv&miVt%p(0%YU~e)^^m>?4XlGn3?HXa8HN(0+1*nPzl`NUV@jcw?H|*T z~HVRS-UeV?`WFu-{aR zW<*Pih>vlrXQ>dIC$&i?k5r}R6vIsVitTdq^>3>I4#AfO$7b>bFc416oO89GdA@q` z`I;Z)ic`i$?f4t|e24(%1~y*27H>veuDbNso}d1353A+v)^WgIi`wFao29a}v0>V5 z4<~((t{#Wh>aN}QUm9k$xF+J=8%oEjBlEta5@U9}L_&vz-5XM!juP1kCJSL$8uMM- zKWZwCTdRHH5*>@q58?@2k@nJUZuBOm+MLRm%&QTl=I_`>n~F_&?;tcblhbAo4 zzQw2zC^|OQDOdq)Awjr=QWoC}q}Q|4nF8BB;feao{Z@ps$6%kqKMY!+ zHe(l#qf@V^Fs+&N`J>>(zPp^3-~6-KgAq%CD$7$h1D72r1nnu052&S=Q>jk{f%{%# zJ6wjCrGnciZyw-3p_3Opn{gRaQg-| zg_hu{`<{3hnoOS+sESh$@?o&Dz-XREA17tEXjNe$lnanFZ!aSkC=j0ANK5&iUMVN! zp46(rvSG|#B%Azdi-X*#M_1kDJwmRP z`)XKPj!)4f1DE4_6WS1+ORg6kuYB6pZW*zNQK0F|(bR&%YQzvdEgC#To2BjUhl}d2 zOJksw-PGAwWErt=leDOX)5>?eF4>itt4%$x;g<^-sT@PT_@}(sik0NevugNd=BgeO zya=Y$ma>-L!3kH+k@UdCC|C9;OXgoob|{r>c+~WFYWAe|mfv`GNpG``j-+Y!$Kt`Wrwzp$cEv5@78soj@MfE{uNBn>#~OlyHtD5dSgzxJm_ZF8hDg*&l`J;hCwZVBkTTdXyS7X(pcv) zm!i?d0=6!8c|_B~X+Ic|RpSf?^Pz z*iyA+-6*;N|EL|?`mWhFPTx4;MGI~pi83h)IiT+jXKsSnT8^vb2vq3qKxQ>8#z!ypWx zG;`DIadX1&>J(BEVJ1*#I(=#K;DMAP@;ctv3r~r#?Xc3XC|(|C&aaeUXYQO^P*MM5 zGc>yMq@uS_Oq5LCDrkQF;Nhsf%ZFgmq*o?J$eDjb88R%bDe^m>{;h3HIbs*pRkY<~ zyGhqx*Y6*KmI8Z3oPv6r#2`xT{QU~Re^>ZHWXHLC42Sh36ua@P13d+|jQnS_{oJq~ zDhh4urbJ#d2=oY-Vy!9CKTZD@m;#WQFcA>i+eYa{n?jn3H)k&j8%)>|!&gZq9laLx zPglJ`T#`nuvTG7ey^*{&36|bOza`4tH*o!osZ%K(Q-9Xn{BHK;jlBMDb*2eO_>(#I zbG&IK&!~<)cB=U*wYx$kvM|*#- z%Cqp75!UB-a{2g*S&a|ufQeoJ=WK%LJjRnUs?~Odp5I^Q?JBqpT7QQ07&A;%PP}_$1+n^nL5mp7N-8uIGB%KIg)iT2U$&&zSoMyb)Z!-5|O<)q5m$ zNs%*DX>4Y)=Wwptj&J2+Tp9j+Tv9vuv%(TQbkU%f5(@r3h;bI}z|sl8@d6GStc(9B z>F{6rG3A#{b2R6|V#2O0Bd)3cesb;XKOJo>Nt!Ul-C{^}H^u2WSI|yd zTt$#P_-t4B2V)9)9IO3>?&>AsX7nMMpOO0z(^)$$n*@f{8Rdf7QZtsl$H{m)sTv+Rtte|FW=;=3#*Wu@W{zC2h3%l&7(Rs&cWZMIY85-&<}6(N}zTx?&D3 zCN{*4zrI=q7$PGC2_2>&s~D}2h3O&Q(9VuS7LydZTJDF-&{y$E1UHO{bA99wZ2L9M z(|_|~(Xs=$!j!_0Zf$t5ch9*xz$q`-5GaBz^b6upj0Z z4$F^bRozm*j&P{deydL5`d&%)3?V(m&C(i^&3Ft*b--in&*9%8ci?M$Z3=Y?4h+=M zmuj6Oo^gP=>q@%luWsi`>WORx3q-7X*YV|D{M&VMG7x)&Xu7u=VjE81<@KYqH5GLx z#%hb>vpDk3qmHI^Ca*EgN(h2OdH1hdSsTa9|tpDnaa3*DuPEIcHj9aJXr9Xf(4GuPN0I$ zfokaFVrTO(Qm(=~wm?`bL-<`Sxh1#2|$3LEhIEk9Ce?yC@p^)P|y+9ds0fw2L+ z!9|2MUWezO%`d%ytz%HU7f2WJ;EvTq{T^*+#0qtaAD$JHTX_}qj? z^t6Y+v;K;X_!4^TQ0Z5c6~t66WckQd|3R5^GkNxazu>&cAM#n?(iZ8QxYSS8kFaTr zZyM`gm*ft1$?H^}PzSubt7kk!l z0PkQqqGE(p>P;qn!vvBOtrg8QPZZc;DIt?A3j=+rL8}eWzLFUI(37t=mE&HFMztE}EW1(;OsIz7g zfyf6xzfQE0_xqzAYE$<7lvcQu92AP6TSgT?9oUTDd3V)$K{GQ)a}k0d>p}hdj#7uQ zb<%m|8Sme| z{`0{PBly#Rf~cpEXvStgaA_C^a-Lg5X>#A=VC;5v8cO>Wa(`b* zNMqZy`o1PxGg$F&G6$>?b|VhBG2~tv@}APzJ@N8+l1|@3*ud8|;QA8->5fCEJH*5X zo5mlR{>+o=P1^PQ9Kn?^6X@R(|{%Vtr_@<%5-*9;}+3%6&0h80}a`pR*O%pL;`aYHC znlI=FY6(jR3iqsMQOj>{_7@Vx&`nbt5mW&!vGK+uaf^v~v19X@7h&on)ciaD1=CMB zy}bO|XH2@lkboEEI7!}LB)4@NK{CC;j;-cd@61}TVy&-{N2@O1zT7oZt$F?);uyKl8}I!kLppSvgRIcs1PSy||r@ySA9ta`kFCHxxq z0bh3{DO4tv=KdM-uvPG2tg`Tii_qEo_2_d-3_^mF0!O^>JuYHM<(kquEo=8|Lj<=H&V2gKUX$|43Vccf@>#yZ)s(WdaGXUP55#wJ#e1o&eMlu_bnUNxXkK2A_hiJx z?LU=~`jyU(r-+<+@-C)28`j~gT~J=TV){0l;!TmpOjVh~-H&gTV5YwGy8}+U73COD zpWux_GVP=Y+rGnW3Q%BRhX_euY$O0}LQSj>B@R=QbhpT2>;mi`3!%k>h$YRkv&m|N z$heBow)SUK`28~$G*b#}Z}3}&|%|By&vt zfM+u_W4SAG-U!%%^k3T9%Ln6e5kK2MY9qoaNZ65zxeOb%@!k@Sc)r)!C2N3Yt4pg0 z@9n;DlhTDDxQ6H!m20$MtM7V5(=Wef4!QheHufb}G~}?kRjX|xJ^C6HOKhAoq!hUw z6`QqU?KEfQ*Uu^oNHNs8laPR2%X^6xgGsu;wWYgwP?mA1Bxz?R*n?^lGOP zohT@6>z5V42Z&J#mMkj78CMjfHWnEoJxfw!atkZmxW7mJ;?O8AJDCMq)GDg%V>2uC zQW5Ew8M8zjb2&Cl8N{Jg9lpa-@_euNlh~CUA^Wqcd4PM!)e*gcdsyz}=3DC>UE0Og zosE6rT%)Ry1t%#~dUDXzP`m8p3HY1`JRI}*Db+o`!tB{O;h-!O=EV5vB9(leG#GWK z2;ds={@Y5OaQ^rc{8R<1dzFm#S}eLEWkL1xUjM*YeEi0A^y}Cd?*!cIniyKLSpJXV zZ-o&UKw;E!lIm~|oZ>KeZdCd2@~>&8`BL6*Eisp3itzY24)~r#H~an|M8oT`2(#eY z<@N)Nuy=xt2RUz%-P7XWA4#MZDB^I}OLbvy5`*j7;qu*bQM&!!YK?DaK)bEr1yWTwJwf>f~G~y;4 z0wpBrD;=4T>y^~$tZ46WUIJ`y^b0}>R&p$xrCCD575P57;*%Hrih2JKr4G47bi^#H z(ow%oKeuKfbj*CX3B+al_5RxR{;~TFB=4zjLyN?)IV5Gov&lP{~uLJ+L|C}aP-1L*h}Lo z5r6;#TZBsb7OV=Wq6vFH>*(M{H%Zo1)L=6kd&wKe1f!)4T40(f+Pnk>BW_x)IC`ZG z_wE3Hhte{iOadOH@ef%DW1xoy(Jm%(gx#&C&dwf5je8(${tkYNOAL+?Q1dB_D-%G` zY^yG+EGjLU`r#z24RQoYw7X6HIP($jtD8-!^%2au3j=`RR}@JEL+4*P?icc&@!vf61ccC92;q2t6m(&9&!k^{1{Gbp)vd_`+%7?{;?MQhC?%u`t7x z9CvRoQ)3zHSjgeGxj-7htJdAWqt;HDV$uJL8B@AWfoQ<&_f|1SeIzq6*I3%;D+gen zhiJB}R}!&p^4^5Uv-^kd_N@N&`RgC+Wutl;JNgCyk!#>Xz%LV|M2c-WYn>WedLY4@ z=O!umiU)y>cH10{o7evCUvw?C`A z#V2?Cy;6P;X~XWf7`{JFHq!T?b(ys$wW?UAz@tCZd?JMXa(@Md0-@i3iwx(KTgOTn z6fg+-h~Yd>C^zDSQllVKNmi@1|BI%Ye3BlFKX(kfLd?Jg7VjYvIq*T-`eYKp0y9rSeGg*Dy<0)E)Noz>e0+NrJ1HP0Kb{lipulC2>?w zs0?}!x<{0_3BP=A`Gu%ZMVO}RdQ1A_F6RC;Nzj|&4AMJy)i&Oj=%t#MpP_oemi9nY zH@mTuScuHiOrn>{o>(m%3`8U82!;>Ge)U1|;`*QS2o`ysUh<8mKi zW_Q*(V6q&CtjiP7xbsxHs~_xX<~5QV^Mx*5EW?zc){ZF6obLVc?$fir&K;?!TTl8s zktohW2M9m(iw$u&qTLAI!h~4wJxc*DsDA3HMUg-30)y*ALJW4lL-O`Uw3 z&JJoj=;%8f!eV5CLhpRI;CLce-5o9g+x8#XfN=O#EF3uH-P!I}uQ1iZ6tr*b>#)Y+ zcB&R{DcRJ=204P_I}kgxUU7TgcZOeAb1pF)BXDJ0dwTiEbH9jm$MHl!(Xvy_{;X}kyoOg8s=T2x#ZYlOkZW+39-hpiaF*rwn-my{b7ow(A|$+ynkawkC8EODOHXu!c$U$Rr1j_403uOqwHf3QB&f ziNVp6C(_U;60rCEIC7**;;`tH_i7ykpp`a-mZNcHxY%>wi(;Hxuu}@TNxU}WpEv!t zx_ldrdjsE)@Wf=tS7}lelks3$lB@b1K{`Ek(a_uzb|iqzX9=InZ%)12ll~Rlo;j~2+fZo+6Pe50&@uPNug2}MQAC*C+|$m>$i_qhbG3qFG!E)*;T_9}+pu%f8`%{TCX1BOQB#NZBRd+) zaV~^ju(}ubSe012k}GnVfvA7&{KGQQh)n8wnTx*q>hOIdwXL;|dC&CvzB@GWUk#6 zbymj^+ZymmW5Ysp%+p_VR5If-c^BQsAIHvt&bB4L`jk#IGhQC{%2ju`6b zqr~gvv6$_e7A|Q=mI(vGb1@4j=+j=2&NE6edoy3J5ho;HSlE_7#*f1VhSXMbk7-t@ zMmuZFd0SaFzzx`AcfqY}MM2@{BH_{r*#mf^NdIy$ljJ7bL>c5cM{E^|1Hu2nO&ck4 z@M$5_LQj)K2KjJiIcGSbz*OX6;rjYiRI&e&sQ+s9U`b9xL`kKCjQ`h(pR_ut4xXLF zGQe##&vb&N7VV95VxsGx|Pq%4n@L^j3%L8SOUQ=^|ouR9&USTOnjX&c7*lWoqp$RIj^ z3=Gx?JAf>$jLEiVBqzsZ04r9Y8(yA~VmhBQdE;f7$x^xElP%6_F{S2#xeaG6nU3az znF0koKpBC_pU+A$%`OEBDNTM;$}!pUoEB4i8JPRw9NXl3WulXF&kIc6bWVy%whAh2 z%OqF}W+v6jfMjJ5twja~Hx!qJHi8xIJ|DpJxf#sVzu?X!+5=|Jy5PnrKKbE=02!19 z0*V1#lfX*zFFGR delta 17117 zcmY(KV{j!vx2`j>ZQHhO+qN}HCf-RVcCusJwr$(a#L2|go%7vu>)g{-U9DB!f7HNM(#r+f`H)TgMg5L z0B=VKfW0G-fNUKYWAs(8ubie%HryCQP3b!08`D1M?2!>;xZerEAc5q;m=W~Yn`Bqg zy4urYjg0|YD=~+2yb5S1f>}$7SxtWpE<-V36fa8{Y!+9#Gh1ZhniMiy95Zsx5-2}+ zHpMEJCEa09r}@4vKEI#8uLW*jo&3((Ks+L%AW_>)0LIu%%XQB->%NklOq0hL?Qd|r zf_8gYw{p1t>j8n8kb+@GEH{-eUH1M83m+Z!{)2r4o*IKrwl54|3NH>|CLghZyTjMx zN4u%hM5ix7fkHz>%^QyHKRO&)1r7b$+^UDMqC<=s(Ep3G=&arKxLGrLer^fcA!hWAr^{(eY`8z0;)?C zBj=fEBctQ8ggTa6gZq zL#k5x-AC|qsZm9I9K7&h!gC>BL05fYc-W=KPQ{H@e87OL#ii|;RNzL>?O+(x2w@}w zAO~k}DONI2c_KT#p2p%Z{$ko~)>D(z;+N4~)vMR$1)*xxJ2-o+R25GqC46=(qwY4% zWcpd`tKmZWenbBe%%&WbfmEK$&QB|TzHCC-62Hxa0X{kyp+APMsx`^j3}mHUbAB>Z zXGF-Sb_T;$$thJ?>pUdLr@zpex=g6g0BdCF?J}Eu778UxhFdgr941~eJTpp=AM4}> z-8LLRn}W^?i`{7tqiasbbl2>&Kk_4ulPY;zhTF6e58{R~ebv=GJh4~5;^GjFiz&DN z4vr^PliO;Nk|>abrT|fCVfe17vb!$dj=JDq`i^LP3>g#K>+^oj-8#(HtFlub0*WV! z5EH5efi2xTIDANQklw6p0t_gs?k#ao-0AHsdK-qL-3xqQ@mEtXjnM`_)IJ?0X-UT7 z5+WZUS~vbwc(C;d%gwK$;Q#~=7eiV&q^^Fz9$Bt1HAZ?Jtf{$D6_v@lcDIiSohCKd z+1PCmJ|}`^PV#p)ZuxBatD;pm0YV7>HZF{p-&tQ(VP_?Cjx*z^4YPpJ8*rb>chVyQ zH8*w|efrW>UwXQmK^<*)^PSUzeHgnz2+7T$+as;vqTK;a~o+;>|U|BbB&FLA! zDaz+i0i)})I^To2jJ?W>ifkG4X$MM#+ggK}iw?$SI#3Zc-b0r_y;hiw0Hv%nldYps zj&0Sh>?zke?b9k4^0}o$ay6sX!Ko2yedyYox+*~=CzSS7BzBGtj`6jgb}1>5KS{W< z>C!kHJKP#pGf8t|(lT#L?9&y3U49H2sK!RfdCGG-v9rWU$$Ls?-dF(pCD3-`xE6jj z_6Y5AFkJ*R>7(%}%!i(U13EOz`8PFl2$#qJI2SG@S7W&-LrxSV%4-!<0mJ?Y;*1SWpD2MN7{{F zL0cj&hnE9a1A?@p3m_`K9o2%>jIW#7QmTDlC?`RD-Z?Ki9+ODpEk4Ybu@`YbLB*C> zLdToYphHNm$2{lt4*>i*H%falqD>}DD_nuso91k`2KC*X_q@%YJv%-3 zmyHY5F-0l%7%n?H+bXh2o?D~6gYozxEuHA- zLQTw(yOq7L{j5fRoqbJ@)1h3p#l@$?$A@>LL!evfb5m!5BZP^ST&I|_zD8Y}Kwo#K zNmpc3V!v1hN6*>!!c~S^)}^lR9TQH2fn;1%n&&Hs7r?Knk%zdKQV`ov*_zPuDfZNq zEOWcHrtONzP^iW_weU9f0o2qcv~fKg8OU#R8-<-VkS6bL>R8Vv>G4a|`i(kKY`2`T zlKiVv+V041E|I~@-x4Q#{~>jYg)^yK+e6B>yh~Jk0mtl#495^Z^`o8rj-+)?ZrRDf!(*ZRK;)+Ir62#b#>xhNbmWYLvdKq_>0wSGJ_87xz1{Os$6g5 z;{tSLBEA2cD053JyrxC7!@ z`QPfj-9`+3!?RZsg7wzD$=#GD^^JUAtCs3mg5ypf8HzY>kJhJJOtFZG;#O(vjmKm9 zUVAtUehm{iFIsyM&_U!nlmW=BQHUos5I_a)} z1|3G+kp}-b#%pHhv_n*xtzB>EdCQC)bdv<=Dzg1WTPQMC6GeAse*Lzr!zQ&8AK=`D zZ^aaf)OwimQoZGJMuvW)q1}4YvU!?z`96uEfvOtTIfbdXOCu~fxo@M+pMZl)1pp?g zPharFJ4K;)jsbx3n~R`yquaKOWvbQNbLom$;<3`Cdkc-FKW``#+FseI4-a*9`K7vL zaCxnHP{5ONpox0}zEh>nz6a|c0LT&=^ABJ%yA;w<)^yL(wl4bO-TC7kbhSF4Hk^?& zhY)Uq=7!llHeFoFiECm{+Eu~a@Jx?0wOkQA7Pl7sTYNq5o9XpcxKxh!_ zxNf#|SzW!ZhXo_~K+ie+yreD=)qb&-HC#<3ejgPc+G_5yiC`ZS*2-Y|4wz(cpXSi2 z>UL*nKG)k+?Zj-IUG6%;X=?QYUEW`z_sG!%KJDnv1Ur(_3tdf*B&T#J6)*(Pgd1+_ z10~+?cl|35^1pe>`ZMRq`sq7(oeHYiqW+%LH<#w$bx^L7Au#pk)jiP~7ET%tt}bz% zy!}E^=o7$yj6V?U00_Cb00Le*a&HC3@*Yfy-dzHs5h zgy@v?7++k4u`OLet$ShEb9}cZUCG+ZWw)^Y*iK~XgqA_Q*))b?0Eal0YY0or=&tKN zJ{7r`)b`e2s<8RWASgaw$n~jUD#>NTowtNR4tzb4&j)_N>dL2{LW05odJ*~5>v#T~ zIJHvngA}|rvYnJ+#{Of)udU(S?T_|MAs@{8XWRK{l40i_a+Q`nF?I+E3?fPjqIWNh z**_Pvfh|uGTWkxj03L8d=-o|41Dywc1ho(!qQPyHo@>abQ7ji?UjQc5rgo+G>vTaJ zHzN}v;+6ARi5KtKATKZb#NL&ai8ie{R3y%?yfhc68+rmYiN8KKC>s2*nodXbL>=u1 zBu{E`;dDwa-=8}8xPPIM%w4#Bi{2KwGluu1rC!qTiIAM}0kw_;%F&Gifr=tQ`}C6D zK?%a-W6S%V?mjQ#n1$rnUJz8Zi5!$VO3C$-parO2N_&tahx;(;+oeV&3B0%5BfTt| z9itlKp6U+k%G!$&A&*u5u%Zu4N#AKt3I(JwWWkD4FU zK0juvM&tIq0FYPw+ZmZYL4jW`AK*SL$ID6$RB#(=63>Fg`r~G4-hjwFO_ze5L3l3b8v z4+oIyuV8|SQgV&g5_6S38&tIRNsPhjJp*!$>1U`%5AvaXbji`9F0Sf5&B}hqtl)IU zmRDNT`Gr~v$o&=^7-~rUgvTKV;924L3+gOvTs)FE9%%B^0EH>2S`sm(6BNn{M?@mB+UiZu zTi6Zcj4oreI!&8pO^MNAZFo}DZ{XT45xAzDMLc^9 z)^BP4F0p;ZUhjMDKELiP?|wax3jN@YG&=LdFGlo5#ad#n-jCu19C#`YM#qxN+TM5R zcF)CPEq_qB-zDNQR_t4FXyaOLs%TC|#u`dzmoVC-*^PF^63F^O*%PGJ=Q-jNXtZ73 zBz5cZ^=!cqxfA@r<*nJX1wF4l8CuM43za}Hn!nLNFhVEd=b@$I_F z5;nSRa37xFP2o!gWW)MyX5*opPWU(q)NL7WxZ0bt?`Oga|Syz zs>gRv!*4d=<7SMP#)3_^3H02lRIV?z?!2=vL5DCcsHrz@+kUcQzSO`QCdkS)A-CZ z2ZbtqM$D@^nia$Ws#GNuS@F}acyN-&hF~^b(2X`0a5Qc8mUXj|y+$i1t?*jl@k=Vd z1LJN;X?eZU$$6DbHtS*6VEx}tshK9>_!}ZnLivsW93QTgd+&sbvnIv%#@MR}_yZqWsY{Mku|&zA0=ZjA=Is) zyH2I|`bw0nVn~K>&p|J6yW>s9Qm%^DqLXKlb;7hsQH$vMF!eRwJE zC$G$nc{&(yCvq4d(klCm=tHmEuf?jHaW5+pla9x6kC{|{6;<6z6e-cUbuNZfH?&#- zCjW}k+564B6;%78dI;j<58f1$Rd?wBcD1c19HXr~)~zWmn}ux7k75q5n>G$Gx*vV5 zb`*oPF(+moGl1uPQ=i@IP-;e)aoIs2o4keo#g=5Fw)@h*iTt}$P}tu28Oqv6NL>)O zVweZfc`FVPUziK=0466b0XJu;w15Z(kdKE_lT?Vknmb}eEx}a}i+Tz=^zYc2#kVD` z5B@XdV6ET6H9uea)4JfEGrCc%YkFAima@a~pe&&r+-F02uz`AyY08Z_4aooD@)VHqvM-8W5(KIYwCrVoiTn-lpiRMz%Upa zyR>?~0;umEaq+j{YJ0o|ERE$2S~NB;j$Ll)V}oEh#1I{#SfPx{XHdsy1Cb z?7Iw@L~yB2YN|F$ltis^!N~bCK&MelC!0$b;ly_d9hY_6!UHP~1iKp^(^PziDmq*gxPG&JIDp`B(zhcpC2Cg+aBs z(`FeVo}2`z$*z6dU_yzuH~d&2*SpRAJ-?lp?gQ$0*_%NW0Cg6op)9BuKo)29;`2zp z9D_0KVw+<-|Bm(|I<^b?{W@=>@)>c1Xx;le@M_KIa~pOPxc?f0+=w#XbaQr&wzL2U z{7LUi3lLe|Gr&jpM7lkA=Z{sZi*h9U`6(UDM5l<6J$`LU+Hvb@-IL3@oi%%)e^D=g zppy)hg|sjKNu(?X296HW7*A9Sir5-qd{F=k0z!-ZFMCKP1!;oKfPS#9a1t1vKZBSFZj!t#8OsT7h27Q)?VasB_k8+YzxRv+zr9{qKr)9gG5DNYBd0wh^bKiKQ)##h3#5ah zZd@U1Zw{0FyJY_wRv!R3+D7AiK0T|0R?ExcwJ|)q`MZ>c@opp`oK#h=0(PrRsdh-c zdNdfFfRmdVTXDarJ%#)EK0Q;xyY+@)yQKPkG^$44)#*odAdo7w>DssA!qB^R9y+GYp}AC5#XGVGw^t<;Kd|=I+YF8)Jaf?*4Z7 zHbI!rGlJXG6Epz4Ble8y!C77@I`qBToSkKZRC&dcQZ*%~F7!cr0~s14zV#P;lZS_U zlhvzwJM}vhA0K4H+)-m5g!u4gVMJN8n6Zh$XM8~IG=6?lWR3N}smy2`_V|xa>8W_x z3={#*BC0~yYf!%xZFY*fo=N%GP$}S>^b~Zi{Q2RbBrBk6a);2_W80fuq|n#p3zoi| zPu;qK!9XcC(I|PeKH%JSr;rL_f*`sKX9p(+ho6B+DTBYMKvGr|JgLY=_e$jeGwxzM zsXvaR-CNRh-Z>K|?ji!k=28$ZELxV-@&Fu1CP?lc=1r-To~(z7jy6nWlO4y4`nV0l z;)7p&!xbRudKzw+K4B(@#q(5LZB5S)mg>RV1zCRS$fn2_Wp;d8rv5})OYOEER#fRs zLQonly}=sMy8`#!XHS3j6sv|}wvk2aXHLEg1zLG-DP{Jg2&w5l#En}!C008dcSNd{ zsgINF4q+YCrODkFY!U+X&ik%JMgOU;X>#ylCJ)ei%~rs{(&$*gU^6FIXD(&3u*lw#a34spLCdu?9$zVb;z_&Bmg*f_M?jTPDG6~sN^X)Teq7tt}C0^K7$Rj!OnF|J#mc?Nlt#H~?_7!U|sHZ7V zDyWm)a3_a-ZM#S(*i{&5(N)SLBuMkZX%*C?h9k8LB5>=I6f+Nd7IxWQ7g80q=K*aA z0!g;u81?dKSTcToQZ^-&DNz`pd>aqq15Ki2klQF$q`{;t0?D|gR$@}q=3^RMLo+D6 z8SIDo(3x8(0v5rxtHrjNmc=&L31*T*3q!K?va;|trp@SB@S9v-W((~TjlNBi`crdH zX(V_Qe+q(2D#10RsU)e3H!6$lOaax}r4f$>ntQBw&UOmaCRmxuwp-!iags3!%Iq$L zUkZ_Bi{b(`W?oO!Owsz8>6F{{NDA*m$*bfs4$9(%l$_x)U9my-gBfk$t#qcqE~3^2 zm=gxdMDIp>r1~^3S7sNppw+xz9X3_fmAOiX44ejjOwag8$Hwz~22v-~a)55e`vn$( zc|p z1eMOp%3C~=d*@#4k@$>N(F~7XK0M;Z)tWkwpzg12>>kr0QZTfWou0(KjeN_tcKy=K zwd>|B7G9s#a~C^eCk4Li!2kmxDzn-WW`h?2C97pmy#UiS&AA6L!`FS9fiu1wD?`8j zl%Mq{)+yIPkVq-7ejZ$E6qKX6w8wiPR(%8T4L`M%?sj-sn8yEFG_qF_8X$)0E?~!< zxl+rNc-B=r8k#)dZrYwm$==gh<~cODaC0v3MpXx3a0^Y_kHmr z4S2Xh520QsTtk@z=V04rvJ!U}?z8Jt64bOjdZrb}6n|dXrsu$H3CJZ{G@M}?Pw05s z)HFhlBp%DW4m5THCyN$g^Z@2lb-RQkw@rkFy_hG7d<;#+U&JV$M~A$Jo*`1qh+cD^ z5U%x5)qY`@;0+^L&VWY@_@hTdw-cNtznQs~rkQ(vS-NbR?$Xyk0z%j86Ixz3X5^$S zYMf!A?LXZ-i0?Y}L@=zJ*S1UevP(Cyfmb;dM&Z9&uxfIND02e>#L{X_MR{_8=M59WT6_SQ==*ROY$AHDtUwME-@*vm7s&?~1az|A`Ua*1uYHYXHONeQ@#{#nCXjn?*7#ZZ~p)4sKAPGJG^ z8H|9!8(<61>W;`9QL}#~koIWEA?AUXBk?9nIo)`RKk#{{ae4m6E~Y)SOLC5DJ(=g{ zG>Ass_;}`=v^Ku9y}T@~;K2pS%eJ=IZGvl7JG3@8SXdKdm3f444*NE9)jaF%Iqfr> z@D8ADn(JQ}cX(oQ#sKza?)qFBjpj^0P`zk~PETrs*rrKWrbXJN&%``9q#5=EsW_Qz z{52W)YtbN!hew^Ckg_APX%S;Pe1GFRpoQ`VN?A{ANh5G0$|p&)b+*wxt7!06PokXI z-{YfvMNY@{&UOkE%oYEZ|C4>$L`@Q7Ay50A4zF!vgg3rDV8Hn7!1#Pe10QdLLm_X> zEEMNBv9J2q6{X7-^DR$b$P%kuzG4tpR!JK%Mp?2d;~*n;11ABOOtH3vaC0M6XLfIZ|#&JeJe2KEM>5pk}X zUn3)LU=fr(y>#*e2X^-1z6xaaIDViM!WwrL=H`rF%UiaHM{M8gN5=FanEr&tkBURr z*Q)pu)r<Q3voG!Ivv$RW6v8KWyf!OP zFQ7Yl&UOJSH=aUHNhg#x6`)<|t<=8x0}iY<|Eh0WK$>qPV4aYZD{mb3qdvRD1Q`=b zWK9@^9kyzm0a5`iE}gl9{wtqbGjzL&&@pYRexVPAwH01;UfRoV&O% zBkW8{bR5w#aa9ioilrJmE{IK=1W1!k+8DHR1)!oz&in`x%m>zrYdJ~14Wzs9HYzNNg~nyo)(r=5@Jdm_Y%{qhEvIOLp|Q85>FYH;mca-6M8=abnvCc{Tl zQh5})4meEFTqLBPxYgEWfI*TbbzCt|MZQj~05bVQf;*P&iuI;^7`4cT(k2f(xKw%v z1<7{;+Kdk5j%(ZLg}& zv#4af?lFrM_3l%^W-Ux|+JGf-Q&y)FFqt5L;rF=hJvtNoVkvW`ZKG6%0IC+jYZ!pg zj7V25VXt&TaUjzu)_R*&`}}xHkV4oZ^??GVs?6{QG0a}0JHuv1BHkX)fy+re&V+bW z7`STdHq1_Eb8cq9oKX@bQ$p!hS&x+0Fcf*=&Sp!F3Ths_U~QWjVnO;F<$-SvFgJ+j z#&G#(C>SG_su~{IVWslWQoWJhCx|NuACgz#YHU1PLa^`3^x|V1d!rFXLA?!S>RmlLxRiSGQV^M zi=6d{DYlpTbIvk(Ir}ou!j`f^OvNz~PENy33Iro}UJzfgc!aadEas}3RLp}m5cBvt zpr44TH&>rEcR0FpJD?++6o8nAA-K)?s=^;qH#pD8+$wghgS7LqXZIonn6?L4>bd>> zc)d^0FleoM`0|)2r!IBsVTUWy;hwS$taIHZSgg{2?vz&nQZ^|=S980Iu1hFotQ4Rv z@|rlxEb7uXRVaq6tn3fVncqTC)xW6U+bZrBm@vwPOx~$^{PJijl40PpaIkQx%$^|_ zsx0?fW>qLYIrU23DK)ADunYgD{fzdnSx|dul3iU8Dsw~dQ!EZULrH$RX*Twi#VDZ% zjhS71q`fM+K;NmpbN}#4u00We1&9dtl-(it7ETx);MEHd8I`xg1+S%Qe8B=RXwB`y ztsM>2v_eQF_G`<#QhQ^|W^&>&Dv3pB>3o3`T=xvLyA!SDzI?lYz@-C2HfrC}iQPS? z3SX>iwO7X;sSF>D9wqiRqa&zOhfC1GC@yld6qIGQ^^CK`d;1X4^$<~OLm5*;YW!8S zeC;jR{EsGfGRy_j&ooQZ#uz!!N<@wlkDYi7BzMxNum?f=g@muUpsB7e+a>J5kJV z_D`|fnfOfjY+QVF!D@0%R68(9gA?)QFXh%2Ii%(bZ+df^dBXKNvF^}i0|V4XI9E2@ zh7Jz67{ZJbUB_9t$21rErZ=%Vx857qc+F%{U3Xi2+pr>lH3AL{_9!~Rep($pj18r@ zoCTZlkY%ba;W_)^d^~2ul)32T5xVknfi`vL0(^c+1wt~ptm#=3cA~3tXx888VLsJn zgX$~lc$npNh>f%#$wZj!f(3UZ{_6Xq>i+upfHbH&4W!a(-o>RiieDA{(oU7W!MVz> zGG2H=v!|tipg+Q$C~^{ceJ3=RGoy6Ql6{N@J|`Y-Qis%{{F5p4Dz7#>Wa>F8uhc@7 zH_z%{JpuKe_Ep8yp}OvH&~mG;`8oThj7vCNc4DZ0Ldq{Z$+;(BXJrIx!~0X$4N81w zw7q>yk?Kq`_jk~678U%-M*9NP)I&t5a9;>YG38x?Inlva%1T+n zBKFG{WF0BUSs{PW=~-Y($qu3w@qTyfP9<8)o5t=jVX$Oo#6u@}7Vw5{C>{~rUBG@z z9}(T-(S8T-4r$k_K~{WVeybm~z7j0u)ilS+_MYU@eEdw_#c=xw+LhDumX9g9W7;?S zN;b9vj96P$;i+^fOe>DBiyeeL4>PO5~lWSX=pOD>jVaIj50=>m2k3onP09ZSDK6k8NJftSQ)B)N~|=%0I6AZAOm zl@OG=g58zZputK-IOO89o+D@#{Fs{DqQCqCELqG-S7tZ4{(VeSlFPO@*GHn{Y^cZb zAWyh8(^L=$20|0KjPBdlC_BGV>6`EM!9O~Dni9+b0w?>sF2T7-fcgtq3n+vp{eN0C zEEMLb*U?t!X#jKkeM?x15qk^_K)l2VGB%)}T$ zv@Z4x|L4%Nfw2lm_Ia~5f2bFY1P&(We3~ok1#SjpFY{TK zqx`&}x%U-!LaMBc%g*}XL;qE}0%MyN7)ir%^matzqK@XFjkaoIe;!Su#rLYE zlT!pXv_{yeQ~jT>1$^0+YkPG7ywR;f8`kxh6!pG@Hf)YotaO9Y#j@Oq zaO%_`HwXh6d98iAu$mH49=*eEWyFmqG%54I^`oMCu#iey9^JlZ$~<8HhF^EA1}GH@rW zxfpDkU)Bq$r<3AOnPWpwnbOH-y%G9^5B?!Nk%S4y&=Au7KP`qq6ttsC@`^uPaN|-V zns@Sk1;E<)JASF4j14%F`(vI4oIqy~x z`sdz(XO(-4)wQOmcHU4LkR)d{zj{Wg3^Qlif%Eie?7*`v+A7v~Hg}KMf!26D2mc1S zJR`ozh zP88nTz--GsCm1CGX3`#cJBTDjhm4oO9*B$5ggdQ;2m*BAXhe1gV41ANPf6Z5r#eve zk^U{(6WKRJKP<-y&YQspX;@|@6Y;ziRm9HY7Igs;D`sDI_weIpj1=$Ok_JvCiwhLc z4!T&=Ce(6sBilCHhq@D(ikW=$0Dc`1)_F?eMu@q;puXOKazajQNN+jGMNB+w`(A<| z3D-JT1OeH&z@5WW4F@{uS(69zi+`5{n(UlVh+sRjWjJ*sLmp|4<{es*&ksIp6p(sj zxqZ=L%8MzVYKL}>YKNXYE%owgza&h!oD|QvxrP0-Y%{(iS>~>cJCryeN`i>^ zVLI}ce)ui`g`Rh23aN;6#aej_>iMDT&sUx-vWwP4 z8um~41d+H~i~lrDpSh=?d|~-=j7eLphqBTtvZn_)#Sc$Lyiv{j^yibNQiBi>ldAWp zb^fY~={UPNd%j7b8?ZpHl6##;vOVa|ihj<@89aUMao8Z*yXNuUktzKkZ2Ob{O-6if z|0hyROnpmJrOh>dMrV>i%*`?L+NQ$p9=#^$0`_8``=vJDJsvmvqXqXBp@#1ok(U5Q z5vKsa!K|sa{|feiK&AnMi?x&w=( z0Eswm?4IQh3Y0yT8p}qf$)}HT{d?WnRvZohX@OMSkKwphbgGqXzz5}ImAJ=ASpHgU zh(Cau8-y3BeE|C-x@H&0;nY5V-ThcHxADRv1ZAI}5+R*e@_RF7QZ1Bf|3e7H{ z=Q+?Sli|v{P#1Ytvghp757J6GPOAA51|$VdTVQzbs~_gqK2~MvL@4Yvx#AfnvtfZ6 z{r;1T@CR|?5r69{LA!qmVo;R(_L~$Q@PMk_9c}ChLFt1*bIC#ek!nMNj+Kx3+W^M0 zTdp@??GS}9aZW({C*;((oZcS`oSzJZM(f8D36)<Wsolk3KZ9`JMhij<-9q` z1@JuElT4zs5x2-%)#|NPX^2!#S%q2h9;QkD$%O?R$VMQ~8bnxCK)|~flA+%q0pqA` zRL_gtP%q^woqLYnhVCGXuB4=cCZ(ze`L?UNMWrJVPxE!HKn^#Z| zcxxVfE$h3c%|$QWIDCI0srQ}R zp!B#nlWk;5B<&KagIxEog_jB1&cxGgz~wB67*PQ?Pe=GWR?|14#doCYaj){sCqlv3 zFGy(O43v6sTY@?X`an~n4WCVWpV21}%HfAu55ehh?Y+|8fDSTKvSZI1fcgYoUH)sB z97?W&bH_CEANhQM0*m_Tt}3Srae;kFdN;(-x9oQUYyvL7g=P&o<*$VbwtkYB;cpm& zQO2k2t%Kfv;hBRCb<~^nqp){dsxd#DYTsDRynCUCUPresD5Zp%@A+LdOGBg!>5ALI zsj@JEFnt;xi6|klaU|IpA;-UA+1cA$N~4m0k0JcmA`G_E4`+^n+g?^Fe1RAtZ40Tfsj?@BKClKu7J50sb zrDaVpUe-_)4#*j7HR3`>&LYF_e)n1KeEwe;LLqSii+M-ZZ<$;u|)BY5STzwiG zFsLmfpvk*cwvmy~79B>G?sp^{k&4lcKD$v;k}B;!Q0y($j8R>MiBsZTr30a6r-M(A z{Z^w{kq*v-E(p^CwoziL8ytnUU(0J2y1se=Y?*ic_YS3GUBHA>fW>y~oa3g9BIra_ zV6|=0jIE_v7XLGp#j3?Y4MVRW<6S@qaHKiP=uoZAsIcIP2kl;au>LvZ7FNzqAzqI_ z7`+BRa*h&%NAO$S!78073wS!?L6kLke!JhkQk~&8=q8ua)|>1t;y{Xii(tW3nd~;~ z(eQqVcfVe`IY!f8^Mo+A-kz|l1?NF}fT=QZp6d0pn6L2a=m20aV5r69Rq;=L_|zyl zO<(qlBWJ)GfaMpsnRv@di7lzLk$lToVlic`J7k7)Erybisv@j1LT{u}PggLc^(1c1 z`gAKUt|JN20WBtpu{*)sU)#rk!)Xg2?-ForzT`5Nd5tsUHcUqrNv&M%5ujQ{~*$-$#S;Lv)WqEc|i%*^4kcbSREFI%@_HS^?OX6&#&BJfaP4pt(d}- zC-s@zEENy-UkWVC)9+!Pn>gqZCxPbcIeJBbZH1TP+~1#~U`UkZk9-5fC4JY`g#q_% zAkd&p2#P|B=T=@yyw@f*7EQ7nhUZL@e!cyThuKbjncFC3XblK2E2ao9tETK2c-U)S zt9Bru%|LLs$et4v(m4EnfZL)jS|A(jd|bi~v_>BDm1UP_Jm&KkmDjUcZj@^;0z4-% zfl0W@=K_j(Xl|Y8Z#HGedi!Ve;uN5hJib7?M*o zLarN4yR&PodaFPE7kNFxNkMDSC}?m)17SmAkvCV!4N}2TQg!0t7MRGzPSJBA&KRlI zjK=WK)DWrJFRoWFt`AQ4U}2B=I-Rn&26iWba+or%*(0Dbj(cQby_tnH|AgWwC&tP2 zu9*wI>`$nN2;jMoQw~6#@+%$Dh9jK;2GQ-a(Z#z57D1P{C85Sy`y_N&R(q`$Sx^uV za0sA7pbCiyx&WIm{hnz;%Ztu%WC~Mf@tY}ejI60Bxvl8p^AE@@;C>();F=y!9u5*s zEY0U+ru}3_;Mdbht<&xg_8WdMFeO&$Gm1cg?j!_tw>H~6$G!4Ezff~I9$IeG@MJnF z_}dn~BzQc7qp@F$GDhB`1x{+@yY5f}f+#r)@6^~xg0#8&B6=?khc64a8hJAoOgBkv zj-5cZ{fNFt?5Ws8=~@Rkz;0^NO~-||ncZbXK0|e2HT{5MFx!%b5cF)Sp$)=6um?Ms zuVcip-G_E2!~)LBemY_LNV-^z=dVtlerf)@4k&#rQh8%OZVa~e3GDm(S2;fT^ijCw zNiHHInv~UBkx8Gauykw7tEAd&!2^?UsGCv@0g8MxYIU!HJ1+Gm;El}4uKk^?VB%q` zoGacbiO|uce5*&1HKCsa4az!=8=NM+Q`W*1O%F1MrR!st#mF?5YpAZdf-H3V(U!$t zGVXZoDw<#w*daLh6bV%Xm0_5N6M1negZf*LYoY*&8L`H_AX|nniXMR|;#}*7>5sFy zjlwyx(gE-5F@697;7@)oj0`qK95ew{X6-T)GT+8)^w5m_`|WxVO)Uz42)Pp3ARBW# zPJ`x2I!fhJiwZQ|kqeMt@fWiTTr0|CcR|Llf($2=LZbNU6@Oxt(r<{w#$+s}nZPJi zovq>SI&nPaGP=Lx>bwds zwv*Zogg88&lSKeAJW7@+CKhu#$*mdAH2s@_G=YES`kj!8prh3D*o?lvEoxd z4*k%noqDS^&2dM3yV&D(#NVnd^xHJ)85ifl+7)Yx2Gx8U`Q?=yi^?#Yb5&x5$H3#Z z4mK}f;TZAq2LZ%ed}j#p4gCn&oy9?uUwa=j%Jp0j(}DpW0P-2P4Bv(-!`4>QpxQgu zWH~A@hFGng^Khp>!SFsZ8`mFpe{;aSVs3;10!AJ2#jRe44&7^+@*33qvMho|noli0dNVQhl!80VDXRuaG{@>|4aR-@o@ z9zknLDrUHO9`>Y04aj5`*yGgA&hPi&j!truQn(EQxKh`(sfo`L47>Ra{^R$<-ve2X z5R$}XkN^{Y@LXY9mD7*xvBajDsVowgAGdIPQg>7xj3iex9%U=Ta78aYK91u2zkN3% zSE9hNSg7Z+!TaMn@R`F@+8?0fK7mzxFfv>BJUOP(zNM$8hvX6I4!qlqH*Q4ZqFvHT zv-$;A$|*T))TIep_(%cO#y0ZEJom*iiNWwM*dar9O|T|2+HNxqKk_8f$OrJ((Z=3i zY^Gi==n3a|MZDzIXd05%v6@JMq%pEW4JvOU<=VriMvd6Xf5Bn8suWlg{>|~MvkZ!)RISsM2Y?#YRrKcz+#E>%`Lo|EGLefN;?d zx#F-8oHE{0+Tdim&SlW1L$!(lfH~;N)QnB|)C-e=z3GbEZ}JjqjcfUq-Onl@`djh< zQ$PnnA4aazWFy_&Mi<$r4g6akaTK~5jCM>-Iw98@%o*=c`KQF4c$g50q>FK>b70!j zkB%o4U3;I~>+Oydf!{3o*<>?%>pzcjNNSpUM13Y1QJ9du^OkLVbHBv;08%Vdqwz-Oul(i zi%HrSDkMBv_mmcsdkC1DcgmefJrc}3bIOI0d9vW?P$q%Y$-1eklY38VG3HO+aoUDy zUh3rCsm7D}uL{T@dV@e8AiIM>GXtnd64*CX0V$lk=!_K8qnyc&c`}o4opEHU$OAI9 z!7>qNrI>EyPkxxMG1=jYz~nVR?z+;+g^kLSU!OH(npFm79xIcY9DPoU$)F0%jj0lv zya&itsReTbYNdg)0@8?g^ZH7CdP zi%qt>EFc4~`GMPW%u)2~P68{`zi7qeKNZZ3ohk^@GkNPpDMp{k7cRQVz{^xt1_oOc z-TJeDTJ$F;Ub146o(p!uflJm*Mf1T-h07jH8x{eXN|Spo8!$#s-g`Ni$$0N%y{$@< zHTLoV14WC;^1$SrD``x;hbBKbXblWCEyf3vt*+`R0P~3#JZ}K41TNb~0)|H>cU;wC J>pB7w0|0?!;G+Nl diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 01c15363e1..1b1cd98009 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Jul 07 15:13:06 PDT 2017 +#Tue Jul 11 16:36:46 PDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.0.1-bin.zip diff --git a/gradlew b/gradlew index 4453ccea33..cccdd3d517 100755 --- a/gradlew +++ b/gradlew @@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -155,7 +155,7 @@ if $cygwin ; then fi # Escape application args -save ( ) { +save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } From 82f859b02808c34a0c94fb5860509d362f021cdc Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 14 Jul 2017 21:50:37 +0200 Subject: [PATCH 0295/1581] Introduce a new property "findBugsVersion" and use it consistently. This property contains the version of the FindBugs tool and the FindBugs JSR 305 jar. --- build.gradle | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 31956b3659..f584bd377e 100644 --- a/build.gradle +++ b/build.gradle @@ -101,6 +101,7 @@ subprojects { autoValueVersion = '1.4' guavaVersion = '19.0' grpcContextVersion = '1.4.0' + findBugsVersion = '3.0.1' libraries = [ auto_value : "com.google.auto.value:auto-value:${autoValueVersion}", @@ -108,7 +109,7 @@ subprojects { errorprone : 'com.google.errorprone:error_prone_annotations:2.0.11', grpc_context : "io.grpc:grpc-context:${grpcContextVersion}", guava : "com.google.guava:guava:${guavaVersion}", - jsr305 : 'com.google.code.findbugs:jsr305:3.0.0', + jsr305 : "com.google.code.findbugs:jsr305:${findBugsVersion}", // Test dependencies. guava_testlib : "com.google.guava:guava-testlib:${guavaVersion}", @@ -135,7 +136,7 @@ subprojects { } findbugs { - toolVersion = '3.0.1' + toolVersion = findBugsVersion ignoreFailures = false // bug free or it doesn't ship! effort = 'max' reportLevel = 'low' // low = sensitive to even minor mistakes From e7e8c65279a019a574fa740c91d0b1f003f242ee Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 14 Jul 2017 21:58:44 +0200 Subject: [PATCH 0296/1581] Sort extra properties by name. Libraries are sorted, too. --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index f584bd377e..5142e49073 100644 --- a/build.gradle +++ b/build.gradle @@ -99,9 +99,9 @@ subprojects { ext { autoValueVersion = '1.4' - guavaVersion = '19.0' - grpcContextVersion = '1.4.0' findBugsVersion = '3.0.1' + grpcContextVersion = '1.4.0' + guavaVersion = '19.0' libraries = [ auto_value : "com.google.auto.value:auto-value:${autoValueVersion}", From f8fb83b1a3f49bd57d6ef5dbbe142388ce26494a Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 4 Jul 2017 02:40:15 +0200 Subject: [PATCH 0297/1581] Add automatic context propagation for Executors. This change adds the required plumbing for accessing/manipulating the context from the instrumented code. This completes the underlying infrastructure for the executor instrumentation, which is also included in this change. --- contrib/agent/README.md | 6 + contrib/agent/build.gradle | 9 ++ .../opencensus/contrib/agent/AgentMain.java | 39 ++++- .../agent/ExecutorInstrumentation.java | 66 ++++++++ .../contrib/agent/GrpcContextStrategy.java | 29 ++++ .../agent/bootstrap/ContextManager.java | 54 +++++++ .../agent/bootstrap/ContextStrategy.java | 29 ++++ .../contrib/agent/bootstrap/package-info.java | 3 + .../agent/ExecutorInstrumentationTest.java | 148 ++++++++++++++++++ 9 files changed, 382 insertions(+), 1 deletion(-) create mode 100644 contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java create mode 100644 contrib/agent/src/main/java/io/opencensus/contrib/agent/GrpcContextStrategy.java create mode 100644 contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java create mode 100644 contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextStrategy.java create mode 100644 contrib/agent/src/test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java diff --git a/contrib/agent/README.md b/contrib/agent/README.md index 787a2c250d..90abb8cf66 100644 --- a/contrib/agent/README.md +++ b/contrib/agent/README.md @@ -14,6 +14,12 @@ currently implemented: TODO(stschmidt): Update README.md along with implementation. +### Automatic context propagation for Executors + +The context of the caller of [Executor#execute](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-) +is automatically propagated to the submitted Runnable. + + ## Design Ideas We see tracing as a cross-cutting concern which the *OpenCensus Agent for Java* weaves into diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index a1b7599059..a90cf0a63e 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -30,6 +30,9 @@ def agentBootstrapClasses = agentBootstrapPackageDir + '**' def agentRepackaged = "${agentPackage}.deps" dependencies { + compileOnly libraries.grpc_context + testCompile libraries.grpc_context + compile group: 'com.google.code.findbugs', name: 'annotations', version: '3.0.1u2' compile libraries.guava compile group: 'net.bytebuddy', name: 'byte-buddy', version: '1.7.1' @@ -119,3 +122,9 @@ shadowJar { jar.finalizedBy shadowJar // TODO(stschmidt): Proguard-shrink the agent JAR. + +// TODO(stschmidt): Move the integration tests to a separate SourceSet once +// https://github.com/johnrengelman/shadow/issues/297 is fixed. +test { + jvmArgs "-javaagent:${shadowJar.archivePath}" +} diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index 1d612f782a..edf9fc5e33 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -14,8 +14,11 @@ package io.opencensus.contrib.agent; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; import static net.bytebuddy.matcher.ElementMatchers.none; +import io.opencensus.contrib.agent.bootstrap.ContextManager; +import io.opencensus.contrib.agent.bootstrap.ContextStrategy; import java.lang.instrument.Instrumentation; import java.util.jar.JarFile; import java.util.logging.Logger; @@ -62,14 +65,48 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th instrumentation.appendToBootstrapClassLoaderSearch( new JarFile(Resources.getResourceAsTempFile("bootstrap.jar"))); + assertIsLoadedByBootstrapClassloader(ContextManager.class); + assertIsLoadedByBootstrapClassloader(ContextStrategy.class); + AgentBuilder agentBuilder = new AgentBuilder.Default() .disableClassFormatChanges() .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) .with(new AgentBuilderListener()) .ignore(none()); - // TODO(stschmidt): Add instrumentation for context propagation. + agentBuilder = LazyLoaded.addGrpcContextPropagation(agentBuilder); + // TODO: Add more instrumentation, potentially introducing a plugin mechanism. agentBuilder.installOn(instrumentation); logger.info("Initialized."); } + + private static void assertIsLoadedByBootstrapClassloader(Class clazz) { + checkNotNull(clazz, "clazz"); + + checkState(clazz.getClassLoader() == null, + "%s must be loaded by the bootstrap classloader", + clazz); + } + + private static class LazyLoaded { + + /** + * Adds automatic context propagation. + */ + static AgentBuilder addGrpcContextPropagation(AgentBuilder agentBuilder) { + checkNotNull(agentBuilder, "agentBuilder"); + + // TODO(stschmidt): Gracefully handle the case of missing io.grpc.Context at runtime. + + ContextManager.setContextHandler(new GrpcContextStrategy()); + + agentBuilder = agentBuilder + .type(ExecutorInstrumentation.matcher()) + .transform(ExecutorInstrumentation.transformer()); + + // TODO(stschmidt): Add instrumentation for {@link Thread}. + + return agentBuilder; + } + } } diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java new file mode 100644 index 0000000000..06fedbb6e8 --- /dev/null +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java @@ -0,0 +1,66 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent; + +import static net.bytebuddy.matcher.ElementMatchers.isAbstract; +import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.not; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import io.opencensus.contrib.agent.bootstrap.ContextManager; +import java.util.concurrent.Executor; +import net.bytebuddy.agent.builder.AgentBuilder; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.dynamic.DynamicType; +import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.utility.JavaModule; + +/** + * Propagates the context of the caller of {@link Executor#execute} to the submitted + * {@link Runnable}, just like the Microsoft .Net Framework propagates the System.Threading.ExecutionContext. + */ +final class ExecutorInstrumentation { + + private static class Transformer implements AgentBuilder.Transformer { + + @Override + public DynamicType.Builder transform(DynamicType.Builder builder, + TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) { + return builder.visit(Advice.to(Execute.class).on(named("execute"))); + } + } + + static ElementMatcher.Junction matcher() { + // TODO(stschmidt): Exclude known call sites that already propagate the context. + + return isSubTypeOf(Executor.class).and(not(isAbstract())); + } + + static AgentBuilder.Transformer transformer() { + return new Transformer(); + } + + private static class Execute { + + @Advice.OnMethodEnter + @SuppressWarnings(value = "UnusedAssignment") + @SuppressFBWarnings(value = {"DLS_DEAD_LOCAL_STORE", "UPM_UNCALLED_PRIVATE_METHOD",}) + private static void enter(@Advice.Argument(value = 0, readOnly = false) Runnable runnable) { + runnable = ContextManager.wrapInCurrentContext(runnable); + } + } +} diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/GrpcContextStrategy.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/GrpcContextStrategy.java new file mode 100644 index 0000000000..b7503894d7 --- /dev/null +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/GrpcContextStrategy.java @@ -0,0 +1,29 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent; + +import io.grpc.Context; +import io.opencensus.contrib.agent.bootstrap.ContextStrategy; + +/** + * Implementation of {@link ContextStrategy} for accessing and manipulating the + * {@link io.grpc.Context}. + */ +final class GrpcContextStrategy implements ContextStrategy { + + @Override + public Runnable wrapInCurrentContext(Runnable runnable) { + return Context.current().wrap(runnable); + } +} diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java new file mode 100644 index 0000000000..ad8d19d8b7 --- /dev/null +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java @@ -0,0 +1,54 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent.bootstrap; + +/** + * {@code ContextManager} provides methods for accessing and manipulating the context from + * instrumented bytecode. + * + *

{@code ContextManager} avoids tight coupling with the concrete implementation of the context + * (such as {@link io.grpc.Context}) by accessing and manipulating the context through the + * {@link ContextStrategy} interface. + * + *

Both {@link ContextManager} and {@link ContextStrategy} are loaded by the bootstrap + * classloader so that they can be used from classes loaded by the bootstrap classloader. + * A concrete implementations of {@link ContextStrategy} will be loaded by the system classloader. + * This allows for using the same context implementation as the instrumented application. + */ +public final class ContextManager { + + private static ContextStrategy contextStrategy; + + /** + * Sets the concrete strategy for accessing and manipulating the context. + * + *

Must be called before any other method in this class. + * + * @param contextStrategy the concrete strategy for accessing and manipulating the context + */ + public static void setContextHandler(ContextStrategy contextStrategy) { + if (contextStrategy == null) { + throw new NullPointerException("contextStrategy"); + } + + ContextManager.contextStrategy = contextStrategy; + } + + /** + * @see ContextStrategy#wrapInCurrentContext(java.lang.Runnable) + */ + public static Runnable wrapInCurrentContext(Runnable runnable) { + return contextStrategy.wrapInCurrentContext(runnable); + } +} diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextStrategy.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextStrategy.java new file mode 100644 index 0000000000..1ab5154c07 --- /dev/null +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextStrategy.java @@ -0,0 +1,29 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent.bootstrap; + +/** + * Strategy interface for accessing and manipulating the context. + */ +public interface ContextStrategy { + + /** + * Wraps a {@link Runnable} so that it executes with the context that is associated with the + * current scope. + * + * @param runnable a {@link Runnable} object + * @return the wrapped {@link Runnable} object + */ + Runnable wrapInCurrentContext(Runnable runnable); +} diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/package-info.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/package-info.java index 748c7f78fc..af6ec4f350 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/package-info.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/package-info.java @@ -16,4 +16,7 @@ /** * Contains classes that need to be loaded by the bootstrap classloader because they are used from * classes loaded by the bootstrap classloader. + * + *

NB: Do not add direct dependencies on classes that are not loaded by the bootstrap + * classloader. Keep this package small. */ diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java new file mode 100644 index 0000000000..bcd9ca71c2 --- /dev/null +++ b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java @@ -0,0 +1,148 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent; + +import static com.google.common.truth.Truth.assertThat; + +import io.grpc.Context; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Integration tests for {@link ExecutorInstrumentation}. + */ +@RunWith(JUnit4.class) +public class ExecutorInstrumentationTest { + + private static final Context.Key KEY = Context.key("mykey"); + + private ExecutorService executor; + private Context previousContext; + + @Before + public void beforeMethod() { + executor = Executors.newCachedThreadPool(); + } + + @After + public void afterMethod() { + Context.current().detach(previousContext); + executor.shutdown(); + } + + @Test(timeout = 5000) + public void execute() throws Exception { + final Thread callerThread = Thread.currentThread(); + final Context context = Context.current().withValue(KEY, "myvalue"); + previousContext = context.attach(); + + final AtomicBoolean tested = new AtomicBoolean(false); + + executor.execute(new Runnable() { + @Override + public void run() { + assertThat(Thread.currentThread()).isNotSameAs(callerThread); + assertThat(Context.current()).isSameAs(context); + assertThat(KEY.get()).isEqualTo("myvalue"); + tested.set(true); + + synchronized (tested) { + tested.notify(); + } + } + }); + + synchronized (tested) { + tested.wait(); + } + + assertThat(tested.get()).isTrue(); + } + + @Test(timeout = 5000) + public void submit_Callable() throws Exception { + final Thread callerThread = Thread.currentThread(); + final Context context = Context.current().withValue(KEY, "myvalue"); + previousContext = context.attach(); + + final AtomicBoolean tested = new AtomicBoolean(false); + + executor.submit(new Callable() { + @Override + public Void call() throws Exception { + assertThat(Thread.currentThread()).isNotSameAs(callerThread); + assertThat(Context.current()).isSameAs(context); + assertThat(KEY.get()).isEqualTo("myvalue"); + tested.set(true); + + return null; + } + }).get(); + + assertThat(tested.get()).isTrue(); + } + + @Test(timeout = 5000) + public void submit_Runnable() throws Exception { + final Thread callerThread = Thread.currentThread(); + final Context context = Context.current().withValue(KEY, "myvalue"); + previousContext = context.attach(); + + final AtomicBoolean tested = new AtomicBoolean(false); + + executor.submit(new Runnable() { + @Override + public void run() { + assertThat(Thread.currentThread()).isNotSameAs(callerThread); + assertThat(Context.current()).isSameAs(context); + assertThat(KEY.get()).isEqualTo("myvalue"); + tested.set(true); + } + }).get(); + + assertThat(tested.get()).isTrue(); + } + + @Test(timeout = 5000) + public void submit_RunnableWithResult() throws Exception { + final Thread callerThread = Thread.currentThread(); + final Context context = Context.current().withValue(KEY, "myvalue"); + previousContext = context.attach(); + + final AtomicBoolean tested = new AtomicBoolean(false); + Object result = new Object(); + + Future future = executor.submit(new Runnable() { + @Override + public void run() { + assertThat(Thread.currentThread()).isNotSameAs(callerThread); + assertThat(Context.current()).isNotSameAs(Context.ROOT); + assertThat(Context.current()).isSameAs(context); + assertThat(KEY.get()).isEqualTo("myvalue"); + tested.set(true); + } + }, result); + + assertThat(future.get()).isSameAs(result); + assertThat(tested.get()).isTrue(); + } +} From cbabb08dea87c67868e9531ff2c068f41b1bfb3a Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 4 Jul 2017 16:21:05 +0200 Subject: [PATCH 0298/1581] Refined/added comments and Javadoc in response to review comments. Also, minor cleanup of some oversights (missing Javadoc tags, method naming, private constructor for singleton, etc.) --- .../opencensus/contrib/agent/AgentMain.java | 16 +++++------- .../agent/ExecutorInstrumentation.java | 9 +++++++ .../agent/bootstrap/ContextManager.java | 26 ++++++++++++++++--- .../agent/ExecutorInstrumentationTest.java | 3 +++ 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index edf9fc5e33..3e079e3f71 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -65,8 +65,8 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th instrumentation.appendToBootstrapClassLoaderSearch( new JarFile(Resources.getResourceAsTempFile("bootstrap.jar"))); - assertIsLoadedByBootstrapClassloader(ContextManager.class); - assertIsLoadedByBootstrapClassloader(ContextStrategy.class); + checkLoadedByBootstrapClassloader(ContextManager.class); + checkLoadedByBootstrapClassloader(ContextStrategy.class); AgentBuilder agentBuilder = new AgentBuilder.Default() .disableClassFormatChanges() @@ -80,9 +80,7 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th logger.info("Initialized."); } - private static void assertIsLoadedByBootstrapClassloader(Class clazz) { - checkNotNull(clazz, "clazz"); - + private static void checkLoadedByBootstrapClassloader(Class clazz) { checkState(clazz.getClassLoader() == null, "%s must be loaded by the bootstrap classloader", clazz); @@ -94,17 +92,17 @@ private static class LazyLoaded { * Adds automatic context propagation. */ static AgentBuilder addGrpcContextPropagation(AgentBuilder agentBuilder) { - checkNotNull(agentBuilder, "agentBuilder"); - // TODO(stschmidt): Gracefully handle the case of missing io.grpc.Context at runtime. - ContextManager.setContextHandler(new GrpcContextStrategy()); + // Initialize the ContextManager singleton with the concrete GrpcContextStrategy. + ContextManager.setContextStrategy(new GrpcContextStrategy()); + // Add automatic context propagation to Executor#execute. agentBuilder = agentBuilder .type(ExecutorInstrumentation.matcher()) .transform(ExecutorInstrumentation.transformer()); - // TODO(stschmidt): Add instrumentation for {@link Thread}. + // TODO(stschmidt): Add automatic context propagation to Thread#start. return agentBuilder; } diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java index 06fedbb6e8..62a9ef649c 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java @@ -56,6 +56,15 @@ static AgentBuilder.Transformer transformer() { private static class Execute { + /** + * Wraps a {@link Runnable} so that it executes with the context that is associated with the + * current scope. + * + *

NB: This method is never called as is. Instead, Byte Buddy copies the method's bytecode + * into Executor#execute. + * + * @see Advice + */ @Advice.OnMethodEnter @SuppressWarnings(value = "UnusedAssignment") @SuppressFBWarnings(value = {"DLS_DEAD_LOCAL_STORE", "UPM_UNCALLED_PRIVATE_METHOD",}) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java index ad8d19d8b7..75ffe76ae1 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java @@ -25,19 +25,33 @@ * classloader so that they can be used from classes loaded by the bootstrap classloader. * A concrete implementations of {@link ContextStrategy} will be loaded by the system classloader. * This allows for using the same context implementation as the instrumented application. + * + *

{@code ContextManager} is implemented as a static class to allow for easy and fast use from + * instrumented bytecode. We cannot use dependency injection for the instrumented bytecode. */ public final class ContextManager { + // Not synchronized to avoid any synchronization costs after initialization. + // The agent is responsible to initialize this once (through #setContextStrategy) before any other + // method of this class is called. private static ContextStrategy contextStrategy; + private ContextManager() { + } + /** * Sets the concrete strategy for accessing and manipulating the context. * - *

Must be called before any other method in this class. + *

NB: The agent is responsible to set the context strategy once before any other method of + * this class is called. * * @param contextStrategy the concrete strategy for accessing and manipulating the context */ - public static void setContextHandler(ContextStrategy contextStrategy) { + public static void setContextStrategy(ContextStrategy contextStrategy) { + if (ContextManager.contextStrategy != null) { + throw new IllegalStateException("contextStrategy was already set"); + } + if (contextStrategy == null) { throw new NullPointerException("contextStrategy"); } @@ -46,7 +60,13 @@ public static void setContextHandler(ContextStrategy contextStrategy) { } /** - * @see ContextStrategy#wrapInCurrentContext(java.lang.Runnable) + * Wraps a {@link Runnable} so that it executes with the context that is associated with the + * current scope. + * + * @param runnable a {@link Runnable} object + * @return the wrapped {@link Runnable} object + * + * @see ContextStrategy#wrapInCurrentContext */ public static Runnable wrapInCurrentContext(Runnable runnable) { return contextStrategy.wrapInCurrentContext(runnable); diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java index bcd9ca71c2..563ae120e5 100644 --- a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java +++ b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java @@ -29,6 +29,9 @@ /** * Integration tests for {@link ExecutorInstrumentation}. + * + *

The integration tests are executed in a separate JVM that has the OpenCensus agent enabled + * via the {@code -javaagent} command line option. */ @RunWith(JUnit4.class) public class ExecutorInstrumentationTest { From 54b541290925c00e72fa73e7b041a91d690b574a Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 4 Jul 2017 16:24:47 +0200 Subject: [PATCH 0299/1581] ContextManager just a static class, not a singleton. --- .../src/main/java/io/opencensus/contrib/agent/AgentMain.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index 3e079e3f71..56a4021349 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -94,7 +94,7 @@ private static class LazyLoaded { static AgentBuilder addGrpcContextPropagation(AgentBuilder agentBuilder) { // TODO(stschmidt): Gracefully handle the case of missing io.grpc.Context at runtime. - // Initialize the ContextManager singleton with the concrete GrpcContextStrategy. + // Initialize the ContextManager with the concrete GrpcContextStrategy. ContextManager.setContextStrategy(new GrpcContextStrategy()); // Add automatic context propagation to Executor#execute. From 687ecb723e1ff9c6f9d3967019603c8d91a9e84c Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 4 Jul 2017 17:18:00 +0200 Subject: [PATCH 0300/1581] Minor grammar fix. --- .../contrib/agent/bootstrap/ContextManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java index 75ffe76ae1..8c60261e86 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java @@ -32,8 +32,8 @@ public final class ContextManager { // Not synchronized to avoid any synchronization costs after initialization. - // The agent is responsible to initialize this once (through #setContextStrategy) before any other - // method of this class is called. + // The agent is responsible for initializing this once (through #setContextStrategy) before any + // other method of this class is called. private static ContextStrategy contextStrategy; private ContextManager() { @@ -42,8 +42,8 @@ private ContextManager() { /** * Sets the concrete strategy for accessing and manipulating the context. * - *

NB: The agent is responsible to set the context strategy once before any other method of - * this class is called. + *

NB: The agent is responsible for setting the context strategy once before any other method + * of this class is called. * * @param contextStrategy the concrete strategy for accessing and manipulating the context */ From 85f6cadf6314b277db0f7b5d064f14a6b02155a1 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 5 Jul 2017 02:04:32 +0200 Subject: [PATCH 0301/1581] s/addGrpcContextPropagation/addContextPropagation/g --- .../src/main/java/io/opencensus/contrib/agent/AgentMain.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index 56a4021349..521181f0ad 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -73,7 +73,7 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) .with(new AgentBuilderListener()) .ignore(none()); - agentBuilder = LazyLoaded.addGrpcContextPropagation(agentBuilder); + agentBuilder = LazyLoaded.addContextPropagation(agentBuilder); // TODO: Add more instrumentation, potentially introducing a plugin mechanism. agentBuilder.installOn(instrumentation); @@ -91,7 +91,7 @@ private static class LazyLoaded { /** * Adds automatic context propagation. */ - static AgentBuilder addGrpcContextPropagation(AgentBuilder agentBuilder) { + static AgentBuilder addContextPropagation(AgentBuilder agentBuilder) { // TODO(stschmidt): Gracefully handle the case of missing io.grpc.Context at runtime. // Initialize the ContextManager with the concrete GrpcContextStrategy. From 1d1a2d1ad3be9f4c0b28ea578cb8ff1654c1f857 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 5 Jul 2017 02:07:23 +0200 Subject: [PATCH 0302/1581] renamed matcher() to createMatcher(), transformer() to createTransformer(). --- .../src/main/java/io/opencensus/contrib/agent/AgentMain.java | 4 ++-- .../io/opencensus/contrib/agent/ExecutorInstrumentation.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index 521181f0ad..0b3f13528a 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -99,8 +99,8 @@ static AgentBuilder addContextPropagation(AgentBuilder agentBuilder) { // Add automatic context propagation to Executor#execute. agentBuilder = agentBuilder - .type(ExecutorInstrumentation.matcher()) - .transform(ExecutorInstrumentation.transformer()); + .type(ExecutorInstrumentation.createMatcher()) + .transform(ExecutorInstrumentation.createTransformer()); // TODO(stschmidt): Add automatic context propagation to Thread#start. diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java index 62a9ef649c..f7b6471e6e 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java @@ -44,13 +44,13 @@ public DynamicType.Builder transform(DynamicType.Builder builder, } } - static ElementMatcher.Junction matcher() { + static ElementMatcher.Junction createMatcher() { // TODO(stschmidt): Exclude known call sites that already propagate the context. return isSubTypeOf(Executor.class).and(not(isAbstract())); } - static AgentBuilder.Transformer transformer() { + static AgentBuilder.Transformer createTransformer() { return new Transformer(); } From 4728f2165b5f086bee02e1181ef60256e801370a Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 5 Jul 2017 02:11:49 +0200 Subject: [PATCH 0303/1581] s/GrpcContextStrategy/ContextStrategyImpl/g and reduce references to io.grpc.Context. --- .../src/main/java/io/opencensus/contrib/agent/AgentMain.java | 4 ++-- .../{GrpcContextStrategy.java => ContextStrategyImpl.java} | 2 +- .../io/opencensus/contrib/agent/bootstrap/ContextManager.java | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) rename contrib/agent/src/main/java/io/opencensus/contrib/agent/{GrpcContextStrategy.java => ContextStrategyImpl.java} (93%) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index 0b3f13528a..0034707363 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -94,8 +94,8 @@ private static class LazyLoaded { static AgentBuilder addContextPropagation(AgentBuilder agentBuilder) { // TODO(stschmidt): Gracefully handle the case of missing io.grpc.Context at runtime. - // Initialize the ContextManager with the concrete GrpcContextStrategy. - ContextManager.setContextStrategy(new GrpcContextStrategy()); + // Initialize the ContextManager with the concrete ContextStrategy. + ContextManager.setContextStrategy(new ContextStrategyImpl()); // Add automatic context propagation to Executor#execute. agentBuilder = agentBuilder diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/GrpcContextStrategy.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ContextStrategyImpl.java similarity index 93% rename from contrib/agent/src/main/java/io/opencensus/contrib/agent/GrpcContextStrategy.java rename to contrib/agent/src/main/java/io/opencensus/contrib/agent/ContextStrategyImpl.java index b7503894d7..3edafeac80 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/GrpcContextStrategy.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ContextStrategyImpl.java @@ -20,7 +20,7 @@ * Implementation of {@link ContextStrategy} for accessing and manipulating the * {@link io.grpc.Context}. */ -final class GrpcContextStrategy implements ContextStrategy { +final class ContextStrategyImpl implements ContextStrategy { @Override public Runnable wrapInCurrentContext(Runnable runnable) { diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java index 8c60261e86..3d2226c391 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java @@ -18,8 +18,7 @@ * instrumented bytecode. * *

{@code ContextManager} avoids tight coupling with the concrete implementation of the context - * (such as {@link io.grpc.Context}) by accessing and manipulating the context through the - * {@link ContextStrategy} interface. + * by accessing and manipulating the context through the {@link ContextStrategy} interface. * *

Both {@link ContextManager} and {@link ContextStrategy} are loaded by the bootstrap * classloader so that they can be used from classes loaded by the bootstrap classloader. From a185ea5231a7b9503264b563e7040d07e20108f8 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 5 Jul 2017 13:37:13 +0200 Subject: [PATCH 0304/1581] Minor grammar fix. --- .../io/opencensus/contrib/agent/bootstrap/ContextManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java index 3d2226c391..89a2f025dd 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java @@ -22,7 +22,7 @@ * *

Both {@link ContextManager} and {@link ContextStrategy} are loaded by the bootstrap * classloader so that they can be used from classes loaded by the bootstrap classloader. - * A concrete implementations of {@link ContextStrategy} will be loaded by the system classloader. + * A concrete implementation of {@link ContextStrategy} will be loaded by the system classloader. * This allows for using the same context implementation as the instrumented application. * *

{@code ContextManager} is implemented as a static class to allow for easy and fast use from From 27fc483b6aec98f1cc1b3f1d1f6174135ccb9b53 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Sun, 9 Jul 2017 23:06:10 +0200 Subject: [PATCH 0305/1581] Mention ContextManager and ContextStrategy as examples of classes that have to be loaded by the bootstrap classloader. --- .../src/main/java/io/opencensus/contrib/agent/AgentMain.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index 0034707363..dd6204b083 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -60,8 +60,9 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th logger.info("Initializing."); - // The classes in bootstrap.jar will be referenced from classes loaded by the bootstrap - // classloader. Thus, these classes have to be loaded by the bootstrap classloader, too. + // The classes in bootstrap.jar, such as ContextManger and ContextStrategy, will be referenced + // from classes loaded by the bootstrap classloader. Thus, these classes have to be loaded by + // the bootstrap classloader, too. instrumentation.appendToBootstrapClassLoaderSearch( new JarFile(Resources.getResourceAsTempFile("bootstrap.jar"))); From f829597f5ee7e3cf993cb2ddfefd988a8faa4643 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 17 Jul 2017 02:01:24 +0200 Subject: [PATCH 0306/1581] Define the FindBugs Annotations library in the root buildscript, using same version as the other FindBugs dependencies. --- build.gradle | 1 + contrib/agent/build.gradle | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5142e49073..a230be2e49 100644 --- a/build.gradle +++ b/build.gradle @@ -107,6 +107,7 @@ subprojects { auto_value : "com.google.auto.value:auto-value:${autoValueVersion}", disruptor : 'com.lmax:disruptor:3.3.6', errorprone : 'com.google.errorprone:error_prone_annotations:2.0.11', + findbugs_annotations : "com.google.code.findbugs:annotations:${findBugsVersion}", grpc_context : "io.grpc:grpc-context:${grpcContextVersion}", guava : "com.google.guava:guava:${guavaVersion}", jsr305 : "com.google.code.findbugs:jsr305:${findBugsVersion}", diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index a90cf0a63e..a80529cb6c 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -32,7 +32,7 @@ def agentRepackaged = "${agentPackage}.deps" dependencies { compileOnly libraries.grpc_context testCompile libraries.grpc_context - compile group: 'com.google.code.findbugs', name: 'annotations', version: '3.0.1u2' + compile libraries.findbugs_annotations compile libraries.guava compile group: 'net.bytebuddy', name: 'byte-buddy', version: '1.7.1' From 6f89840b3305f12cbccdc05dda4e92cee7b141ca Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 17 Jul 2017 02:02:46 +0200 Subject: [PATCH 0307/1581] Define the ByteBuddy library in the root buildscript. --- build.gradle | 1 + contrib/agent/build.gradle | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a230be2e49..6b9f1dda98 100644 --- a/build.gradle +++ b/build.gradle @@ -105,6 +105,7 @@ subprojects { libraries = [ auto_value : "com.google.auto.value:auto-value:${autoValueVersion}", + byte_buddy : 'net.bytebuddy:byte-buddy:1.7.1', disruptor : 'com.lmax:disruptor:3.3.6', errorprone : 'com.google.errorprone:error_prone_annotations:2.0.11', findbugs_annotations : "com.google.code.findbugs:annotations:${findBugsVersion}", diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index a80529cb6c..c6f5fc8649 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -34,7 +34,7 @@ dependencies { testCompile libraries.grpc_context compile libraries.findbugs_annotations compile libraries.guava - compile group: 'net.bytebuddy', name: 'byte-buddy', version: '1.7.1' + compile libraries.byte_buddy signature 'org.codehaus.mojo.signature:java16:+@signature' } From 4efb81f826a15239b831360b694b9013003dbf84 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 14 Jul 2017 18:01:43 +0200 Subject: [PATCH 0308/1581] Add io.grpc.Context#currentContextExecutor as an example. --- .../io/opencensus/contrib/agent/ExecutorInstrumentation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java index f7b6471e6e..c13e4bb8de 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java @@ -45,7 +45,8 @@ public DynamicType.Builder transform(DynamicType.Builder builder, } static ElementMatcher.Junction createMatcher() { - // TODO(stschmidt): Exclude known call sites that already propagate the context. + // TODO(stschmidt): Exclude known call sites that already propagate the context, such as + // io.grpc.Context#currentContextExecutor. return isSubTypeOf(Executor.class).and(not(isAbstract())); } From 43336da94ccb38696e76a589ec028a0f7b57378a Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 14 Jul 2017 17:58:09 +0200 Subject: [PATCH 0309/1581] Added missing Javadoc tags to AgentMain.LazyLoaded#addContextPropagation. --- .../src/main/java/io/opencensus/contrib/agent/AgentMain.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index dd6204b083..8744528a26 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -91,6 +91,10 @@ private static class LazyLoaded { /** * Adds automatic context propagation. + * + * @param agentBuilder an {@link AgentBuilder} object to which the additional instrumentation is + * added + * @return an {@link AgentBuilder} object having the additional instrumentation */ static AgentBuilder addContextPropagation(AgentBuilder agentBuilder) { // TODO(stschmidt): Gracefully handle the case of missing io.grpc.Context at runtime. From 49661e2f447261a59b4a83d4e56c86ed50a4321e Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 14 Jul 2017 17:52:45 +0200 Subject: [PATCH 0310/1581] Make AgentMain.LazyLoaded#addContextPropagation private. --- .../src/main/java/io/opencensus/contrib/agent/AgentMain.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index 8744528a26..c3450868e5 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -96,7 +96,7 @@ private static class LazyLoaded { * added * @return an {@link AgentBuilder} object having the additional instrumentation */ - static AgentBuilder addContextPropagation(AgentBuilder agentBuilder) { + private static AgentBuilder addContextPropagation(AgentBuilder agentBuilder) { // TODO(stschmidt): Gracefully handle the case of missing io.grpc.Context at runtime. // Initialize the ContextManager with the concrete ContextStrategy. From cc557d16d5c9968e07c865371dc12dce45ef063c Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 7 Jul 2017 01:39:30 +0200 Subject: [PATCH 0311/1581] Run the test with MockitoJUnitRunner. --- .../io/opencensus/contrib/agent/ResourcesTest.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java index 9eb33da5be..972a41dc21 100644 --- a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java +++ b/contrib/agent/src/test/java/io/opencensus/contrib/agent/ResourcesTest.java @@ -14,7 +14,6 @@ package io.opencensus.contrib.agent; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import com.google.common.base.Charsets; @@ -27,20 +26,23 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; /** * Unit tests for {@link Resources}. */ -@RunWith(JUnit4.class) +@RunWith(MockitoJUnitRunner.class) public class ResourcesTest { @Rule public final ExpectedException exception = ExpectedException.none(); + + @Mock + private File mockFile; @Test public void getResourceAsTempFile() throws IOException { - File mockFile = mock(File.class); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); Resources.getResourceAsTempFile("some_resource.txt", mockFile, bytes); @@ -54,7 +56,7 @@ public void getResourceAsTempFile_Missing() throws IOException { exception.expect(FileNotFoundException.class); Resources.getResourceAsTempFile("missing_resource.txt", - mock(File.class), new ByteArrayOutputStream()); + mockFile, new ByteArrayOutputStream()); } @Test @@ -69,6 +71,6 @@ public void write(int b) throws IOException { exception.expect(IOException.class); exception.expectMessage("denied"); - Resources.getResourceAsTempFile("some_resource.txt", mock(File.class), badOutputStream); + Resources.getResourceAsTempFile("some_resource.txt", mockFile, badOutputStream); } } From 06876a7109b99288168411a661a66d749debee47 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 7 Jul 2017 01:40:31 +0200 Subject: [PATCH 0312/1581] Separate unit tests from integration tests. --- contrib/agent/build.gradle | 36 ++++++++++++++++--- .../agent/ExecutorInstrumentationTest.java | 0 2 files changed, 31 insertions(+), 5 deletions(-) rename contrib/agent/src/{test => integration-test}/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java (100%) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index c6f5fc8649..446afd2831 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.github.johnrengelman.shadow' version '2.0.0' + id 'com.github.johnrengelman.shadow' version '2.0.1' id 'me.tatarka.retrolambda' version '3.6.0' } @@ -29,9 +29,27 @@ def agentBootstrapClasses = agentBootstrapPackageDir + '**' // classloader). def agentRepackaged = "${agentPackage}.deps" +// The setup for integration testing is mostly based on +// https://www.petrikainulainen.net/programming/gradle/getting-started-with-gradle-integration-testing/. +sourceSets { + integrationTest { + java { + compileClasspath += main.output + test.output + runtimeClasspath += main.output + test.output + srcDir file('src/integration-test/java') + } + resources.srcDir file('src/integration-test/resources') + } +} + +configurations { + integrationTestCompile.extendsFrom testCompile + integrationTestRuntime.extendsFrom testRuntime +} + dependencies { compileOnly libraries.grpc_context - testCompile libraries.grpc_context + integrationTestCompile libraries.grpc_context compile libraries.findbugs_annotations compile libraries.guava compile libraries.byte_buddy @@ -39,6 +57,9 @@ dependencies { signature 'org.codehaus.mojo.signature:java16:+@signature' } +// Disable findbugs for integration tests, too. +findbugsIntegrationTest.enabled = false + jar { manifest { // Set the required manifest attributes for the Java agent, cf. @@ -123,8 +144,13 @@ jar.finalizedBy shadowJar // TODO(stschmidt): Proguard-shrink the agent JAR. -// TODO(stschmidt): Move the integration tests to a separate SourceSet once -// https://github.com/johnrengelman/shadow/issues/297 is fixed. -test { +// Run integration tests with the agent enabled. +task integrationTest(type: Test) { + testClassesDir = sourceSets.integrationTest.output.classesDir + classpath = sourceSets.integrationTest.runtimeClasspath + jvmArgs "-javaagent:${shadowJar.archivePath}" } + +check.dependsOn integrationTest +integrationTest.mustRunAfter test diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java similarity index 100% rename from contrib/agent/src/test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java rename to contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java From 1ed2461c1f6e6ee89cc611fe9eb6dd8b61ab0c2b Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 17 Jul 2017 21:16:47 +0200 Subject: [PATCH 0313/1581] Disable checkstyle for integration tests if not java8. --- contrib/agent/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 446afd2831..f5e81ae2a9 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -60,6 +60,9 @@ dependencies { // Disable findbugs for integration tests, too. findbugsIntegrationTest.enabled = false +// Disable checkstyle for integration tests if not java8. +checkstyleIntegrationTest.enabled = JavaVersion.current().isJava8Compatible() + jar { manifest { // Set the required manifest attributes for the Java agent, cf. From 413e0a5ac390955dabc05a12a3936523cd4ab9e0 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 18 Jul 2017 00:28:25 +0200 Subject: [PATCH 0314/1581] Replace deprecated testClassesDir with testClassesDirs according to https://docs.gradle.org/current/release-notes.html. --- contrib/agent/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index f5e81ae2a9..1cf4f5d032 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -149,7 +149,7 @@ jar.finalizedBy shadowJar // Run integration tests with the agent enabled. task integrationTest(type: Test) { - testClassesDir = sourceSets.integrationTest.output.classesDir + testClassesDirs = sourceSets.integrationTest.output.classesDirs classpath = sourceSets.integrationTest.runtimeClasspath jvmArgs "-javaagent:${shadowJar.archivePath}" From 59919853e95137c67ae59618322bbd9e4f6182d1 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 7 Jul 2017 01:41:39 +0200 Subject: [PATCH 0315/1581] Add a simple test for ContextManager. --- .../agent/bootstrap/ContextManagerTest.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java b/contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java new file mode 100644 index 0000000000..9bd387b924 --- /dev/null +++ b/contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent.bootstrap; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +/** + * Unit tests for {@link ContextManager}. + */ +@RunWith(MockitoJUnitRunner.class) +public class ContextManagerTest { + + @Mock + private ContextStrategy mockContextStrategy; + + @Mock + private Runnable runnable; + + @Test + public void setContextStrategy() { + ContextManager.setContextStrategy(mockContextStrategy); + + ContextManager.wrapInCurrentContext(runnable); + + Mockito.verify(mockContextStrategy).wrapInCurrentContext(runnable); + } +} From f1b1a43a68af3ff5abf3bd617f42bf3f0ba4c036 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 19 Jul 2017 14:53:16 +0200 Subject: [PATCH 0316/1581] Also test double initialization. While there, moved the initialization of ContextManager to the static initializer, otherwise the execution of test methods would matter. --- .../agent/bootstrap/ContextManagerTest.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java b/contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java index 9bd387b924..c072392f4b 100644 --- a/contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java +++ b/contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java @@ -13,7 +13,11 @@ package io.opencensus.contrib.agent.bootstrap; +import static org.mockito.Mockito.mock; + +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; @@ -25,16 +29,28 @@ @RunWith(MockitoJUnitRunner.class) public class ContextManagerTest { - @Mock - private ContextStrategy mockContextStrategy; + private static final ContextStrategy mockContextStrategy; + + static { + mockContextStrategy = mock(ContextStrategy.class); + ContextManager.setContextStrategy(mockContextStrategy); + } + + @Rule + public final ExpectedException exception = ExpectedException.none(); @Mock private Runnable runnable; @Test - public void setContextStrategy() { + public void setContextStrategy_already_initialized() { + exception.expect(IllegalStateException.class); + ContextManager.setContextStrategy(mockContextStrategy); + } + @Test + public void wrapInCurrentContext() { ContextManager.wrapInCurrentContext(runnable); Mockito.verify(mockContextStrategy).wrapInCurrentContext(runnable); From 2718b429bd8a63f9edbb6e402b0a0fba4fd89cfa Mon Sep 17 00:00:00 2001 From: Yang Song Date: Wed, 19 Jul 2017 20:02:55 -0700 Subject: [PATCH 0317/1581] Add basic Aggregation and Aggregate (#450) * Rename View.Dimension to Column. * Add Aggregation and Aggregate. * Rename Aggregate to AggregationData, rename subclasses. --- .../java/io/opencensus/stats/Aggregation.java | 242 ++++++++++++++++ .../io/opencensus/stats/AggregationData.java | 269 ++++++++++++++++++ .../main/java/io/opencensus/stats/View.java | 6 +- .../opencensus/stats/AggregationDataTest.java | 167 +++++++++++ .../io/opencensus/stats/AggregationTest.java | 139 +++++++++ .../java/io/opencensus/stats/ViewTest.java | 12 +- .../io/opencensus/stats/MutableViewData.java | 4 +- 7 files changed, 828 insertions(+), 11 deletions(-) create mode 100644 core/src/main/java/io/opencensus/stats/Aggregation.java create mode 100644 core/src/main/java/io/opencensus/stats/AggregationData.java create mode 100644 core/src/test/java/io/opencensus/stats/AggregationDataTest.java create mode 100644 core/src/test/java/io/opencensus/stats/AggregationTest.java diff --git a/core/src/main/java/io/opencensus/stats/Aggregation.java b/core/src/main/java/io/opencensus/stats/Aggregation.java new file mode 100644 index 0000000000..e6540e6504 --- /dev/null +++ b/core/src/main/java/io/opencensus/stats/Aggregation.java @@ -0,0 +1,242 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.auto.value.AutoValue; +import io.opencensus.common.Function; +import javax.annotation.concurrent.Immutable; + +/** + * {@link Aggregation} is the process of combining a certain set of {@code MeasureValue}s + * for a given {@code Measure} into an {@link AggregationData}. + * + *

{@link Aggregation} currently supports 6 types of basic aggregation: + *

    + *
  • Sum + *
  • Count + *
  • Histogram + *
  • Range + *
  • Mean + *
  • StdDev (standard deviation) + *
+ * + *

When creating a {@link View}, one or more {@link Aggregation} needs to be specified as how to + * aggregate {@code MeasureValue}s. + */ +@Immutable +public abstract class Aggregation { + + private Aggregation() { + } + + /** + * Applies the given match function to the underlying data type. + */ + public abstract T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction); + + /** Calculate sum on aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class Sum extends Aggregation { + + Sum() { + } + + /** + * Construct a {@code Sum}. + * + * @return a new {@code Sum}. + */ + public static Sum create() { + return new AutoValue_Aggregation_Sum(); + } + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p0.apply(this); + } + } + + /** Calculate count on aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class Count extends Aggregation { + + Count() { + } + + /** + * Construct a {@code Count}. + * + * @return a new {@code Count}. + */ + public static Count create() { + return new AutoValue_Aggregation_Count(); + } + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p1.apply(this); + } + } + + /** Calculate histogram on aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class Histogram extends Aggregation { + + Histogram() { + } + + /** + * Construct a {@code Histogram}. + * + * @return a new {@code Histogram}. + */ + // TODO(songya): not v0.1, expose factory method later. + static Histogram create(BucketBoundaries bucketBoundaries) { + checkNotNull(bucketBoundaries, "bucketBoundaries should not be null."); + return new AutoValue_Aggregation_Histogram(bucketBoundaries); + } + + public abstract BucketBoundaries getBucketBoundaries(); + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p2.apply(this); + } + } + + /** Calculate range on aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class Range extends Aggregation { + + Range() { + } + + /** + * Construct a {@code Range}. + * + * @return a new {@code Range}. + */ + public static Range create() { + return new AutoValue_Aggregation_Range(); + } + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p3.apply(this); + } + } + + /** Calculate mean on aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class Mean extends Aggregation { + + Mean() { + } + + /** + * Construct a {@code Mean}. + * + * @return a new {@code Mean}. + */ + // TODO(songya): not v0.1, expose factory method later. + static Mean create() { + return new AutoValue_Aggregation_Mean(); + } + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p4.apply(this); + } + } + + /** Calculate standard deviation on aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class StdDev extends Aggregation { + + StdDev() { + } + + /** + * Construct a {@code StdDev}. + * + * @return a new {@code StdDev}. + */ + // TODO(songya): not v0.1, expose factory method later. + static StdDev create() { + return new AutoValue_Aggregation_StdDev(); + } + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p5.apply(this); + } + } +} diff --git a/core/src/main/java/io/opencensus/stats/AggregationData.java b/core/src/main/java/io/opencensus/stats/AggregationData.java new file mode 100644 index 0000000000..dcf8e50b35 --- /dev/null +++ b/core/src/main/java/io/opencensus/stats/AggregationData.java @@ -0,0 +1,269 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.auto.value.AutoValue; +import io.opencensus.common.Function; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.annotation.concurrent.Immutable; + +/** + * {@link AggregationData} is the result of applying a given {@link Aggregation} to a set of + * {@code MeasureValue}s. + * + *

{@link AggregationData} currently supports 6 types of basic aggregation values: + *

    + *
  • SumData + *
  • CountData + *
  • HistogramData + *
  • RangeData + *
  • MeanData + *
  • StdDevData (standard deviation) + *
+ * + *

{@link ViewData} will contain one or more {@link AggregationData}s, corresponding to its + * {@link Aggregation} definition in {@link View}. + */ +@Immutable +public abstract class AggregationData { + + private AggregationData() { + } + + /** + * Applies the given match function to the underlying data type. + */ + public abstract T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction); + + /** The sum value of aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class SumData extends AggregationData { + + SumData() { + } + + static SumData create(double sum) { + return new AutoValue_AggregationData_SumData(sum); + } + + /** + * Returns the aggregated sum. + * + * @return the aggregated sum. + */ + public abstract double getSum(); + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p0.apply(this); + } + } + + /** The count value of aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class CountData extends AggregationData { + + CountData() { + } + + static CountData create(long count) { + return new AutoValue_AggregationData_CountData(count); + } + + /** + * Returns the aggregated count. + * + * @return the aggregated count. + */ + public abstract long getCount(); + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p1.apply(this); + } + } + + /** The histogram of aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class HistogramData extends AggregationData { + + HistogramData() { + } + + static HistogramData create(long... bucketCountDatas) { + checkNotNull(bucketCountDatas, "bucket counts should not be null."); + List boxedBucketCountDatas = new ArrayList(); + for (long bucketCountData : bucketCountDatas) { + boxedBucketCountDatas.add(bucketCountData); + } + return new AutoValue_AggregationData_HistogramData( + Collections.unmodifiableList(boxedBucketCountDatas)); + } + + /** + * Returns the aggregated bucket counts. The returned list is immutable, trying to update it + * will throw an {@code UnsupportedOperationException}. + * + * @return the aggregated bucket counts. + */ + public abstract List getBucketCounts(); + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p2.apply(this); + } + } + + /** The range of aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class RangeData extends AggregationData { + + RangeData() { + } + + static RangeData create(double min, double max) { + if (min != Double.POSITIVE_INFINITY || max != Double.NEGATIVE_INFINITY) { + checkArgument(min <= max, "max should be greater or equal to min."); + } + return new AutoValue_AggregationData_RangeData(min, max); + } + + /** + * Returns the minimum of the population values. + * + * @return the minimum of the population values. + */ + public abstract double getMin(); + + /** + * Returns the maximum of the population values. + * + * @return the maximum of the population values. + */ + public abstract double getMax(); + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p3.apply(this); + } + } + + /** The mean value of aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class MeanData extends AggregationData { + + MeanData() { + } + + static MeanData create(double mean) { + return new AutoValue_AggregationData_MeanData(mean); + } + + /** + * Returns the aggregated mean. + * + * @return the aggregated mean. + */ + public abstract double getMean(); + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p4.apply(this); + } + } + + /** The standard deviation value of aggregated {@code MeasureValue}s. */ + @Immutable + @AutoValue + public abstract static class StdDevData extends AggregationData { + + StdDevData() { + } + + static StdDevData create(double stdDev) { + return new AutoValue_AggregationData_StdDevData(stdDev); + } + + /** + * Returns the aggregated standard deviation. + * + * @return the aggregated standard deviation. + */ + public abstract double getStdDev(); + + @Override + public final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5, + Function defaultFunction) { + return p5.apply(this); + } + } +} diff --git a/core/src/main/java/io/opencensus/stats/View.java b/core/src/main/java/io/opencensus/stats/View.java index 72ffc389a6..059c235641 100644 --- a/core/src/main/java/io/opencensus/stats/View.java +++ b/core/src/main/java/io/opencensus/stats/View.java @@ -42,13 +42,13 @@ public abstract class View { public abstract Measure getMeasure(); /** - * Dimensions (a.k.a Tag Keys) to match with the associated {@link Measure}. - * If no dimensions are specified, then all stats are recorded. Dimensions must be unique. + * Columns (a.k.a Tag Keys) to match with the associated {@link Measure}. + * If no dimensions are specified, then all stats are recorded. Columns must be unique. * *

Note: The returned list is unmodifiable, attempts to update it will throw an * UnsupportedOperationException. */ - public abstract List getDimensions(); + public abstract List getColumns(); /** * Applies the given match function to the underlying data type. diff --git a/core/src/test/java/io/opencensus/stats/AggregationDataTest.java b/core/src/test/java/io/opencensus/stats/AggregationDataTest.java new file mode 100644 index 0000000000..90eb748669 --- /dev/null +++ b/core/src/test/java/io/opencensus/stats/AggregationDataTest.java @@ -0,0 +1,167 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.stats.AggregationData.CountData; +import io.opencensus.stats.AggregationData.HistogramData; +import io.opencensus.stats.AggregationData.MeanData; +import io.opencensus.stats.AggregationData.RangeData; +import io.opencensus.stats.AggregationData.StdDevData; +import io.opencensus.stats.AggregationData.SumData; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link io.opencensus.stats.AggregationData}. */ +@RunWith(JUnit4.class) +public class AggregationDataTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testCreateHistogramData() { + HistogramData histogram = HistogramData.create(0, 0, 0); + assertThat(histogram.getBucketCounts()).containsExactly(0L, 0L, 0L).inOrder(); + } + + @Test + public void testNullBucketCountData() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("bucket counts should not be null."); + HistogramData.create(null); + } + + @Test + public void testRangeDataMinIsGreaterThanMax() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("max should be greater or equal to min."); + RangeData.create(10.0, 0.0); + } + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup( + SumData.create(10.0), + SumData.create(10.0)) + .addEqualityGroup( + SumData.create(20.0), + SumData.create(20.0)) + .addEqualityGroup( + CountData.create(40), + CountData.create(40)) + .addEqualityGroup( + CountData.create(80), + CountData.create(80)) + .addEqualityGroup( + HistogramData.create(new long[]{0, 10, 0}), + HistogramData.create(new long[]{0, 10, 0})) + .addEqualityGroup( + HistogramData.create(new long[]{0, 10, 100}), + HistogramData.create(new long[]{0, 10, 100})) + .addEqualityGroup( + RangeData.create(-1.0, 1.0), + RangeData.create(-1.0, 1.0)) + .addEqualityGroup( + RangeData.create(-5.0, 1.0), + RangeData.create(-5.0, 1.0)) + .addEqualityGroup( + MeanData.create(5.0), + MeanData.create(5.0)) + .addEqualityGroup( + MeanData.create(-5.0), + MeanData.create(-5.0)) + .addEqualityGroup( + StdDevData.create(23.3), + StdDevData.create(23.3)) + .addEqualityGroup( + StdDevData.create(-23.3), + StdDevData.create(-23.3)) + .testEquals(); + } + + @Test + public void testMatchAndGet() { + List aggregations = Arrays.asList( + SumData.create(10.0), + CountData.create(40), + HistogramData.create(new long[]{0, 10, 0}), + RangeData.create(-1.0, 1.0), + MeanData.create(5.0), + StdDevData.create(23.3)); + + final List actual = new ArrayList(); + for (AggregationData aggregation : aggregations) { + aggregation.match( + new Function() { + @Override + public Void apply(SumData arg) { + actual.add(arg.getSum()); + return null; + } + }, + new Function() { + @Override + public Void apply(CountData arg) { + actual.add(arg.getCount()); + return null; + } + }, + new Function() { + @Override + public Void apply(HistogramData arg) { + actual.add(arg.getBucketCounts()); + return null; + } + }, + new Function() { + @Override + public Void apply(RangeData arg) { + actual.add(arg.getMin()); + actual.add(arg.getMax()); + return null; + } + }, + new Function() { + @Override + public Void apply(MeanData arg) { + actual.add(arg.getMean()); + return null; + } + }, + new Function() { + @Override + public Void apply(StdDevData arg) { + actual.add(arg.getStdDev()); + return null; + } + }, + Functions.throwIllegalArgumentException()); + } + + assertThat(actual).isEqualTo( + Arrays.asList(10.0, 40L, Arrays.asList(0L, 10L, 0L), -1.0, 1.0, 5.0, 23.3)); + } +} diff --git a/core/src/test/java/io/opencensus/stats/AggregationTest.java b/core/src/test/java/io/opencensus/stats/AggregationTest.java new file mode 100644 index 0000000000..39cc9928f8 --- /dev/null +++ b/core/src/test/java/io/opencensus/stats/AggregationTest.java @@ -0,0 +1,139 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.stats.Aggregation.Count; +import io.opencensus.stats.Aggregation.Histogram; +import io.opencensus.stats.Aggregation.Mean; +import io.opencensus.stats.Aggregation.Range; +import io.opencensus.stats.Aggregation.StdDev; +import io.opencensus.stats.Aggregation.Sum; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link io.opencensus.stats.Aggregation}. */ +@RunWith(JUnit4.class) +public class AggregationTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testCreateHistogram() { + BucketBoundaries bucketBoundaries = BucketBoundaries.create(Arrays.asList(0.1, 2.2, 33.3)); + Histogram histogram = Histogram.create(bucketBoundaries); + assertThat(histogram.getBucketBoundaries()).isEqualTo(bucketBoundaries); + } + + @Test + public void testNullBucketBoundaries() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("bucketBoundaries should not be null."); + Histogram.create(null); + } + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup( + Sum.create(), + Sum.create()) + .addEqualityGroup( + Count.create(), + Count.create()) + .addEqualityGroup( + Histogram.create(BucketBoundaries.create(Arrays.asList(-10.0, 1.0, 5.0))), + Histogram.create(BucketBoundaries.create(Arrays.asList(-10.0, 1.0, 5.0)))) + .addEqualityGroup( + Histogram.create(BucketBoundaries.create(Arrays.asList(0.0, 1.0, 5.0))), + Histogram.create(BucketBoundaries.create(Arrays.asList(0.0, 1.0, 5.0)))) + .addEqualityGroup( + Range.create(), + Range.create()) + .addEqualityGroup( + Mean.create(), + Mean.create()) + .addEqualityGroup( + StdDev.create(), + StdDev.create()) + .testEquals(); + } + + @Test + public void testMatch() { + List aggregations = Arrays.asList( + Sum.create(), + Count.create(), + Histogram.create(BucketBoundaries.create(Arrays.asList(-10.0, 1.0, 5.0))), + Range.create(), + Mean.create(), + StdDev.create()); + + List actual = new ArrayList(); + for (Aggregation aggregation : aggregations) { + actual.add(aggregation.match( + new Function() { + @Override + public String apply(Sum arg) { + return "SUM"; + } + }, + new Function() { + @Override + public String apply(Count arg) { + return "COUNT"; + } + }, + new Function() { + @Override + public String apply(Histogram arg) { + return "HISTOGRAM"; + } + }, + new Function() { + @Override + public String apply(Range arg) { + return "RANGE"; + } + }, + new Function() { + @Override + public String apply(Mean arg) { + return "MEAN"; + } + }, + new Function() { + @Override + public String apply(StdDev arg) { + return "STDDEV"; + } + }, + Functions.throwIllegalArgumentException())); + } + + assertThat(actual) + .isEqualTo(Arrays.asList("SUM", "COUNT", "HISTOGRAM", "RANGE", "MEAN", "STDDEV")); + } +} diff --git a/core/src/test/java/io/opencensus/stats/ViewTest.java b/core/src/test/java/io/opencensus/stats/ViewTest.java index afd92ac045..4845aac361 100644 --- a/core/src/test/java/io/opencensus/stats/ViewTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewTest.java @@ -39,9 +39,9 @@ public void testDistributionView() { assertThat(view.getName()).isEqualTo(name); assertThat(view.getDescription()).isEqualTo(description); assertThat(view.getMeasure().getName()).isEqualTo(measure.getName()); - assertThat(view.getDimensions()).hasSize(2); - assertThat(view.getDimensions().get(0).toString()).isEqualTo("foo"); - assertThat(view.getDimensions().get(1).toString()).isEqualTo("bar"); + assertThat(view.getColumns()).hasSize(2); + assertThat(view.getColumns().get(0).toString()).isEqualTo("foo"); + assertThat(view.getColumns().get(1).toString()).isEqualTo("bar"); assertTrue(view.match( new Function () { @Override public Boolean apply(DistributionView dView) { @@ -66,9 +66,9 @@ public void testIntervalView() { assertThat(view.getDescription()).isEqualTo(description); assertThat(view.getMeasure().getName()) .isEqualTo(measure.getName()); - assertThat(view.getDimensions()).hasSize(2); - assertThat(view.getDimensions().get(0).toString()).isEqualTo("foo"); - assertThat(view.getDimensions().get(1).toString()).isEqualTo("bar"); + assertThat(view.getColumns()).hasSize(2); + assertThat(view.getColumns().get(0).toString()).isEqualTo("foo"); + assertThat(view.getColumns().get(1).toString()).isEqualTo("bar"); assertTrue(view.match( new Function () { @Override public Boolean apply(DistributionView dView) { diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java index 15ff1d032c..82917cc5c9 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java +++ b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java @@ -79,7 +79,7 @@ View getView() { void record(StatsContextImpl context, double value) { Map tags = context.tags; // TagKeys need to be unique within one view descriptor. - final List tagKeys = this.distributionView.getDimensions(); + final List tagKeys = this.distributionView.getColumns(); final List tagValues = new ArrayList(tagKeys.size()); // Record all the measures in a "Greedy" way. @@ -152,7 +152,7 @@ private MutableDistributionViewData( private final List generateTags(List tagValues) { final List tags = new ArrayList(tagValues.size()); int i = 0; - for (TagKey tagKey : this.distributionView.getDimensions()) { + for (TagKey tagKey : this.distributionView.getColumns()) { tags.add(Tag.create(tagKey, tagValues.get(i))); ++i; } From 37df029de0462ff421a34f8c5610e09015e953fa Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 24 Jul 2017 14:54:25 +0300 Subject: [PATCH 0318/1581] Fix a bug in the implementation that causes all Spans with RECORD_EVENTS options to also be exported. (#458) * Fix a bug in the implementation that causes all Spans with RECORD_EVENTS options to also be exported. * Make startEndHandler final --- .../io/opencensus/trace/StartEndHandlerImpl.java | 4 +++- .../trace/export/SpanExporterImplTest.java | 14 ++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java index 9159eeade7..c11cb88991 100644 --- a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java +++ b/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java @@ -110,7 +110,9 @@ private static final class SpanEndEvent implements EventQueue.Entry { @Override public void process() { - spanExporter.addSpan(span); + if (span.getContext().getTraceOptions().isSampled()) { + spanExporter.addSpan(span); + } if (runningSpanStore != null) { runningSpanStore.onEnd(span); } diff --git a/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java b/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java index 3c1900f851..d82011462c 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java +++ b/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java @@ -57,9 +57,10 @@ public class SpanExporterImplTest { private final SpanContext notSampledSpanContext = SpanContext.create( TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); - private final SpanExporterImpl sampledSpansServiceExporter = SpanExporterImpl.create(4, 1000); + private final SpanExporterImpl spanExporter = SpanExporterImpl.create(4, 1000); + private final RunningSpanStoreImpl runningSpanStore = new RunningSpanStoreImpl(); private final StartEndHandler startEndHandler = - new StartEndHandlerImpl(sampledSpansServiceExporter, null, null, new SimpleEventQueue()); + new StartEndHandlerImpl(spanExporter, runningSpanStore, null, new SimpleEventQueue()); private EnumSet recordSpanOptions = EnumSet.of(Options.RECORD_EVENTS); private final FakeServiceHandler serviceHandler = new FakeServiceHandler(); @Mock private Handler mockServiceHandler; @@ -67,7 +68,8 @@ public class SpanExporterImplTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); - sampledSpansServiceExporter.registerHandler("test.service", serviceHandler); + + spanExporter.registerHandler("test.service", serviceHandler); } private final SpanImpl createSampledEndedSpan(String spanName) { @@ -132,7 +134,7 @@ public void exportMoreSpansThanTheBufferSize() { @Test public void interruptWorkerThreadStops() throws InterruptedException { - Thread serviceExporterThread = sampledSpansServiceExporter.getServiceExporterThread(); + Thread serviceExporterThread = spanExporter.getServiceExporterThread(); serviceExporterThread.interrupt(); // Test that the worker thread will stop. serviceExporterThread.join(); @@ -143,7 +145,7 @@ public void serviceHandlerThrowsException() { doThrow(new IllegalArgumentException("No export for you.")) .when(mockServiceHandler) .export(anyListOf(SpanData.class)); - sampledSpansServiceExporter.registerHandler("mock.service", mockServiceHandler); + spanExporter.registerHandler("mock.service", mockServiceHandler); SpanImpl span1 = createSampledEndedSpan(SPAN_NAME_1); List exported = serviceHandler.waitForExport(1); assertThat(exported.size()).isEqualTo(1); @@ -158,7 +160,7 @@ public void serviceHandlerThrowsException() { @Test public void exportSpansToMultipleServices() { FakeServiceHandler serviceHandler2 = new FakeServiceHandler(); - sampledSpansServiceExporter.registerHandler("test.service2", serviceHandler2); + spanExporter.registerHandler("test.service2", serviceHandler2); SpanImpl span1 = createSampledEndedSpan(SPAN_NAME_1); SpanImpl span2 = createSampledEndedSpan(SPAN_NAME_2); List exported1 = serviceHandler.waitForExport(2); From 8f3aa393862c75c8899c3c6df863d6efe89f11b9 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 24 Jul 2017 10:36:12 -0700 Subject: [PATCH 0319/1581] Add a no-op StatsComponent to return when no implementation is available. The no-op StatsComponent returns a no-op StatsRecorder and a null ViewManager. The StatsRecorder is non-null so that code that only records stats doesn't need to check for null. NoopStatsRecorder.record(...) simply ignores the stats. However, the ViewManager is null to avoid returning misleading empty results from NoopStatsComponent.getViewManager().getView(...). --- .../main/java/io/opencensus/stats/Stats.java | 4 +- .../io/opencensus/stats/StatsComponent.java | 38 ++++++++++++++++++- .../io/opencensus/stats/StatsRecorder.java | 20 ++++++++++ .../java/io/opencensus/stats/StatsTest.java | 8 ++-- 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/io/opencensus/stats/Stats.java b/core/src/main/java/io/opencensus/stats/Stats.java index 0b52bdf0e0..d245a6d8c9 100644 --- a/core/src/main/java/io/opencensus/stats/Stats.java +++ b/core/src/main/java/io/opencensus/stats/Stats.java @@ -46,7 +46,6 @@ public static ViewManager getViewManager() { // Any provider that may be used for StatsComponent can be added here. @VisibleForTesting - @Nullable static StatsComponent loadStatsComponent(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. @@ -72,8 +71,7 @@ static StatsComponent loadStatsComponent(ClassLoader classLoader) { + "default implementation for StatsComponent.", e); } - // TODO: Add a no-op implementation. - return null; + return StatsComponent.getNoopStatsComponent(); } private Stats() {} diff --git a/core/src/main/java/io/opencensus/stats/StatsComponent.java b/core/src/main/java/io/opencensus/stats/StatsComponent.java index fbf609e17d..8e1dc8dfc5 100644 --- a/core/src/main/java/io/opencensus/stats/StatsComponent.java +++ b/core/src/main/java/io/opencensus/stats/StatsComponent.java @@ -13,15 +13,20 @@ package io.opencensus.stats; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + /** * Class that holds the implementations for {@link ViewManager}, {@link StatsRecorder}, and {@link * StatsContextFactory}. * *

All objects returned by methods on {@code StatsComponent} are cacheable. */ -// TODO(sebright): Add a no-op StatsComponent. public abstract class StatsComponent { + private static final StatsComponent NOOP_STATS_COMPONENT = new NoopStatsComponent(); + /** Returns the default {@link ViewManager}. */ + @Nullable public abstract ViewManager getViewManager(); /** Returns the default {@link StatsRecorder}. */ @@ -29,5 +34,36 @@ public abstract class StatsComponent { /** Returns the default {@link StatsContextFactory}. */ // TODO(sebright): Remove this method once StatsContext is replaced by TagContext. + @Nullable abstract StatsContextFactory getStatsContextFactory(); + + /** + * Returns a {@code StatsComponent} that has a no-op implementation for the {@link StatsRecorder}. + * + * @return a {@code StatsComponent} that has a no-op implementation for the {@code StatsRecorder}. + */ + static StatsComponent getNoopStatsComponent() { + return NOOP_STATS_COMPONENT; + } + + @Immutable + private static final class NoopStatsComponent extends StatsComponent { + + @Override + @Nullable + public ViewManager getViewManager() { + return null; + } + + @Override + public StatsRecorder getStatsRecorder() { + return StatsRecorder.getNoopStatsRecorder(); + } + + @Override + @Nullable + StatsContextFactory getStatsContextFactory() { + return null; + } + } } diff --git a/core/src/main/java/io/opencensus/stats/StatsRecorder.java b/core/src/main/java/io/opencensus/stats/StatsRecorder.java index f93ad9ed2b..d26f1d0e76 100644 --- a/core/src/main/java/io/opencensus/stats/StatsRecorder.java +++ b/core/src/main/java/io/opencensus/stats/StatsRecorder.java @@ -13,8 +13,12 @@ package io.opencensus.stats; +import javax.annotation.concurrent.Immutable; + /** Provides methods to record stats against tags. */ public abstract class StatsRecorder { + private static final StatsRecorder NOOP_STATS_RECORDER = new NoopStatsRecorder(); + // // TODO(sebright): Add a "record" method for implicit propagation: // // public void record(MeasurementMap measurementValues) { @@ -28,4 +32,20 @@ public abstract class StatsRecorder { * @param measurementValues the measurements to record. */ abstract void record(StatsContext tags, MeasureMap measurementValues); + + /** + * Returns a {@code StatsRecorder} that does not record any data. + * + * @return a {@code StatsRecorder} that does not record any data. + */ + static StatsRecorder getNoopStatsRecorder() { + return NOOP_STATS_RECORDER; + } + + @Immutable + private static final class NoopStatsRecorder extends StatsRecorder { + + @Override + void record(StatsContext tags, MeasureMap measurementValues) {} + } } diff --git a/core/src/test/java/io/opencensus/stats/StatsTest.java b/core/src/test/java/io/opencensus/stats/StatsTest.java index 278f0ce35a..423df07ef0 100644 --- a/core/src/test/java/io/opencensus/stats/StatsTest.java +++ b/core/src/test/java/io/opencensus/stats/StatsTest.java @@ -49,14 +49,16 @@ public void loadStatsManager_IgnoresMissingClasses() { public Class loadClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(); } - })) - .isNull(); + }) + .getClass() + .getName()) + .isEqualTo("io.opencensus.stats.StatsComponent$NoopStatsComponent"); } @Test public void defaultValues() { assertThat(Stats.getStatsContextFactory()).isNull(); - assertThat(Stats.getStatsRecorder()).isNull(); + assertThat(Stats.getStatsRecorder()).isEqualTo(StatsRecorder.getNoopStatsRecorder()); assertThat(Stats.getViewManager()).isNull(); } } From 069f69c4e3ea5e9a70e26190d94ed79f1e9d7de3 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 24 Jul 2017 12:37:03 -0700 Subject: [PATCH 0320/1581] Validate arguments in NoopStatsRecorder.record. --- core/src/main/java/io/opencensus/stats/StatsRecorder.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/io/opencensus/stats/StatsRecorder.java b/core/src/main/java/io/opencensus/stats/StatsRecorder.java index d26f1d0e76..6fec44fa9b 100644 --- a/core/src/main/java/io/opencensus/stats/StatsRecorder.java +++ b/core/src/main/java/io/opencensus/stats/StatsRecorder.java @@ -13,6 +13,7 @@ package io.opencensus.stats; +import com.google.common.base.Preconditions; import javax.annotation.concurrent.Immutable; /** Provides methods to record stats against tags. */ @@ -46,6 +47,9 @@ static StatsRecorder getNoopStatsRecorder() { private static final class NoopStatsRecorder extends StatsRecorder { @Override - void record(StatsContext tags, MeasureMap measurementValues) {} + void record(StatsContext tags, MeasureMap measurementValues) { + Preconditions.checkNotNull(tags); + Preconditions.checkNotNull(measurementValues); + } } } From 430c613e435aadee00e04a0206dee483b13d4cd7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 24 Jul 2017 12:37:33 -0700 Subject: [PATCH 0321/1581] Test StatsRecorder.getNoopStatsRecorder(). --- .../opencensus/stats/StatsRecorderTest.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 core/src/test/java/io/opencensus/stats/StatsRecorderTest.java diff --git a/core/src/test/java/io/opencensus/stats/StatsRecorderTest.java b/core/src/test/java/io/opencensus/stats/StatsRecorderTest.java new file mode 100644 index 0000000000..0a74f9f072 --- /dev/null +++ b/core/src/test/java/io/opencensus/stats/StatsRecorderTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import java.io.IOException; +import java.io.OutputStream; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link StatsRecorder}. */ +@RunWith(JUnit4.class) +public final class StatsRecorderTest { + + private final StatsContext statsContext = + new StatsContext() { + + @Override + public void serialize(OutputStream output) throws IOException { + } + + @Override + public StatsContext record(MeasureMap measurements) { + return null; + } + + @Override + public Builder builder() { + return null; + } + }; + + @Test + public void defaultRecord() { + StatsRecorder.getNoopStatsRecorder().record(statsContext, MeasureMap.builder().build()); + } + + @Test(expected = NullPointerException.class) + public void defaultRecord_DisallowNullStatsContext() { + StatsRecorder.getNoopStatsRecorder().record(null, MeasureMap.builder().build()); + } + + @Test(expected = NullPointerException.class) + public void defaultRecord_DisallowNullMeasureMap() { + StatsRecorder.getNoopStatsRecorder().record(statsContext, null); + } +} From 5ac2617a8e715cc318d5fc37a4a95899d967a3e5 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 24 Jul 2017 13:52:47 -0700 Subject: [PATCH 0322/1581] Add a function that always throws an AssertionError. The function can be used for all default cases in calls to "match" functions in the API library, since a version mismatch isn't possible, and the default case cannot occur in "match" functions that take all subclasses. --- .../java/io/opencensus/common/Functions.java | 21 +++++++++++++++++++ .../io/opencensus/common/FunctionsTest.java | 8 +++++++ 2 files changed, 29 insertions(+) diff --git a/api/src/main/java/io/opencensus/common/Functions.java b/api/src/main/java/io/opencensus/common/Functions.java index 60bb888554..dcc1dab53b 100644 --- a/api/src/main/java/io/opencensus/common/Functions.java +++ b/api/src/main/java/io/opencensus/common/Functions.java @@ -33,6 +33,14 @@ public Void apply(Object ignored) { } }; + private static final Function THROW_ASSERTION_ERROR = + new Function() { + @Override + public Void apply(Object ignored) { + throw new AssertionError(); + } + }; + /** * A {@code Function} that always ignores its argument and returns {@code null}. * @@ -72,4 +80,17 @@ public static Function throwIllegalArgumentException() { Function function = (Function) THROW_ILLEGAL_ARGUMENT_EXCEPTION; return function; } + + /** + * A {@code Function} that always ignores its argument and throws an {@link AssertionError}. + * + * @return a {@code Function} that always ignores its argument and throws an {@code + * AssertionError}. + */ + public static Function throwAssertionError() { + // It is safe to cast a producer of Void to anything, because Void is always null. + @SuppressWarnings("unchecked") + Function function = (Function) THROW_ASSERTION_ERROR; + return function; + } } diff --git a/api/src/test/java/io/opencensus/common/FunctionsTest.java b/api/src/test/java/io/opencensus/common/FunctionsTest.java index 2ab1ebca98..6479ad865e 100644 --- a/api/src/test/java/io/opencensus/common/FunctionsTest.java +++ b/api/src/test/java/io/opencensus/common/FunctionsTest.java @@ -42,4 +42,12 @@ public void testThrowIllegalArgumentException() { thrown.expect(IllegalArgumentException.class); f.apply("ignored"); } + + @Test + public void testThrowAssertionError() { + Function f = Functions.throwAssertionError(); + thrown.handleAssertionErrors(); + thrown.expect(AssertionError.class); + f.apply("ignored"); + } } From a5f4bfac3184fc87c0792da5723dac6012930f08 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 25 Jul 2017 00:01:57 +0200 Subject: [PATCH 0323/1581] Do not add automatic context propagation to CurrentContextExecutor and FixedContextExecutor from io.grpc.Context, which already propagate the context. --- .../contrib/agent/ExecutorInstrumentation.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java index c13e4bb8de..19cf181df0 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java @@ -15,6 +15,8 @@ import static net.bytebuddy.matcher.ElementMatchers.isAbstract; import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf; +import static net.bytebuddy.matcher.ElementMatchers.nameEndsWith; +import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.not; @@ -45,10 +47,13 @@ public DynamicType.Builder transform(DynamicType.Builder builder, } static ElementMatcher.Junction createMatcher() { - // TODO(stschmidt): Exclude known call sites that already propagate the context, such as - // io.grpc.Context#currentContextExecutor. - - return isSubTypeOf(Executor.class).and(not(isAbstract())); + // Matches implementations of Executor, but excludes CurrentContextExecutor and + // FixedContextExecutor from io.grpc.Context, which already propagate the context. + return isSubTypeOf(Executor.class) + .and(not(isAbstract())) + .and(not(nameStartsWith("io.grpc.Context$") + .and(nameEndsWith("CurrentContextExecutor") + .or(nameEndsWith("FixedContextExecutor"))))); } static AgentBuilder.Transformer createTransformer() { From 35b8fef45a1d2f1babcd19a8cc239028208859fe Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 25 Jul 2017 09:21:15 -0700 Subject: [PATCH 0324/1581] Improve comments about suppressed "unchecked" warnings. --- api/src/main/java/io/opencensus/common/Functions.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/io/opencensus/common/Functions.java b/api/src/main/java/io/opencensus/common/Functions.java index dcc1dab53b..67d1f9aa6d 100644 --- a/api/src/main/java/io/opencensus/common/Functions.java +++ b/api/src/main/java/io/opencensus/common/Functions.java @@ -75,7 +75,7 @@ public T apply(Object ignored) { * IllegalArgumentException}. */ public static Function throwIllegalArgumentException() { - // It is safe to cast a producer of Void to anything, because Void is always null. + // It is safe to cast this function to have any return type, since it never returns a result. @SuppressWarnings("unchecked") Function function = (Function) THROW_ILLEGAL_ARGUMENT_EXCEPTION; return function; @@ -88,7 +88,7 @@ public static Function throwIllegalArgumentException() { * AssertionError}. */ public static Function throwAssertionError() { - // It is safe to cast a producer of Void to anything, because Void is always null. + // It is safe to cast this function to have any return type, since it never returns a result. @SuppressWarnings("unchecked") Function function = (Function) THROW_ASSERTION_ERROR; return function; From 2bc1819ddea827b3059b04edf565919b1f928318 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 25 Jul 2017 09:28:52 -0700 Subject: [PATCH 0325/1581] Add TODO about creating a no-op ViewManager. --- core/src/main/java/io/opencensus/stats/StatsComponent.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/io/opencensus/stats/StatsComponent.java b/core/src/main/java/io/opencensus/stats/StatsComponent.java index 8e1dc8dfc5..4ea13c2353 100644 --- a/core/src/main/java/io/opencensus/stats/StatsComponent.java +++ b/core/src/main/java/io/opencensus/stats/StatsComponent.java @@ -52,6 +52,7 @@ private static final class NoopStatsComponent extends StatsComponent { @Override @Nullable public ViewManager getViewManager() { + // TODO(sebright): Decide whether to also provide a no-op implementation for the ViewManager. return null; } From 93ca8e0471eb3b5d9f05c53d59edde6c86cb4be5 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 26 Jul 2017 10:44:21 -0700 Subject: [PATCH 0326/1581] Work around Java 7 Travis build failure by specifying "dist: precise". The Java 7 build job started failing when Travis switched to Ubuntu Trusty. This commit sets the version back to Precise to fix the build while we determine how to upgrade or decide to remove the Java 7 job. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index fcab102a03..3f70740b3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ sudo: false +dist: precise language: java From f793449e47e58e8cbf3e1fb2c28c95f13bff7833 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 26 Jul 2017 10:17:29 -0700 Subject: [PATCH 0327/1581] Remove Provider.newInstance(...). newInstance was replaced by Provider.createInstance, which was designed to work with shading and Android. This is part of https://github.com/census-instrumentation/opencensus-java/issues/151 . --- .../java/io/opencensus/internal/Provider.java | 29 ------------------- .../io/opencensus/internal/ProviderTest.java | 14 --------- 2 files changed, 43 deletions(-) diff --git a/api/src/main/java/io/opencensus/internal/Provider.java b/api/src/main/java/io/opencensus/internal/Provider.java index 148b6c3876..224d92cffd 100644 --- a/api/src/main/java/io/opencensus/internal/Provider.java +++ b/api/src/main/java/io/opencensus/internal/Provider.java @@ -14,9 +14,6 @@ package io.opencensus.internal; import java.util.ServiceConfigurationError; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.annotation.Nullable; /** * Instrumentation specific service provider mechanism. @@ -27,32 +24,6 @@ * } */ public final class Provider { - private static final Logger logger = Logger.getLogger(Provider.class.getName()); - - /** - * Returns a new instance of the class specified with {@code name} by invoking the empty-argument - * constructor via reflections. If the specified class is not found, the {@code defaultValue} is - * returned. - */ - @SuppressWarnings("unchecked") - @Nullable - public static T newInstance(String name, @Nullable T defaultValue) { - try { - Class provider = Class.forName(name); - T result = (T) provider.getConstructor().newInstance(); - logger.fine("Loaded: " + name); - return result; - } catch (ClassNotFoundException e) { - logger.log(Level.FINE, "Falling back to " + defaultValue, e); - return defaultValue; - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new RuntimeException(e); - } - } - } /** * Tries to create an instance of the given rawClass as a subclass of the given superclass. diff --git a/api/src/test/java/io/opencensus/internal/ProviderTest.java b/api/src/test/java/io/opencensus/internal/ProviderTest.java index 30f5f0e87f..3ca13b725d 100644 --- a/api/src/test/java/io/opencensus/internal/ProviderTest.java +++ b/api/src/test/java/io/opencensus/internal/ProviderTest.java @@ -43,20 +43,6 @@ static class MyInterfaceImpl implements MyInterface { public MyInterfaceImpl() {} } - @Test - public void testGoodClass() { - assertThat( - Provider.newInstance("io.opencensus.internal.ProviderTest$GoodClass", null)) - .isNotNull(); - } - - @Test - public void testBadClass() { - assertThat( - Provider.newInstance("io.opencensus.internal.ProviderTest$BadClass", null)) - .isNull(); - } - @Test(expected = ServiceConfigurationError.class) public void createInstance_ThrowsErrorWhenClassIsPrivate() throws ClassNotFoundException { Provider.createInstance( From d779d0008dbf6c6094b09c8bea5fb1d284a3c4eb Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 26 Jul 2017 10:30:27 -0700 Subject: [PATCH 0328/1581] Update Javadoc. --- api/src/main/java/io/opencensus/internal/Provider.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/io/opencensus/internal/Provider.java b/api/src/main/java/io/opencensus/internal/Provider.java index 224d92cffd..05e36d092d 100644 --- a/api/src/main/java/io/opencensus/internal/Provider.java +++ b/api/src/main/java/io/opencensus/internal/Provider.java @@ -16,11 +16,12 @@ import java.util.ServiceConfigurationError; /** - * Instrumentation specific service provider mechanism. + * OpenCensus service provider mechanism. * *

{@code
- * // Initialize a static variable using reflection.
- * static final Foo foo = Provider.newInstance("Foo", new NoopFoo());
+ * // Initialize a variable using reflection.
+ * foo = Provider.createInstance(
+ *     Class.forName("FooImpl", true, classLoader), Foo.class);
  * }
*/ public final class Provider { From 5b4003af72a6f03f77119db15099b043462ca451 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 21 Jul 2017 15:19:31 -0700 Subject: [PATCH 0329/1581] Add Tags and TagsComponent classes to the 'tags' package. TagsComponent is an abstract class that holds the implementations for different parts of the 'tags' package. The class currently has one field, which is a skeleton for a new TagContextFactory class. It allows the implementation library to determine the implementation of TagContext, which could be important for performance. This commit also adds a Tags class, which instantiates the TagsComponent with reflection. The design is very similar to the 'stats' package. Tags corresponds to the Stats class, and TagsComponent corresponds to StatsComponent. --- .../io/opencensus/tags/TagContextFactory.java | 20 ++++++ .../main/java/io/opencensus/tags/Tags.java | 66 +++++++++++++++++++ .../io/opencensus/tags/TagsComponent.java | 25 +++++++ .../tags/TagContextFactoryImpl.java | 17 +++++ .../tags/TagsComponentImplBase.java | 24 +++++++ .../tags/TagsComponentImplLite.java | 17 +++++ .../java/io/opencensus/tags/TagsTest.java | 29 ++++++++ .../io/opencensus/tags/TagsComponentImpl.java | 17 +++++ .../java/io/opencensus/tags/TagsTest.java | 29 ++++++++ 9 files changed, 244 insertions(+) create mode 100644 core/src/main/java/io/opencensus/tags/TagContextFactory.java create mode 100644 core/src/main/java/io/opencensus/tags/Tags.java create mode 100644 core/src/main/java/io/opencensus/tags/TagsComponent.java create mode 100644 core_impl/src/main/java/io/opencensus/tags/TagContextFactoryImpl.java create mode 100644 core_impl/src/main/java/io/opencensus/tags/TagsComponentImplBase.java create mode 100644 core_impl_android/src/main/java/io/opencensus/tags/TagsComponentImplLite.java create mode 100644 core_impl_android/src/test/java/io/opencensus/tags/TagsTest.java create mode 100644 core_impl_java/src/main/java/io/opencensus/tags/TagsComponentImpl.java create mode 100644 core_impl_java/src/test/java/io/opencensus/tags/TagsTest.java diff --git a/core/src/main/java/io/opencensus/tags/TagContextFactory.java b/core/src/main/java/io/opencensus/tags/TagContextFactory.java new file mode 100644 index 0000000000..95b3ed4773 --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/TagContextFactory.java @@ -0,0 +1,20 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +/** + * Factory for new {@link TagContext}s and {@code TagContext}s based on the current context. + */ +public abstract class TagContextFactory { +} diff --git a/core/src/main/java/io/opencensus/tags/Tags.java b/core/src/main/java/io/opencensus/tags/Tags.java new file mode 100644 index 0000000000..a780130ff0 --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/Tags.java @@ -0,0 +1,66 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import com.google.common.annotations.VisibleForTesting; +import io.opencensus.internal.Provider; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.Nullable; + +/** Class for accessing the default {@link TagsComponent}. */ +public final class Tags { + private static final Logger logger = Logger.getLogger(Tags.class.getName()); + + private static final TagsComponent tagsComponent = + loadTagsComponent(Provider.getCorrectClassLoader(TagsComponent.class)); + + private Tags() {} + + public static TagContextFactory getTagContextFactory() { + return tagsComponent.getTagContextFactory(); + } + + // Any provider that may be used for TagsComponent can be added here. + @VisibleForTesting + @Nullable + static TagsComponent loadTagsComponent(ClassLoader classLoader) { + try { + // Call Class.forName with literal string name of the class to help shading tools. + return Provider.createInstance( + Class.forName("io.opencensus.tags.TagsComponentImpl", true, classLoader), + TagsComponent.class); + } catch (ClassNotFoundException e) { + logger.log( + Level.FINE, + "Couldn't load full implementation for TagsComponent, now trying to load lite " + + "implementation.", + e); + } + try { + // Call Class.forName with literal string name of the class to help shading tools. + return Provider.createInstance( + Class.forName("io.opencensus.tags.TagsComponentImplLite", true, classLoader), + TagsComponent.class); + } catch (ClassNotFoundException e) { + logger.log( + Level.FINE, + "Couldn't load lite implementation for TagsComponent, now using " + + "default implementation for TagsComponent.", + e); + } + // TODO: Add a no-op implementation. + return null; + } +} diff --git a/core/src/main/java/io/opencensus/tags/TagsComponent.java b/core/src/main/java/io/opencensus/tags/TagsComponent.java new file mode 100644 index 0000000000..fa7f401d19 --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/TagsComponent.java @@ -0,0 +1,25 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +/** + * Class that holds the implementations for {@link TagContextFactory}. + * + *

All objects returned by methods on {@code TagsComponent} are cacheable. + */ +public abstract class TagsComponent { + + /** Returns the default {@link TagContextFactory}. */ + abstract TagContextFactory getTagContextFactory(); +} diff --git a/core_impl/src/main/java/io/opencensus/tags/TagContextFactoryImpl.java b/core_impl/src/main/java/io/opencensus/tags/TagContextFactoryImpl.java new file mode 100644 index 0000000000..248a851bed --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/tags/TagContextFactoryImpl.java @@ -0,0 +1,17 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +final class TagContextFactoryImpl extends TagContextFactory { +} diff --git a/core_impl/src/main/java/io/opencensus/tags/TagsComponentImplBase.java b/core_impl/src/main/java/io/opencensus/tags/TagsComponentImplBase.java new file mode 100644 index 0000000000..3f789bf68e --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/tags/TagsComponentImplBase.java @@ -0,0 +1,24 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +/** Base implementation of {@link TagsComponent}. */ +public abstract class TagsComponentImplBase extends TagsComponent { + private final TagContextFactory tagContextFactory = new TagContextFactoryImpl(); + + @Override + public TagContextFactory getTagContextFactory() { + return tagContextFactory; + } +} diff --git a/core_impl_android/src/main/java/io/opencensus/tags/TagsComponentImplLite.java b/core_impl_android/src/main/java/io/opencensus/tags/TagsComponentImplLite.java new file mode 100644 index 0000000000..ec232e21f7 --- /dev/null +++ b/core_impl_android/src/main/java/io/opencensus/tags/TagsComponentImplLite.java @@ -0,0 +1,17 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +/** Android-compatible implementation of {@link TagsComponent}. */ +public final class TagsComponentImplLite extends TagsComponentImplBase {} diff --git a/core_impl_android/src/test/java/io/opencensus/tags/TagsTest.java b/core_impl_android/src/test/java/io/opencensus/tags/TagsTest.java new file mode 100644 index 0000000000..e9457b1224 --- /dev/null +++ b/core_impl_android/src/test/java/io/opencensus/tags/TagsTest.java @@ -0,0 +1,29 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Test for accessing the {@link TagsComponent} through the {@link Tags} class. */ +@RunWith(JUnit4.class) +public final class TagsTest { + @Test + public void getTagContextFactory() { + assertThat(Tags.getTagContextFactory()).isInstanceOf(TagContextFactoryImpl.class); + } +} diff --git a/core_impl_java/src/main/java/io/opencensus/tags/TagsComponentImpl.java b/core_impl_java/src/main/java/io/opencensus/tags/TagsComponentImpl.java new file mode 100644 index 0000000000..9c9404bd3c --- /dev/null +++ b/core_impl_java/src/main/java/io/opencensus/tags/TagsComponentImpl.java @@ -0,0 +1,17 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +/** Java 7 and 8 implementation of {@link TagsComponent}. */ +public final class TagsComponentImpl extends TagsComponentImplBase {} diff --git a/core_impl_java/src/test/java/io/opencensus/tags/TagsTest.java b/core_impl_java/src/test/java/io/opencensus/tags/TagsTest.java new file mode 100644 index 0000000000..e9457b1224 --- /dev/null +++ b/core_impl_java/src/test/java/io/opencensus/tags/TagsTest.java @@ -0,0 +1,29 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Test for accessing the {@link TagsComponent} through the {@link Tags} class. */ +@RunWith(JUnit4.class) +public final class TagsTest { + @Test + public void getTagContextFactory() { + assertThat(Tags.getTagContextFactory()).isInstanceOf(TagContextFactoryImpl.class); + } +} From 86ec06eb9bf452ddf122945e4155157edfb2bee7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 24 Jul 2017 09:39:24 -0700 Subject: [PATCH 0330/1581] Fix a typo. --- core/src/main/java/io/opencensus/tags/TagsComponent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/io/opencensus/tags/TagsComponent.java b/core/src/main/java/io/opencensus/tags/TagsComponent.java index fa7f401d19..24c3671153 100644 --- a/core/src/main/java/io/opencensus/tags/TagsComponent.java +++ b/core/src/main/java/io/opencensus/tags/TagsComponent.java @@ -14,7 +14,7 @@ package io.opencensus.tags; /** - * Class that holds the implementations for {@link TagContextFactory}. + * Class that holds the implementation for {@link TagContextFactory}. * *

All objects returned by methods on {@code TagsComponent} are cacheable. */ From 403762881af2aaa874d61262f5aeee81bdc99c79 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 24 Jul 2017 09:41:01 -0700 Subject: [PATCH 0331/1581] Add a TODO. --- core/src/main/java/io/opencensus/tags/TagContextFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/io/opencensus/tags/TagContextFactory.java b/core/src/main/java/io/opencensus/tags/TagContextFactory.java index 95b3ed4773..b4d06084de 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextFactory.java +++ b/core/src/main/java/io/opencensus/tags/TagContextFactory.java @@ -17,4 +17,5 @@ * Factory for new {@link TagContext}s and {@code TagContext}s based on the current context. */ public abstract class TagContextFactory { + // TODO(sebright): Add TagContext related methods to this class. } From 8edfd30a7e7d913216cf07b746f08482e0a55af7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 25 Jul 2017 14:47:48 -0700 Subject: [PATCH 0332/1581] Add a TODO about renaming TagContextFactory. --- core/src/main/java/io/opencensus/tags/TagContextFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/io/opencensus/tags/TagContextFactory.java b/core/src/main/java/io/opencensus/tags/TagContextFactory.java index b4d06084de..b68036b396 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextFactory.java +++ b/core/src/main/java/io/opencensus/tags/TagContextFactory.java @@ -16,6 +16,7 @@ /** * Factory for new {@link TagContext}s and {@code TagContext}s based on the current context. */ +// TODO(sebright): Pick a more descriptive name for this class. public abstract class TagContextFactory { // TODO(sebright): Add TagContext related methods to this class. } From a07afad67af0ee44297dfed771985a6aae4a0f93 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 26 Jul 2017 11:53:26 -0700 Subject: [PATCH 0333/1581] Improve Tags and TagsComponent Javadocs. --- core/src/main/java/io/opencensus/tags/Tags.java | 5 +++++ core/src/main/java/io/opencensus/tags/TagsComponent.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/io/opencensus/tags/Tags.java b/core/src/main/java/io/opencensus/tags/Tags.java index a780130ff0..026c394d4a 100644 --- a/core/src/main/java/io/opencensus/tags/Tags.java +++ b/core/src/main/java/io/opencensus/tags/Tags.java @@ -28,6 +28,11 @@ public final class Tags { private Tags() {} + /** + * Returns the default {@code TagContextFactory}. + * + * @return the default {@code TagContextFactory}. + */ public static TagContextFactory getTagContextFactory() { return tagsComponent.getTagContextFactory(); } diff --git a/core/src/main/java/io/opencensus/tags/TagsComponent.java b/core/src/main/java/io/opencensus/tags/TagsComponent.java index 24c3671153..67369ea850 100644 --- a/core/src/main/java/io/opencensus/tags/TagsComponent.java +++ b/core/src/main/java/io/opencensus/tags/TagsComponent.java @@ -20,6 +20,6 @@ */ public abstract class TagsComponent { - /** Returns the default {@link TagContextFactory}. */ + /** Returns the {@link TagContextFactory} for this implementation. */ abstract TagContextFactory getTagContextFactory(); } From d246143f39b8f281a4b712aaaf96fd8d469bbc69 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 26 Jul 2017 11:54:29 -0700 Subject: [PATCH 0334/1581] Add more tests for Tags class, and fix a NullPointerException. --- .../main/java/io/opencensus/tags/Tags.java | 2 +- .../java/io/opencensus/tags/TagsTest.java | 59 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 core/src/test/java/io/opencensus/tags/TagsTest.java diff --git a/core/src/main/java/io/opencensus/tags/Tags.java b/core/src/main/java/io/opencensus/tags/Tags.java index 026c394d4a..bc0dbd0f65 100644 --- a/core/src/main/java/io/opencensus/tags/Tags.java +++ b/core/src/main/java/io/opencensus/tags/Tags.java @@ -34,7 +34,7 @@ private Tags() {} * @return the default {@code TagContextFactory}. */ public static TagContextFactory getTagContextFactory() { - return tagsComponent.getTagContextFactory(); + return tagsComponent == null ? null : tagsComponent.getTagContextFactory(); } // Any provider that may be used for TagsComponent can be added here. diff --git a/core/src/test/java/io/opencensus/tags/TagsTest.java b/core/src/test/java/io/opencensus/tags/TagsTest.java new file mode 100644 index 0000000000..c4530263ef --- /dev/null +++ b/core/src/test/java/io/opencensus/tags/TagsTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Tags}. */ +@RunWith(JUnit4.class) +public class TagsTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void loadTagsComponent_UsesProvidedClassLoader() { + final RuntimeException toThrow = new RuntimeException("UseClassLoader"); + thrown.expect(RuntimeException.class); + thrown.expectMessage("UseClassLoader"); + Tags.loadTagsComponent( + new ClassLoader() { + @Override + public Class loadClass(String name) { + throw toThrow; + } + }); + } + + @Test + public void loadTagsComponent_IgnoresMissingClasses() { + ClassLoader classLoader = + new ClassLoader() { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + throw new ClassNotFoundException(); + } + }; + assertThat(Tags.loadTagsComponent(classLoader)).isNull(); + } + + @Test + public void defaultTagContextFactory() { + assertThat(Tags.getTagContextFactory()).isNull(); + } +} From ad4bf111ebc3e3223927f98f21ac96c134976a13 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Wed, 26 Jul 2017 16:41:32 -0700 Subject: [PATCH 0335/1581] Refactor to use more generic View and ViewData. (#462) * Refactor to use more generic View and ViewData. * Refactor Window and WindowData, update tests. * Check duplicate columns and aggregations in View. --- .../io/opencensus/stats/BucketBoundaries.java | 5 +- .../io/opencensus/stats/RpcViewConstants.java | 650 ++++++++++----- .../main/java/io/opencensus/stats/View.java | 192 +++-- .../java/io/opencensus/stats/ViewData.java | 223 +++-- .../stats/RpcViewConstantsTest.java | 122 ++- .../io/opencensus/stats/ViewDataTest.java | 264 +++--- .../java/io/opencensus/stats/ViewTest.java | 114 +-- .../io/opencensus/stats/MeasureToViewMap.java | 40 +- .../io/opencensus/stats/MutableViewData.java | 292 ++++--- .../io/opencensus/stats/StatsManager.java | 8 +- .../stats/MeasureToViewMapTest.java | 80 +- .../io/opencensus/stats/StatsContextTest.java | 142 ++-- .../opencensus/stats/ViewManagerImplTest.java | 787 +++++++++--------- 13 files changed, 1657 insertions(+), 1262 deletions(-) diff --git a/core/src/main/java/io/opencensus/stats/BucketBoundaries.java b/core/src/main/java/io/opencensus/stats/BucketBoundaries.java index 07f5ad1eb3..adcbefbcc4 100644 --- a/core/src/main/java/io/opencensus/stats/BucketBoundaries.java +++ b/core/src/main/java/io/opencensus/stats/BucketBoundaries.java @@ -23,14 +23,15 @@ import javax.annotation.concurrent.Immutable; /** - * The optional histogram bucket boundaries for a {@link Distribution}. + * The optional histogram bucket boundaries for an {@link Aggregation.Histogram}. */ @Immutable @AutoValue public abstract class BucketBoundaries { /** - * @param bucketBoundaries the boundaries for the buckets in the underlying {@link Distribution}. + * @param bucketBoundaries the boundaries for the buckets in the underlying + * {@link Aggregation.Histogram}. * @return a new {@code BucketBoundaries} with the specified boundaries. * @throws NullPointerException if {@code bucketBoundaries} is null. * @throws IllegalArgumentException if {@code bucketBoundaries} is not sorted. diff --git a/core/src/main/java/io/opencensus/stats/RpcViewConstants.java b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java index c105ad3cf0..75d9262b4e 100644 --- a/core/src/main/java/io/opencensus/stats/RpcViewConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcViewConstants.java @@ -40,8 +40,12 @@ import static io.opencensus.stats.RpcMeasureConstants.RPC_STATUS; import io.opencensus.common.Duration; -import io.opencensus.stats.View.DistributionView; -import io.opencensus.stats.View.IntervalView; +import io.opencensus.stats.Aggregation.Count; +import io.opencensus.stats.Aggregation.Histogram; +import io.opencensus.stats.Aggregation.Sum; +import io.opencensus.stats.View.Window; +import io.opencensus.stats.View.Window.Cumulative; +import io.opencensus.stats.View.Window.Interval; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -51,329 +55,591 @@ */ public final class RpcViewConstants { - // Common histogram bucket boundaries for bytes received/sets DistributionViews. + // Common histogram bucket boundaries for bytes received/sets Views. static final List RPC_BYTES_BUCKET_BOUNDARIES = Collections.unmodifiableList( Arrays.asList(0.0, 1024.0, 2048.0, 4096.0, 16384.0, 65536.0, 262144.0, 1048576.0, 4194304.0, 16777216.0, 67108864.0, 268435456.0, 1073741824.0, 4294967296.0)); - // Common histogram bucket boundaries for latency and elapsed-time DistributionViews. + // Common histogram bucket boundaries for latency and elapsed-time Views. static final List RPC_MILLIS_BUCKET_BOUNDARIES = Collections.unmodifiableList( Arrays.asList(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 13.0, 16.0, 20.0, 25.0, 30.0, 40.0, 50.0, 65.0, 80.0, 100.0, 130.0, 160.0, 200.0, 250.0, 300.0, 400.0, 500.0, 650.0, 800.0, 1000.0, 2000.0, 5000.0, 10000.0, 20000.0, 50000.0, 100000.0)); - // Rpc client {@link View}s. - public static final DistributionView RPC_CLIENT_ERROR_COUNT_VIEW = - DistributionView.create( + // Common histogram bucket boundaries for request/response count Views. + static final List RPC_COUNT_BUCKET_BOUNDARIES = Collections.unmodifiableList( + Arrays.asList(0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, + 4096.0, 8192.0, 16384.0, 32768.0, 65536.0)); + + static final List AGGREGATION_NO_HISTOGRAM = Collections.unmodifiableList( + Arrays.asList(Sum.create(), Count.create())); + + static final List AGGREGATION_WITH_BYTES_HISTOGRAM = Collections.unmodifiableList( + Arrays.asList(Sum.create(), Count.create(), + Histogram.create(BucketBoundaries.create(RPC_BYTES_BUCKET_BOUNDARIES)))); + + static final List AGGREGATION_WITH_MILLIS_HISTOGRAM = Collections.unmodifiableList( + Arrays.asList(Sum.create(), Count.create(), + Histogram.create(BucketBoundaries.create(RPC_MILLIS_BUCKET_BOUNDARIES)))); + + static final List AGGREGATION_WITH_COUNT_HISTOGRAM = Collections.unmodifiableList( + Arrays.asList(Sum.create(), Count.create(), + Histogram.create(BucketBoundaries.create(RPC_COUNT_BUCKET_BOUNDARIES)))); + + static final Duration MINUTE = Duration.create(60, 0); + static final Duration HOUR = Duration.create(60 * 60, 0); + static final Window CUMULATIVE = Cumulative.create(); + static final Window INTERVAL_MINUTE = Interval.create(MINUTE); + static final Window INTERVAL_HOUR = Interval.create(HOUR); + + // Rpc client cumulative {@link View}s. + public static final View RPC_CLIENT_ERROR_COUNT_VIEW = + View.create( View.Name.create("grpc.io/client/error_count/distribution_cumulative"), "RPC Errors", RPC_CLIENT_ERROR_COUNT, - DistributionAggregation.create(), - Arrays.asList(RPC_STATUS, RPC_CLIENT_METHOD)); - public static final DistributionView RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW = - DistributionView.create( + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_STATUS, RPC_CLIENT_METHOD), + CUMULATIVE); + public static final View RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW = + View.create( View.Name.create("grpc.io/client/roundtrip_latency/distribution_cumulative"), "Latency in msecs", RPC_CLIENT_ROUNDTRIP_LATENCY, - DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionView RPC_CLIENT_SERVER_ELAPSED_TIME_VIEW = - DistributionView.create( + AGGREGATION_WITH_MILLIS_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + CUMULATIVE); + public static final View RPC_CLIENT_SERVER_ELAPSED_TIME_VIEW = + View.create( View.Name.create("grpc.io/client/server_elapsed_time/distribution_cumulative"), "Server elapsed time in msecs", RPC_CLIENT_SERVER_ELAPSED_TIME, - DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionView RPC_CLIENT_REQUEST_BYTES_VIEW = - DistributionView.create( + AGGREGATION_WITH_MILLIS_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + CUMULATIVE); + public static final View RPC_CLIENT_REQUEST_BYTES_VIEW = + View.create( View.Name.create("grpc.io/client/request_bytes/distribution_cumulative"), "Request bytes", RPC_CLIENT_REQUEST_BYTES, - DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionView RPC_CLIENT_RESPONSE_BYTES_VIEW = - DistributionView.create( + AGGREGATION_WITH_BYTES_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + CUMULATIVE); + public static final View RPC_CLIENT_RESPONSE_BYTES_VIEW = + View.create( View.Name.create("grpc.io/client/response_bytes/distribution_cumulative"), "Response bytes", RPC_CLIENT_RESPONSE_BYTES, - DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionView RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_VIEW = - DistributionView.create( + AGGREGATION_WITH_BYTES_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + CUMULATIVE); + public static final View RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_VIEW = + View.create( View.Name.create("grpc.io/client/uncompressed_request_bytes/distribution_cumulative"), "Uncompressed Request bytes", RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, - DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionView RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_VIEW = - DistributionView.create( + AGGREGATION_WITH_BYTES_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + CUMULATIVE); + public static final View RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_VIEW = + View.create( View.Name.create("grpc.io/client/uncompressed_response_bytes/distribution_cumulative"), "Uncompressed Response bytes", RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, - DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionView RPC_CLIENT_REQUEST_COUNT_VIEW = - DistributionView.create( + AGGREGATION_WITH_BYTES_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + CUMULATIVE); + public static final View RPC_CLIENT_REQUEST_COUNT_VIEW = + View.create( View.Name.create("grpc.io/client/request_count/distribution_cumulative"), "Count of request messages per client RPC", RPC_CLIENT_REQUEST_COUNT, - DistributionAggregation.create(), - Arrays.asList(RPC_CLIENT_METHOD)); - public static final DistributionView RPC_CLIENT_RESPONSE_COUNT_VIEW = - DistributionView.create( + AGGREGATION_WITH_COUNT_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + CUMULATIVE); + public static final View RPC_CLIENT_RESPONSE_COUNT_VIEW = + View.create( View.Name.create("grpc.io/client/response_count/distribution_cumulative"), "Count of response messages per client RPC", RPC_CLIENT_RESPONSE_COUNT, - DistributionAggregation.create(), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_WITH_COUNT_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + CUMULATIVE); - // Rpc server {@link View}s. - public static final DistributionView RPC_SERVER_ERROR_COUNT_VIEW = - DistributionView.create( + // Rpc server cumulative {@link View}s. + public static final View RPC_SERVER_ERROR_COUNT_VIEW = + View.create( View.Name.create("grpc.io/server/error_count/distribution_cumulative"), "RPC Errors", RPC_SERVER_ERROR_COUNT, - DistributionAggregation.create(), - Arrays.asList(RPC_STATUS, RPC_SERVER_METHOD)); - public static final DistributionView RPC_SERVER_SERVER_LATENCY_VIEW = - DistributionView.create( + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_STATUS, RPC_SERVER_METHOD), + CUMULATIVE); + public static final View RPC_SERVER_SERVER_LATENCY_VIEW = + View.create( View.Name.create("grpc.io/server/server_latency/distribution_cumulative"), "Latency in msecs", RPC_SERVER_SERVER_LATENCY, - DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionView RPC_SERVER_SERVER_ELAPSED_TIME_VIEW = - DistributionView.create( + AGGREGATION_WITH_MILLIS_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + CUMULATIVE); + public static final View RPC_SERVER_SERVER_ELAPSED_TIME_VIEW = + View.create( View.Name.create("grpc.io/server/elapsed_time/distribution_cumulative"), "Server elapsed time in msecs", RPC_SERVER_SERVER_ELAPSED_TIME, - DistributionAggregation.create(RPC_MILLIS_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionView RPC_SERVER_REQUEST_BYTES_VIEW = - DistributionView.create( + AGGREGATION_WITH_MILLIS_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + CUMULATIVE); + public static final View RPC_SERVER_REQUEST_BYTES_VIEW = + View.create( View.Name.create("grpc.io/server/request_bytes/distribution_cumulative"), "Request bytes", RPC_SERVER_REQUEST_BYTES, - DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionView RPC_SERVER_RESPONSE_BYTES_VIEW = - DistributionView.create( + AGGREGATION_WITH_BYTES_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + CUMULATIVE); + public static final View RPC_SERVER_RESPONSE_BYTES_VIEW = + View.create( View.Name.create("grpc.io/server/response_bytes/distribution_cumulative"), "Response bytes", RPC_SERVER_RESPONSE_BYTES, - DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionView RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_VIEW = - DistributionView.create( + AGGREGATION_WITH_BYTES_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + CUMULATIVE); + public static final View RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_VIEW = + View.create( View.Name.create("grpc.io/server/uncompressed_request_bytes/distribution_cumulative"), "Uncompressed Request bytes", RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, - DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionView RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_VIEW = - DistributionView.create( + AGGREGATION_WITH_BYTES_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + CUMULATIVE); + public static final View RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_VIEW = + View.create( View.Name.create("grpc.io/server/uncompressed_response_bytes/distribution_cumulative"), "Uncompressed Response bytes", RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, - DistributionAggregation.create(RPC_BYTES_BUCKET_BOUNDARIES), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionView RPC_SERVER_REQUEST_COUNT_VIEW = - DistributionView.create( + AGGREGATION_WITH_BYTES_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + CUMULATIVE); + public static final View RPC_SERVER_REQUEST_COUNT_VIEW = + View.create( View.Name.create("grpc.io/server/request_count/distribution_cumulative"), "Count of request messages per server RPC", RPC_SERVER_REQUEST_COUNT, - DistributionAggregation.create(), - Arrays.asList(RPC_SERVER_METHOD)); - public static final DistributionView RPC_SERVER_RESPONSE_COUNT_VIEW = - DistributionView.create( + AGGREGATION_WITH_COUNT_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + CUMULATIVE); + public static final View RPC_SERVER_RESPONSE_COUNT_VIEW = + View.create( View.Name.create("grpc.io/server/response_count/distribution_cumulative"), "Count of response messages per server RPC", RPC_SERVER_RESPONSE_COUNT, - DistributionAggregation.create(), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_WITH_COUNT_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + CUMULATIVE); // Interval Stats - static final Duration MINUTE = Duration.create(60, 0); - static final Duration HOUR = Duration.create(60 * 60, 0); - // RPC client {@link IntervalView}s. - public static final IntervalView RPC_CLIENT_ROUNDTRIP_LATENCY_INTERVAL_VIEW = - IntervalView.create( + // RPC client interval {@link View}s. + public static final View RPC_CLIENT_ROUNDTRIP_LATENCY_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/client/roundtrip_latency/interval"), + "Minute stats for latency in msecs", + RPC_CLIENT_ROUNDTRIP_LATENCY, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_CLIENT_REQUEST_BYTES_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/client/request_bytes/interval"), + "Minute stats for request size in bytes", + RPC_CLIENT_REQUEST_BYTES, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_CLIENT_RESPONSE_BYTES_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/client/response_bytes/interval"), + "Minute stats for response size in bytes", + RPC_CLIENT_RESPONSE_BYTES, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_CLIENT_ERROR_COUNT_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/client/error_count/interval"), + "Minute stats for rpc errors", + RPC_CLIENT_ERROR_COUNT, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/client/uncompressed_request_bytes/interval"), + "Minute stats for uncompressed request size in bytes", + RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/client/uncompressed_response_bytes/interval"), + "Minute stats for uncompressed response size in bytes", + RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_CLIENT_SERVER_ELAPSED_TIME_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/client/server_elapsed_time/interval"), + "Minute stats for server elapsed time in msecs", + RPC_CLIENT_SERVER_ELAPSED_TIME, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_CLIENT_STARTED_COUNT_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/client/started_count/interval"), + "Minute stats on the number of client RPCs started", + RPC_CLIENT_STARTED_COUNT, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_CLIENT_FINISHED_COUNT_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/client/finished_count/interval"), + "Minute stats on the number of client RPCs finished", + RPC_CLIENT_FINISHED_COUNT, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_CLIENT_REQUEST_COUNT_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/client/request_count/interval"), + "Minute stats on the count of request messages per client RPC", + RPC_CLIENT_REQUEST_COUNT, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_CLIENT_RESPONSE_COUNT_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/client/response_count/interval"), + "Minute stats on the count of response messages per client RPC", + RPC_CLIENT_RESPONSE_COUNT, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_CLIENT_ROUNDTRIP_LATENCY_HOUR_VIEW = + View.create( View.Name.create("grpc.io/client/roundtrip_latency/interval"), - "Minute and Hour stats for latency in msecs", + "Hour stats for latency in msecs", RPC_CLIENT_ROUNDTRIP_LATENCY, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_CLIENT_REQUEST_BYTES_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_CLIENT_REQUEST_BYTES_HOUR_VIEW = + View.create( View.Name.create("grpc.io/client/request_bytes/interval"), - "Minute and Hour stats for request size in bytes", + "Hour stats for request size in bytes", RPC_CLIENT_REQUEST_BYTES, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_CLIENT_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_CLIENT_RESPONSE_BYTES_HOUR_VIEW = + View.create( View.Name.create("grpc.io/client/response_bytes/interval"), - "Minute and Hour stats for response size in bytes", + "Hour stats for response size in bytes", RPC_CLIENT_RESPONSE_BYTES, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_CLIENT_ERROR_COUNT_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_CLIENT_ERROR_COUNT_HOUR_VIEW = + View.create( View.Name.create("grpc.io/client/error_count/interval"), - "Minute and Hour stats for rpc errors", + "Hour stats for rpc errors", RPC_CLIENT_ERROR_COUNT, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_HOUR_VIEW = + View.create( View.Name.create("grpc.io/client/uncompressed_request_bytes/interval"), - "Minute and Hour stats for uncompressed request size in bytes", + "Hour stats for uncompressed request size in bytes", RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_HOUR_VIEW = + View.create( View.Name.create("grpc.io/client/uncompressed_response_bytes/interval"), - "Minute and Hour stats for uncompressed response size in bytes", + "Hour stats for uncompressed response size in bytes", RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_CLIENT_SERVER_ELAPSED_TIME_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_CLIENT_SERVER_ELAPSED_TIME_HOUR_VIEW = + View.create( View.Name.create("grpc.io/client/server_elapsed_time/interval"), - "Minute and Hour stats for server elapsed time in msecs", + "Hour stats for server elapsed time in msecs", RPC_CLIENT_SERVER_ELAPSED_TIME, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_CLIENT_STARTED_COUNT_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_CLIENT_STARTED_COUNT_HOUR_VIEW = + View.create( View.Name.create("grpc.io/client/started_count/interval"), - "Minute and Hour stats on the number of client RPCs started", + "Hour stats on the number of client RPCs started", RPC_CLIENT_STARTED_COUNT, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_CLIENT_FINISHED_COUNT_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_CLIENT_FINISHED_COUNT_HOUR_VIEW = + View.create( View.Name.create("grpc.io/client/finished_count/interval"), - "Minute and Hour stats on the number of client RPCs finished", + "Hour stats on the number of client RPCs finished", RPC_CLIENT_FINISHED_COUNT, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_CLIENT_REQUEST_COUNT_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_CLIENT_REQUEST_COUNT_HOUR_VIEW = + View.create( View.Name.create("grpc.io/client/request_count/interval"), - "Minute and Hour stats on the count of request messages per client RPC", + "Hour stats on the count of request messages per client RPC", RPC_CLIENT_REQUEST_COUNT, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_CLIENT_RESPONSE_COUNT_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_CLIENT_RESPONSE_COUNT_HOUR_VIEW = + View.create( View.Name.create("grpc.io/client/response_count/interval"), - "Minute and Hour stats on the count of response messages per client RPC", + "Hour stats on the count of response messages per client RPC", RPC_CLIENT_RESPONSE_COUNT, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_CLIENT_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_CLIENT_METHOD), + INTERVAL_HOUR); + + // RPC server interval {@link View}s. + public static final View RPC_SERVER_SERVER_LATENCY_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/server/server_latency/interval"), + "Minute stats for server latency in msecs", + RPC_SERVER_SERVER_LATENCY, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_SERVER_REQUEST_BYTES_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/server/request_bytes/interval"), + "Minute stats for request size in bytes", + RPC_SERVER_REQUEST_BYTES, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_SERVER_RESPONSE_BYTES_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/server/response_bytes/interval"), + "Minute stats for response size in bytes", + RPC_SERVER_RESPONSE_BYTES, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_SERVER_ERROR_COUNT_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/server/error_count/interval"), + "Minute stats for rpc errors", + RPC_SERVER_ERROR_COUNT, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/server/uncompressed_request_bytes/interval"), + "Minute stats for uncompressed request size in bytes", + RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/server/uncompressed_response_bytes/interval"), + "Minute stats for uncompressed response size in bytes", + RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_SERVER_SERVER_ELAPSED_TIME_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/server/server_elapsed_time/interval"), + "Minute stats for server elapsed time in msecs", + RPC_SERVER_SERVER_ELAPSED_TIME, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_SERVER_STARTED_COUNT_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/server/started_count/interval"), + "Minute stats on the number of server RPCs started", + RPC_SERVER_STARTED_COUNT, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_SERVER_FINISHED_COUNT_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/server/finished_count/interval"), + "Minute stats on the number of server RPCs finished", + RPC_SERVER_FINISHED_COUNT, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_SERVER_REQUEST_COUNT_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/server/request_count/interval"), + "Minute stats on the count of request messages per server RPC", + RPC_SERVER_REQUEST_COUNT, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_MINUTE); + + public static final View RPC_SERVER_RESPONSE_COUNT_MINUTE_VIEW = + View.create( + View.Name.create("grpc.io/server/response_count/interval"), + "Minute stats on the count of response messages per server RPC", + RPC_SERVER_RESPONSE_COUNT, + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_MINUTE); - // RPC server {@link IntervalView}s. - public static final IntervalView RPC_SERVER_SERVER_LATENCY_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_SERVER_SERVER_LATENCY_HOUR_VIEW = + View.create( View.Name.create("grpc.io/server/server_latency/interval"), - "Minute and Hour stats for server latency in msecs", + "Hour stats for server latency in msecs", RPC_SERVER_SERVER_LATENCY, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_SERVER_REQUEST_BYTES_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_SERVER_REQUEST_BYTES_HOUR_VIEW = + View.create( View.Name.create("grpc.io/server/request_bytes/interval"), - "Minute and Hour stats for request size in bytes", + "Hour stats for request size in bytes", RPC_SERVER_REQUEST_BYTES, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_SERVER_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_SERVER_RESPONSE_BYTES_HOUR_VIEW = + View.create( View.Name.create("grpc.io/server/response_bytes/interval"), - "Minute and Hour stats for response size in bytes", + "Hour stats for response size in bytes", RPC_SERVER_RESPONSE_BYTES, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_SERVER_ERROR_COUNT_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_SERVER_ERROR_COUNT_HOUR_VIEW = + View.create( View.Name.create("grpc.io/server/error_count/interval"), - "Minute and Hour stats for rpc errors", + "Hour stats for rpc errors", RPC_SERVER_ERROR_COUNT, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_HOUR_VIEW = + View.create( View.Name.create("grpc.io/server/uncompressed_request_bytes/interval"), - "Minute and Hour stats for uncompressed request size in bytes", + "Hour stats for uncompressed request size in bytes", RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_HOUR_VIEW = + View.create( View.Name.create("grpc.io/server/uncompressed_response_bytes/interval"), - "Minute and Hour stats for uncompressed response size in bytes", + "Hour stats for uncompressed response size in bytes", RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_SERVER_SERVER_ELAPSED_TIME_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_SERVER_SERVER_ELAPSED_TIME_HOUR_VIEW = + View.create( View.Name.create("grpc.io/server/server_elapsed_time/interval"), - "Minute and Hour stats for server elapsed time in msecs", + "Hour stats for server elapsed time in msecs", RPC_SERVER_SERVER_ELAPSED_TIME, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_SERVER_STARTED_COUNT_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_SERVER_STARTED_COUNT_HOUR_VIEW = + View.create( View.Name.create("grpc.io/server/started_count/interval"), - "Minute and Hour stats on the number of server RPCs started", + "Hour stats on the number of server RPCs started", RPC_SERVER_STARTED_COUNT, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_SERVER_FINISHED_COUNT_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_SERVER_FINISHED_COUNT_HOUR_VIEW = + View.create( View.Name.create("grpc.io/server/finished_count/interval"), - "Minute and Hour stats on the number of server RPCs finished", + "Hour stats on the number of server RPCs finished", RPC_SERVER_FINISHED_COUNT, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_SERVER_REQUEST_COUNT_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_SERVER_REQUEST_COUNT_HOUR_VIEW = + View.create( View.Name.create("grpc.io/server/request_count/interval"), - "Minute and Hour stats on the count of request messages per server RPC", + "Hour stats on the count of request messages per server RPC", RPC_SERVER_REQUEST_COUNT, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_HOUR); - public static final IntervalView RPC_SERVER_RESPONSE_COUNT_INTERVAL_VIEW = - IntervalView.create( + public static final View RPC_SERVER_RESPONSE_COUNT_HOUR_VIEW = + View.create( View.Name.create("grpc.io/server/response_count/interval"), - "Minute and Hour stats on the count of response messages per server RPC", + "Hour stats on the count of response messages per server RPC", RPC_SERVER_RESPONSE_COUNT, - IntervalAggregation.create(Arrays.asList(MINUTE, HOUR)), - Arrays.asList(RPC_SERVER_METHOD)); + AGGREGATION_NO_HISTOGRAM, + Arrays.asList(RPC_SERVER_METHOD), + INTERVAL_HOUR); // Visible for testing. RpcViewConstants() { diff --git a/core/src/main/java/io/opencensus/stats/View.java b/core/src/main/java/io/opencensus/stats/View.java index 059c235641..6cbddf29ef 100644 --- a/core/src/main/java/io/opencensus/stats/View.java +++ b/core/src/main/java/io/opencensus/stats/View.java @@ -13,10 +13,14 @@ package io.opencensus.stats; +import static com.google.common.base.Preconditions.checkArgument; + import com.google.auto.value.AutoValue; +import io.opencensus.common.Duration; import io.opencensus.common.Function; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import javax.annotation.concurrent.Immutable; @@ -25,7 +29,12 @@ * down by the unique set of matching tag values for each measure. */ @Immutable +@AutoValue public abstract class View { + + View() { + } + /** * Name of view. Must be unique. */ @@ -41,21 +50,60 @@ public abstract class View { */ public abstract Measure getMeasure(); + /** + * The {@link Aggregation}s associated with this {@link View}. {@link Aggregation}s should be + * unique within one view. + */ + public abstract List getAggregations(); + /** * Columns (a.k.a Tag Keys) to match with the associated {@link Measure}. - * If no dimensions are specified, then all stats are recorded. Columns must be unique. * - *

Note: The returned list is unmodifiable, attempts to update it will throw an - * UnsupportedOperationException. + *

{@link Measure} will be recorded in a "greedy" way. That is, every view aggregates every + * measure. This is similar to doing a GROUPBY on view’s columns. Columns must be unique. */ public abstract List getColumns(); /** - * Applies the given match function to the underlying data type. + * Returns the time {@link Window} for this {@code View}. + * + * @return the time {@link Window}. + */ + public abstract Window getWindow(); + + /** + * Constructs a new {@link View}. + * + * @param name the {@link Name} of view. Must be unique. + * @param description the description of view. + * @param measure the {@link Measure} to be aggregated by this view. + * @param aggregations basic {@link Aggregation}s that this view will support. The aggregation + * list should not contain duplicates. + * @param columns the {@link TagKey}s that this view will aggregate on. Columns should not contain + * duplicates. + * @param window the {@link Window} of view. + * @return a new {@link View}. */ - public abstract T match( - Function p0, - Function p1); + public static View create( + Name name, + String description, + Measure measure, + List aggregations, + List columns, + Window window) { + checkArgument(new HashSet(aggregations).size() == aggregations.size(), + "Aggregations have duplicate."); + checkArgument(new HashSet(columns).size() == columns.size(), + "Columns have duplicate."); + + return new AutoValue_View( + name, + description, + measure, + Collections.unmodifiableList(new ArrayList(aggregations)), + Collections.unmodifiableList(new ArrayList(columns)), + window); + } /** * The name of a {@code View}. @@ -85,77 +133,79 @@ public static Name create(String name) { } } - /** - * A {@link View} for distribution-base aggregations. - */ + /** The time window for a {@code View}. */ @Immutable - @AutoValue - public abstract static class DistributionView extends View { - /** - * Constructs a new {@link DistributionView}. - */ - public static DistributionView create( - Name name, - String description, - Measure measure, - DistributionAggregation distributionAggregation, - List tagKeys) { - return new AutoValue_View_DistributionView( - name, - description, - measure, - Collections.unmodifiableList(new ArrayList(tagKeys)), - distributionAggregation); - } - - /** - * The {@link DistributionAggregation} associated with this - * {@link DistributionView}. - */ - public abstract DistributionAggregation getDistributionAggregation(); + public abstract static class Window { - @Override - public T match( - Function p0, - Function p1) { - return p0.apply(this); - } - } + private Window() {} - /** - * A {@link View} for interval-based aggregations. - */ - @Immutable - @AutoValue - public abstract static class IntervalView extends View { /** - * Constructs a new {@link IntervalView}. + * Applies the given match function to the underlying data type. */ - public static IntervalView create( - Name name, - String description, - Measure measure, - IntervalAggregation intervalAggregation, - List tagKeys) { - return new AutoValue_View_IntervalView( - name, - description, - measure, - Collections.unmodifiableList(new ArrayList(tagKeys)), - intervalAggregation); + public abstract T match( + Function p0, + Function p1, + Function defaultFunction); + + /** Cumulative (infinite interval) time {@code Window}. */ + @Immutable + @AutoValue + public abstract static class Cumulative extends Window { + + private static final Cumulative CUMULATIVE = new AutoValue_View_Window_Cumulative(); + + Cumulative() {} + + /** + * Constructs a cumulative {@code Window} that does not have an explicit {@code Duration}. + * Instead, cumulative {@code Window} always has an interval of infinite {@code Duration}. + * + * @return a cumulative {@code Window}. + */ + public static Cumulative create() { + return CUMULATIVE; + } + + @Override + public final T match( + Function p0, + Function p1, + Function defaultFunction) { + return p0.apply(this); + } } - /** - * The {@link IntervalAggregation} associated with this - * {@link IntervalView}. - */ - public abstract IntervalAggregation getIntervalAggregation(); - - @Override - public T match( - Function p0, - Function p1) { - return p1.apply(this); + /** Interval (finite interval) time {@code Window.} */ + @Immutable + @AutoValue + public abstract static class Interval extends Window { + + Interval() {} + + /** + * Returns the {@code Duration} associated with this {@code Interval}. + * + * @return a {@code Duration}. + */ + public abstract Duration getDuration(); + + + /** + * Constructs an interval {@code Window} that has a finite explicit {@code Duration}. + * + * @return an interval {@code Window}. + */ + public static Interval create(Duration duration) { + return new AutoValue_View_Window_Interval(duration); + } + + @Override + public final T match( + Function p0, + Function p1, + Function defaultFunction) { + return p1.apply(this); + } } } } diff --git a/core/src/main/java/io/opencensus/stats/ViewData.java b/core/src/main/java/io/opencensus/stats/ViewData.java index 9275394115..7fd130b299 100644 --- a/core/src/main/java/io/opencensus/stats/ViewData.java +++ b/core/src/main/java/io/opencensus/stats/ViewData.java @@ -15,115 +15,164 @@ import com.google.auto.value.AutoValue; import io.opencensus.common.Function; +import io.opencensus.common.Functions; import io.opencensus.common.Timestamp; -import io.opencensus.stats.View.DistributionView; -import io.opencensus.stats.View.IntervalView; + import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import javax.annotation.concurrent.Immutable; -/** - * The aggregated data for a particular {@link View}. - */ + +/** The aggregated data for a particular {@link View}. */ @Immutable +@AutoValue public abstract class ViewData { - /** - * The {@link View} associated with this {@link ViewData}. - */ + + // Prevents this class from being subclassed anywhere else. + ViewData() {} + + /** The {@link View} associated with this {@link ViewData}. */ public abstract View getView(); /** - * Applies the given match function to the underlying data type. + * The {@link AggregationData}s grouped by combination of {@link TagValue}s, associated with this + * {@link ViewData}. */ - public abstract T match( - Function p0, - Function p1); - - // Prevents this class from being subclassed anywhere else. - private ViewData() { - } + public abstract Map, List> getAggregationMap(); /** - * A {@link ViewData} for distribution-based aggregations. + * Returns the {@link WindowData} associated with this {@link ViewData}. + * + * @return the {@code WindowData}. */ - @Immutable - @AutoValue - public abstract static class DistributionViewData extends ViewData { - /** - * Constructs a new {@link DistributionViewData}. - */ - public static DistributionViewData create(DistributionView distributionView, - List distributionAggregates, Timestamp start, Timestamp end) { - return new AutoValue_ViewData_DistributionViewData( - distributionView, - Collections.unmodifiableList( - new ArrayList(distributionAggregates)), - start, - end); - } + public abstract WindowData getWindowData(); + + /** Constructs a new {@link ViewData}. */ + public static ViewData create( + View view, Map, List> map, final WindowData windowData) { + view.getWindow() + .match( + new Function() { + @Override + public Void apply(View.Window.Cumulative arg) { + if (!(windowData instanceof WindowData.CumulativeData)) { + throw new IllegalArgumentException( + "Window and WindowData types mismatch. " + + "Window: " + + arg + + " WindowData: " + + windowData); + } + return null; + } + }, + new Function() { + @Override + public Void apply(View.Window.Interval arg) { + if (!(windowData instanceof WindowData.IntervalData)) { + throw new IllegalArgumentException( + "Window and WindowData types mismatch. " + + "Window: " + + arg + + " WindowData: " + + windowData); + } + return null; + } + }, + Functions.throwIllegalArgumentException()); - @Override - public abstract DistributionView getView(); - - /** - * The {@link DistributionAggregate}s associated with this {@link DistributionViewData}. - * - *

Note: The returned list is unmodifiable, attempts to update it will throw an - * UnsupportedOperationException. - */ - public abstract List getDistributionAggregates(); - - /** - * Returns start timestamp for this aggregation. - */ - public abstract Timestamp getStart(); - - /** - * Returns end timestamp for this aggregation. - */ - public abstract Timestamp getEnd(); - - @Override - public final T match( - Function p0, - Function p1) { - return p0.apply(this); + Map, List> deepCopy = + new HashMap, List>(); + for (Entry, List> entry : map.entrySet()) { + deepCopy.put( + Collections.unmodifiableList(new ArrayList(entry.getKey())), + Collections.unmodifiableList(new ArrayList(entry.getValue()))); } + + return new AutoValue_ViewData(view, Collections.unmodifiableMap(deepCopy), windowData); } - /** - * A {@link ViewData} for interval-base aggregations. - */ + /** The {@code WindowData} for a {@link ViewData}. */ @Immutable - @AutoValue - public abstract static class IntervalViewData extends ViewData { - /** - * Constructs a new {@link IntervalViewData}. - */ - public static IntervalViewData create(IntervalView intervalView, - List intervalAggregates) { - return new AutoValue_ViewData_IntervalViewData( - intervalView, - Collections.unmodifiableList(new ArrayList(intervalAggregates))); + public abstract static class WindowData { + + private WindowData() {} + + /** Applies the given match function to the underlying data type. */ + public abstract T match( + Function p0, + Function p1, + Function defaultFunction); + + /** Cumulative {@code WindowData.} */ + @Immutable + @AutoValue + public abstract static class CumulativeData extends WindowData { + + CumulativeData() {} + + /** + * Returns the start {@code Timestamp} for a {@link CumulativeData}. + * + * @return the start {@code Timestamp}. + */ + public abstract Timestamp getStart(); + + /** + * Returns the end {@code Timestamp} for a {@link CumulativeData}. + * + * @return the end {@code Timestamp}. + */ + public abstract Timestamp getEnd(); + + @Override + public final T match( + Function p0, + Function p1, + Function defaultFunction) { + return p0.apply(this); + } + + /** Constructs a new {@link CumulativeData}. */ + public static CumulativeData create(Timestamp start, Timestamp end) { + if (start.compareTo(end) > 0) { + throw new IllegalArgumentException("Start time is later than end time."); + } + return new AutoValue_ViewData_WindowData_CumulativeData(start, end); + } } - @Override - public abstract IntervalView getView(); - - /** - * The {@link IntervalAggregate}s associated with this {@link IntervalViewData}. - * - *

Note: The returned list is unmodifiable, attempts to update it will throw an - * UnsupportedOperationException. - */ - public abstract List getIntervalAggregates(); - - @Override - public final T match( - Function p0, - Function p1) { - return p1.apply(this); + /** Interval {@code WindowData.} */ + @Immutable + @AutoValue + public abstract static class IntervalData extends WindowData { + + IntervalData() {} + + /** + * Returns the end {@code Timestamp} for an {@link IntervalData}. + * + * @return the end {@code Timestamp}. + */ + public abstract Timestamp getEnd(); + + @Override + public final T match( + Function p0, + Function p1, + Function defaultFunction) { + return p1.apply(this); + } + + /** Constructs a new {@link IntervalData}. */ + public static IntervalData create(Timestamp end) { + return new AutoValue_ViewData_WindowData_IntervalData(end); + } } } } diff --git a/core/src/test/java/io/opencensus/stats/RpcViewConstantsTest.java b/core/src/test/java/io/opencensus/stats/RpcViewConstantsTest.java index 6ddaf938a0..ab5fc3deec 100644 --- a/core/src/test/java/io/opencensus/stats/RpcViewConstantsTest.java +++ b/core/src/test/java/io/opencensus/stats/RpcViewConstantsTest.java @@ -13,12 +13,18 @@ package io.opencensus.stats; -import static com.google.common.truth.Truth.assertThat; - +import io.opencensus.common.Duration; +import io.opencensus.stats.Aggregation.Count; +import io.opencensus.stats.Aggregation.Histogram; +import io.opencensus.stats.Aggregation.Sum; +import io.opencensus.stats.View.Window.Cumulative; +import io.opencensus.stats.View.Window.Interval; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import static com.google.common.truth.Truth.assertThat; + /** * Test for {@link RpcViewConstants}. */ @@ -27,6 +33,53 @@ public final class RpcViewConstantsTest { @Test public void testConstants() { + + // Test bucket boundaries. + assertThat(RpcViewConstants.RPC_BYTES_BUCKET_BOUNDARIES).containsExactly( + 0.0, 1024.0, 2048.0, 4096.0, 16384.0, 65536.0, 262144.0, 1048576.0, 4194304.0, + 16777216.0, 67108864.0, 268435456.0, 1073741824.0, 4294967296.0).inOrder(); + assertThat(RpcViewConstants.RPC_MILLIS_BUCKET_BOUNDARIES).containsExactly( + 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 13.0, 16.0, 20.0, 25.0, 30.0, + 40.0, 50.0, 65.0, 80.0, 100.0, 130.0, 160.0, 200.0, 250.0, 300.0, 400.0, 500.0, 650.0, + 800.0, 1000.0, 2000.0, 5000.0, 10000.0, 20000.0, 50000.0, 100000.0).inOrder(); + assertThat(RpcViewConstants.RPC_COUNT_BUCKET_BOUNDARIES).containsExactly( + 0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, + 4096.0, 8192.0, 16384.0, 32768.0, 65536.0).inOrder(); + + // Test Aggregations + assertThat(RpcViewConstants.AGGREGATION_NO_HISTOGRAM) + .containsExactly(Sum.create(), Count.create()) + .inOrder(); + assertThat(RpcViewConstants.AGGREGATION_WITH_BYTES_HISTOGRAM) + .containsExactly( + Sum.create(), + Count.create(), + Histogram.create(BucketBoundaries.create(RpcViewConstants.RPC_BYTES_BUCKET_BOUNDARIES))) + .inOrder(); + assertThat(RpcViewConstants.AGGREGATION_WITH_COUNT_HISTOGRAM) + .containsExactly( + Sum.create(), + Count.create(), + Histogram.create(BucketBoundaries.create(RpcViewConstants.RPC_COUNT_BUCKET_BOUNDARIES))) + .inOrder(); + assertThat(RpcViewConstants.AGGREGATION_WITH_MILLIS_HISTOGRAM) + .containsExactly( + Sum.create(), + Count.create(), + Histogram.create( + BucketBoundaries.create(RpcViewConstants.RPC_MILLIS_BUCKET_BOUNDARIES))) + .inOrder(); + + // Test Duration and Window + assertThat(RpcViewConstants.MINUTE).isEqualTo(Duration.create(60, 0)); + assertThat(RpcViewConstants.HOUR).isEqualTo(Duration.create(60 * 60, 0)); + assertThat(RpcViewConstants.CUMULATIVE).isEqualTo(Cumulative.create()); + assertThat(RpcViewConstants.INTERVAL_MINUTE).isEqualTo( + Interval.create(RpcViewConstants.MINUTE)); + assertThat(RpcViewConstants.INTERVAL_HOUR).isEqualTo( + Interval.create(RpcViewConstants.HOUR)); + + // Test client distribution view descriptors. assertThat(RpcViewConstants.RPC_CLIENT_ERROR_COUNT_VIEW).isNotNull(); assertThat(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW).isNotNull(); @@ -49,29 +102,52 @@ public void testConstants() { assertThat(RpcViewConstants.RPC_SERVER_RESPONSE_COUNT_VIEW).isNotNull(); // Test client interval view descriptors. - assertThat(RpcViewConstants.RPC_CLIENT_ERROR_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_CLIENT_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_CLIENT_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_CLIENT_STARTED_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_CLIENT_FINISHED_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_CLIENT_SERVER_ELAPSED_TIME_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_CLIENT_REQUEST_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_CLIENT_RESPONSE_COUNT_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_ERROR_COUNT_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_REQUEST_BYTES_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_RESPONSE_BYTES_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_STARTED_COUNT_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_FINISHED_COUNT_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_SERVER_ELAPSED_TIME_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_REQUEST_COUNT_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_RESPONSE_COUNT_MINUTE_VIEW).isNotNull(); + + assertThat(RpcViewConstants.RPC_CLIENT_ERROR_COUNT_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_REQUEST_BYTES_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_RESPONSE_BYTES_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_UNCOMPRESSED_REQUEST_BYTES_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_UNCOMPRESSED_RESPONSE_BYTES_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_STARTED_COUNT_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_FINISHED_COUNT_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_SERVER_ELAPSED_TIME_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_REQUEST_COUNT_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_CLIENT_RESPONSE_COUNT_HOUR_VIEW).isNotNull(); // Test server interval view descriptors. - assertThat(RpcViewConstants.RPC_SERVER_ERROR_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_SERVER_SERVER_LATENCY_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_SERVER_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_SERVER_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_SERVER_STARTED_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_SERVER_FINISHED_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_SERVER_REQUEST_COUNT_INTERVAL_VIEW).isNotNull(); - assertThat(RpcViewConstants.RPC_SERVER_RESPONSE_COUNT_INTERVAL_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_ERROR_COUNT_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_SERVER_LATENCY_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_REQUEST_BYTES_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_RESPONSE_BYTES_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_STARTED_COUNT_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_FINISHED_COUNT_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_REQUEST_COUNT_MINUTE_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_RESPONSE_COUNT_MINUTE_VIEW).isNotNull(); + + assertThat(RpcViewConstants.RPC_SERVER_ERROR_COUNT_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_SERVER_LATENCY_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_REQUEST_BYTES_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_RESPONSE_BYTES_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_UNCOMPRESSED_REQUEST_BYTES_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_UNCOMPRESSED_RESPONSE_BYTES_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_STARTED_COUNT_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_FINISHED_COUNT_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_REQUEST_COUNT_HOUR_VIEW).isNotNull(); + assertThat(RpcViewConstants.RPC_SERVER_RESPONSE_COUNT_HOUR_VIEW).isNotNull(); } @Test(expected = AssertionError.class) diff --git a/core/src/test/java/io/opencensus/stats/ViewDataTest.java b/core/src/test/java/io/opencensus/stats/ViewDataTest.java index d4213ff1c9..42db54c1a7 100644 --- a/core/src/test/java/io/opencensus/stats/ViewDataTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewDataTest.java @@ -14,143 +14,177 @@ package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableMap; import com.google.common.testing.EqualsTester; import io.opencensus.common.Duration; import io.opencensus.common.Function; +import io.opencensus.common.Functions; import io.opencensus.common.Timestamp; -import io.opencensus.stats.DistributionAggregate.Range; -import io.opencensus.stats.IntervalAggregate.Interval; -import io.opencensus.stats.ViewData.DistributionViewData; -import io.opencensus.stats.ViewData.IntervalViewData; -import io.opencensus.stats.View.DistributionView; -import io.opencensus.stats.View.IntervalView; +import io.opencensus.stats.Aggregation.Count; +import io.opencensus.stats.Aggregation.Histogram; +import io.opencensus.stats.Aggregation.Mean; +import io.opencensus.stats.Aggregation.Range; +import io.opencensus.stats.Aggregation.StdDev; +import io.opencensus.stats.Aggregation.Sum; +import io.opencensus.stats.AggregationData.CountData; +import io.opencensus.stats.AggregationData.HistogramData; +import io.opencensus.stats.AggregationData.MeanData; +import io.opencensus.stats.AggregationData.RangeData; +import io.opencensus.stats.AggregationData.StdDevData; +import io.opencensus.stats.AggregationData.SumData; +import io.opencensus.stats.View.Window; +import io.opencensus.stats.View.Window.Cumulative; +import io.opencensus.stats.View.Window.Interval; +import io.opencensus.stats.ViewData.WindowData; +import io.opencensus.stats.ViewData.WindowData.CumulativeData; +import io.opencensus.stats.ViewData.WindowData.IntervalData; import java.util.Arrays; import java.util.Collections; import java.util.List; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** Tests for class {@link ViewData}. */ @RunWith(JUnit4.class) public final class ViewDataTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Test public void testDistributionViewData() { - DistributionAggregation aggregation = - DistributionAggregation.create(Arrays.asList(10.0, 20.0, 30.0, 40.0)); - final DistributionView view = - DistributionView.create( - name, description, measure, aggregation, tagKeys); - final List aggregations = Arrays.asList( - DistributionAggregate.create(5, 5.0, 15.0, Range.create(1.0, 5.0), tags1, - Arrays.asList(1L, 1L, 1L, 1L, 1L)), - DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), tags2, - Arrays.asList(2L, 2L, 2L, 2L, 2L))); - final Timestamp start = Timestamp.fromMillis(1000); - final Timestamp end = Timestamp.fromMillis(2000); - final ViewData viewData = DistributionViewData.create(view, aggregations, start, end); - + View view = + View.create(name, description, measure, AGGREGATIONS, tagKeys, CUMULATIVE); + Timestamp start = Timestamp.fromMillis(1000); + Timestamp end = Timestamp.fromMillis(2000); + WindowData windowData = CumulativeData.create(start, end); + ViewData viewData = ViewData.create(view, ENTRIES, windowData); assertThat(viewData.getView()).isEqualTo(view); - assertTrue(viewData.match( - new Function () { - @Override public Boolean apply(DistributionViewData dViewData) { - return dViewData == viewData - && dViewData.getView().equals(view) - && shallowListEquals(dViewData.getDistributionAggregates(), aggregations) - && dViewData.getStart().equals(start) - && dViewData.getEnd().equals(end); - } - }, - new Function () { - @Override public Boolean apply(IntervalViewData iViewData) { - return false; - } - })); + assertThat(viewData.getAggregationMap()).isEqualTo(ENTRIES); + assertThat(viewData.getWindowData()).isEqualTo(windowData); } @Test public void testIntervalViewData() { - IntervalAggregation aggregation = - IntervalAggregation.create(Arrays.asList(Duration.fromMillis(111))); - final IntervalView view = - IntervalView.create( - name, description, measure, aggregation, tagKeys); - final List aggregations = Arrays.asList( - IntervalAggregate.create(tags1, Arrays.asList( - Interval.create(Duration.fromMillis(111), 10, 100))), - IntervalAggregate.create(tags2, Arrays.asList( - Interval.create(Duration.fromMillis(111), 10, 100)))); - - final ViewData viewData = IntervalViewData.create(view, aggregations); + View view = View.create( + name, description, measure, AGGREGATIONS, tagKeys, INTERVAL_HOUR); + Timestamp end = Timestamp.fromMillis(2000); + WindowData windowData = IntervalData.create(end); + ViewData viewData = ViewData.create(view, ENTRIES, windowData); assertThat(viewData.getView()).isEqualTo(view); - assertTrue(viewData.match( - new Function () { - @Override public Boolean apply(DistributionViewData dViewData) { - return false; - } - }, - new Function () { - @Override public Boolean apply(IntervalViewData iViewData) { - return iViewData == viewData - && iViewData.getView().equals(view) - && shallowListEquals(iViewData.getIntervalAggregates(), aggregations); - } - })); + assertThat(viewData.getAggregationMap()).isEqualTo(ENTRIES); + assertThat(viewData.getWindowData()).isEqualTo(windowData); } @Test public void testViewDataEquals() { - DistributionView dView = - DistributionView.create( - name, - description, - measure, - DistributionAggregation.create(Arrays.asList(10.0)), - tagKeys); - List dAggregates = - Arrays.asList( - DistributionAggregate.create( - 5, 5.0, 15.0, Range.create(1.0, 5.0), tags1, Arrays.asList(1L))); - IntervalView iView = - IntervalView.create( - name, - description, - measure, - IntervalAggregation.create(Arrays.asList(Duration.fromMillis(111))), - tagKeys); - List iAggregates = - Arrays.asList( - IntervalAggregate.create( - tags1, Arrays.asList(Interval.create(Duration.fromMillis(111), 10, 100)))); + View dView = + View.create(name, description, measure, AGGREGATIONS, tagKeys, CUMULATIVE); + View iView = + View.create(name, description, measure, AGGREGATIONS, tagKeys, INTERVAL_HOUR); new EqualsTester() .addEqualityGroup( - DistributionViewData.create( - dView, - dAggregates, - Timestamp.fromMillis(1000), - Timestamp.fromMillis(2000)), - DistributionViewData.create( + ViewData.create( + dView, ENTRIES, + CumulativeData.create( + Timestamp.fromMillis(1000), Timestamp.fromMillis(2000))), + ViewData.create( dView, - dAggregates, - Timestamp.fromMillis(1000), - Timestamp.fromMillis(2000))) + ENTRIES, + CumulativeData.create( + Timestamp.fromMillis(1000), Timestamp.fromMillis(2000)))) .addEqualityGroup( - DistributionViewData.create( + ViewData.create( dView, - dAggregates, - Timestamp.fromMillis(1000), - Timestamp.fromMillis(3000))) + ENTRIES, + CumulativeData.create( + Timestamp.fromMillis(1000), Timestamp.fromMillis(3000)))) .addEqualityGroup( - IntervalViewData.create(iView, iAggregates), - IntervalViewData.create(iView, iAggregates)) + ViewData.create( + iView, ENTRIES, + IntervalData.create(Timestamp.fromMillis(2000))), + ViewData.create( + iView, ENTRIES, + IntervalData.create(Timestamp.fromMillis(2000)))) .addEqualityGroup( - IntervalViewData.create(iView, Collections.emptyList())) + ViewData.create( + iView, Collections., List>emptyMap(), + IntervalData.create(Timestamp.fromMillis(2000)))) .testEquals(); } + @Test + public void testWindowDataMatch() { + final Timestamp start = Timestamp.fromMillis(1000); + final Timestamp end = Timestamp.fromMillis(2000); + final WindowData windowData1 = CumulativeData.create(start, end); + final WindowData windowData2 = IntervalData.create(end); + windowData1.match( + new Function() { + @Override + public Void apply(CumulativeData windowData) { + assertThat(windowData.getStart()).isEqualTo(start); + assertThat(windowData.getEnd()).isEqualTo(end); + return null; + } + }, + new Function() { + @Override + public Void apply(IntervalData windowData) { + fail("CumulativeData expected."); + return null; + } + }, + Functions.throwIllegalArgumentException()); + windowData2.match( + new Function() { + @Override + public Void apply(CumulativeData windowData) { + fail("IntervalData expected."); + return null; + } + }, + new Function() { + @Override + public Void apply(IntervalData windowData) { + assertThat(windowData.getEnd()).isEqualTo(end); + return null; + } + }, + Functions.throwIllegalArgumentException()); + } + + @Test + public void preventWindowAndWindowDataMismatch() { + thrown.expect(IllegalArgumentException.class); + ViewData.create( + View.create(name, description, measure, AGGREGATIONS, tagKeys, INTERVAL_HOUR), + ENTRIES, + CumulativeData.create( + Timestamp.fromMillis(1000), Timestamp.fromMillis(2000))); + } + + @Test + public void preventWindowAndWindowDataMismatch2() { + thrown.expect(IllegalArgumentException.class); + ViewData.create( + View.create(name, description, measure, AGGREGATIONS, tagKeys, CUMULATIVE), + ENTRIES, + IntervalData.create(Timestamp.fromMillis(1000))); + } + + @Test + public void preventStartTimeLaterThanEndTime() { + thrown.expect(IllegalArgumentException.class); + CumulativeData.create(Timestamp.fromMillis(3000), Timestamp.fromMillis(2000)); + } + // tag keys private static final TagKey K1 = TagKey.create("k1"); private static final TagKey K2 = TagKey.create("k2"); @@ -162,9 +196,23 @@ public void testViewDataEquals() { private static final TagValue V10 = TagValue.create("v10"); private static final TagValue V20 = TagValue.create("v20"); - // tags - List tags1 = Arrays.asList(Tag.create(K1, V1), Tag.create(K2, V2)); - List tags2 = Arrays.asList(Tag.create(K1, V10), Tag.create(K2, V20)); + private static final Window CUMULATIVE = Cumulative.create(); + private static final Window INTERVAL_HOUR = Interval.create(Duration.create(3600, 0)); + + private static final BucketBoundaries BUCKET_BOUNDARIES = BucketBoundaries.create( + Arrays.asList(10.0, 20.0, 30.0, 40.0)); + + private static final List AGGREGATIONS = Collections.unmodifiableList(Arrays.asList( + Sum.create(), Count.create(), Range.create(), Histogram.create(BUCKET_BOUNDARIES), + Mean.create(), StdDev.create())); + + private static final ImmutableMap, List> ENTRIES = ImmutableMap.of( + Arrays.asList(V1, V2), + Arrays.asList(SumData.create(0), CountData.create(1), HistogramData.create(1, 0, 0, 0, 0), + RangeData.create(0, 0), MeanData.create(0), StdDevData.create(0)), + Arrays.asList(V10, V20), + Arrays.asList(SumData.create(50), CountData.create(2), HistogramData.create(0, 0, 2, 0, 0), + RangeData.create(25, 25), MeanData.create(25), StdDevData.create(0))); // name private final View.Name name = View.Name.create("test-view"); @@ -175,16 +223,4 @@ public void testViewDataEquals() { "measure", "measure description", "1"); - - private static final boolean shallowListEquals(List l1, List l2) { - if (l1.size() != l2.size()) { - return false; - } - for (int i = 0; i < l1.size(); i++) { - if (l1.get(i) != l2.get(i)) { - return false; - } - } - return true; - } } diff --git a/core/src/test/java/io/opencensus/stats/ViewTest.java b/core/src/test/java/io/opencensus/stats/ViewTest.java index 4845aac361..0ead370dd2 100644 --- a/core/src/test/java/io/opencensus/stats/ViewTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewTest.java @@ -14,13 +14,13 @@ package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertTrue; import com.google.common.testing.EqualsTester; import io.opencensus.common.Duration; -import io.opencensus.common.Function; -import io.opencensus.stats.View.DistributionView; -import io.opencensus.stats.View.IntervalView; +import io.opencensus.stats.Aggregation.Count; +import io.opencensus.stats.Aggregation.Sum; +import io.opencensus.stats.View.Window.Cumulative; +import io.opencensus.stats.View.Window.Interval; import java.util.Arrays; import java.util.List; import org.junit.Test; @@ -32,99 +32,68 @@ public final class ViewTest { @Test public void testDistributionView() { - DistributionAggregation dAggr = DistributionAggregation.create(); - final View view = DistributionView.create( - name, description, measure, dAggr, keys); - + final View view = View.create( + name, description, measure, aggregations, keys, Cumulative.create()); assertThat(view.getName()).isEqualTo(name); assertThat(view.getDescription()).isEqualTo(description); assertThat(view.getMeasure().getName()).isEqualTo(measure.getName()); + assertThat(view.getAggregations()).isEqualTo(aggregations); assertThat(view.getColumns()).hasSize(2); - assertThat(view.getColumns().get(0).toString()).isEqualTo("foo"); - assertThat(view.getColumns().get(1).toString()).isEqualTo("bar"); - assertTrue(view.match( - new Function () { - @Override public Boolean apply(DistributionView dView) { - return dView == view; - } - }, - new Function () { - @Override public Boolean apply(IntervalView iView) { - return false; - } - })); + assertThat(view.getColumns()).containsExactly(FOO, BAR).inOrder(); + assertThat(view.getWindow()).isEqualTo(Cumulative.create()); } @Test public void testIntervalView() { - IntervalAggregation iAggr = IntervalAggregation.create( - Arrays.asList(Duration.fromMillis(1), Duration.fromMillis(22), Duration.fromMillis(333))); - final View view = IntervalView.create( - name, description, measure, iAggr, keys); - + final View view = View.create( + name, description, measure, aggregations, keys, Interval.create(minute)); assertThat(view.getName()).isEqualTo(name); assertThat(view.getDescription()).isEqualTo(description); assertThat(view.getMeasure().getName()) .isEqualTo(measure.getName()); + assertThat(view.getAggregations()).isEqualTo(aggregations); assertThat(view.getColumns()).hasSize(2); - assertThat(view.getColumns().get(0).toString()).isEqualTo("foo"); - assertThat(view.getColumns().get(1).toString()).isEqualTo("bar"); - assertTrue(view.match( - new Function () { - @Override public Boolean apply(DistributionView dView) { - return false; - } - }, - new Function () { - @Override public Boolean apply(IntervalView iView) { - return iView == view; - } - })); + assertThat(view.getColumns()).containsExactly(FOO, BAR).inOrder(); + assertThat(view.getWindow()).isEqualTo(Interval.create(minute)); } @Test public void testViewEquals() { - DistributionAggregation dAggr = DistributionAggregation.create(); - IntervalAggregation iAggr = IntervalAggregation.create( - Arrays.asList(Duration.fromMillis(1), Duration.fromMillis(22), Duration.fromMillis(333))); new EqualsTester() .addEqualityGroup( - DistributionView.create( - name, description, measure, dAggr, keys), - DistributionView.create( - name, description, measure, dAggr, keys)) + View.create( + name, description, measure, aggregations, keys, Cumulative.create()), + View.create( + name, description, measure, aggregations, keys, Cumulative.create())) .addEqualityGroup( - DistributionView.create( - name, description + 2, measure, dAggr, keys)) + View.create( + name, description + 2, measure, aggregations, keys, Cumulative.create())) .addEqualityGroup( - IntervalView.create( - name, description, measure, iAggr, keys), - IntervalView.create( - name, description, measure, iAggr, keys)) + View.create( + name, description, measure, aggregations, keys, Interval.create(minute)), + View.create( + name, description, measure, aggregations, keys, Interval.create(minute))) .addEqualityGroup( - IntervalView.create( - name, description + 2, measure, iAggr, keys)) + View.create( + name, description, measure, aggregations, keys, Interval.create(twoMinutes))) .testEquals(); } - @Test(expected = NullPointerException.class) - public void preventNullDistributionViewName() { - DistributionView.create( - null, - description, - measure, - DistributionAggregation.create(), - keys); + @Test(expected = IllegalArgumentException.class) + public void preventDuplicateAggregations() { + View.create(name, description, measure, + Arrays.asList(Sum.create(), Sum.create(), Count.create()), keys, Cumulative.create()); + } + + @Test(expected = IllegalArgumentException.class) + public void preventDuplicateColumns() { + View.create(name, description, measure, aggregations, + Arrays.asList(TagKey.create("duplicate"), TagKey.create("duplicate")), Cumulative.create()); } @Test(expected = NullPointerException.class) - public void preventNullIntervalViewName() { - IntervalView.create( - null, - description, - measure, - IntervalAggregation.create(Arrays.asList(Duration.fromMillis(1))), - keys); + public void preventNullViewName() { + View.create(null, description, measure, aggregations, keys, Interval.create(minute)); } @Test @@ -150,5 +119,10 @@ public void testViewNameEquals() { private final String description = "test-view-name description"; private final Measure measure = Measure.MeasureDouble.create( "measure", "measure description", "1"); - private final List keys = Arrays.asList(TagKey.create("foo"), TagKey.create("bar")); + private static final TagKey FOO = TagKey.create("foo"); + private static final TagKey BAR = TagKey.create("bar"); + private final List keys = Arrays.asList(FOO, BAR); + private final List aggregations = Arrays.asList(Sum.create(), Count.create()); + private final Duration minute = Duration.create(60, 0); + private final Duration twoMinutes = Duration.create(120, 0); } diff --git a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java index f2669fa860..e06bbdf847 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java +++ b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java @@ -19,10 +19,6 @@ import io.opencensus.common.Function; import io.opencensus.stats.Measurement.MeasurementDouble; import io.opencensus.stats.Measurement.MeasurementLong; -import io.opencensus.stats.MutableViewData.MutableDistributionViewData; -import io.opencensus.stats.MutableViewData.MutableIntervalViewData; -import io.opencensus.stats.View.DistributionView; -import io.opencensus.stats.View.IntervalView; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; @@ -84,12 +80,13 @@ synchronized void registerView(View view, Clock clock) { } } registeredViews.put(view.getName(), view); - MutableViewData mutableViewData = - view.match( - new CreateMutableDistributionViewDataFunction(clock), - new CreateMutableIntervalViewDataFunction()); - mutableMap.put( - view.getMeasure().getName(), mutableViewData); + // TODO(songya): update to use refactored implementation. + // MutableViewData mutableViewData = + // view.match( + // new CreateMutableDistributionViewDataFunction(clock), + // new CreateMutableIntervalViewDataFunction()); + // mutableMap.put( + // view.getMeasure().getName(), mutableViewData); } // Records stats with a set of tags. @@ -105,29 +102,6 @@ synchronized void record(StatsContextImpl tags, MeasureMap stats) { } } - private static final class CreateMutableDistributionViewDataFunction - implements Function { - private final Clock clock; - - CreateMutableDistributionViewDataFunction(Clock clock) { - this.clock = clock; - } - - @Override - public MutableViewData apply(DistributionView view) { - return MutableDistributionViewData.create(view, clock.now()); - } - } - - private static final class CreateMutableIntervalViewDataFunction - implements Function { - @Override - public MutableViewData apply(IntervalView view) { - // TODO(songya): Create Interval Aggregations from internal Distributions. - return MutableIntervalViewData.create(view); - } - } - private static final class RecordDoubleValueFunc implements Function { @Override public Void apply(MeasurementDouble arg) { diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java index 82917cc5c9..7d4214dab3 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java +++ b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java @@ -15,19 +15,11 @@ import com.google.common.annotations.VisibleForTesting; import io.opencensus.common.Clock; -import io.opencensus.common.Timestamp; -import io.opencensus.stats.View.DistributionView; -import io.opencensus.stats.View.IntervalView; -import io.opencensus.stats.ViewData.DistributionViewData; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; /** * A mutable version of {@link ViewData}, used for recording stats and start/end time. */ +// TODO(songya): update to use refactored implementation. abstract class MutableViewData { // TODO(songya): might want to update the default tag value later. @@ -57,145 +49,145 @@ abstract class MutableViewData { private MutableViewData() { } - /** - * A {@link MutableViewData} for recording stats on distribution-based aggregations. - */ - static final class MutableDistributionViewData extends MutableViewData { - - /** - * Constructs a new {@link MutableDistributionViewData}. - */ - static MutableDistributionViewData create( - DistributionView distributionView, Timestamp start) { - return new MutableDistributionViewData(distributionView, start); - } - - @Override - View getView() { - return distributionView; - } - - @Override - void record(StatsContextImpl context, double value) { - Map tags = context.tags; - // TagKeys need to be unique within one view descriptor. - final List tagKeys = this.distributionView.getColumns(); - final List tagValues = new ArrayList(tagKeys.size()); - - // Record all the measures in a "Greedy" way. - // Every view aggregates every measure. This is similar to doing a GROUPBY view’s keys. - for (int i = 0; i < tagKeys.size(); ++i) { - TagKey tagKey = tagKeys.get(i); - if (!tags.containsKey(tagKey)) { - // replace not found key values by “unknown/not set”. - tagValues.add(UNKNOWN_TAG_VALUE); - } else { - tagValues.add(tags.get(tagKey)); - } - } - - if (!tagValueDistributionMap.containsKey(tagValues)) { - final List bucketBoundaries = - this.distributionView.getDistributionAggregation() - .getBucketBoundaries(); - final MutableDistribution distribution = - bucketBoundaries == null ? MutableDistribution.create() - : MutableDistribution.create(BucketBoundaries.create(bucketBoundaries)); - tagValueDistributionMap.put(tagValues, distribution); - } - tagValueDistributionMap.get(tagValues).add(value); - } - - @Override - void record(StatsContextImpl tags, long value) { - // TODO(songya): modify MutableDistribution to support long values. - throw new UnsupportedOperationException("Not implemented."); - } - - @Override - final ViewData toViewData(Clock clock) { - final List distributionAggregations = - new ArrayList(); - for (Entry, MutableDistribution> entry : tagValueDistributionMap.entrySet()) { - MutableDistribution distribution = entry.getValue(); - DistributionAggregate distributionAggregation = distribution.getBucketCounts() == null - ? DistributionAggregate.create(distribution.getCount(), distribution.getMean(), - distribution.getSum(), convertRange(distribution.getRange()), - generateTags(entry.getKey())) - : DistributionAggregate.create(distribution.getCount(), distribution.getMean(), - distribution.getSum(), convertRange(distribution.getRange()), - generateTags(entry.getKey()), distribution.getBucketCounts()); - distributionAggregations.add(distributionAggregation); - } - return DistributionViewData.create(distributionView, distributionAggregations, start, - clock.now()); - } - - /** - * Returns start timestamp for this aggregation. - */ - Timestamp getStart() { - return start; - } - - private final DistributionView distributionView; - private final Map, MutableDistribution> tagValueDistributionMap = - new HashMap, MutableDistribution>(); - private final Timestamp start; - - private MutableDistributionViewData( - DistributionView distributionView, Timestamp start) { - this.distributionView = distributionView; - this.start = start; - } - - private final List generateTags(List tagValues) { - final List tags = new ArrayList(tagValues.size()); - int i = 0; - for (TagKey tagKey : this.distributionView.getColumns()) { - tags.add(Tag.create(tagKey, tagValues.get(i))); - ++i; - } - return tags; - } - - // TODO(songya): remove DistributionAggregate.Range, then remove this method - private static final DistributionAggregate.Range convertRange( - MutableDistribution.Range range) { - return DistributionAggregate.Range.create(range.getMin(), range.getMax()); - } - } - - /** - * A {@link MutableViewData} for recording stats on interval-based aggregations. - */ - static final class MutableIntervalViewData extends MutableViewData { - - /** - * Constructs a new {@link MutableIntervalViewData}. - */ - static MutableIntervalViewData create(IntervalView view) { - throw new UnsupportedOperationException("Not implemented."); - } - - @Override - View getView() { - throw new UnsupportedOperationException("Not implemented."); - } - - @Override - void record(StatsContextImpl tags, double value) { - throw new UnsupportedOperationException("Not implemented."); - } - - @Override - void record(StatsContextImpl tags, long value) { - throw new UnsupportedOperationException("Not implemented."); - } - - @Override - final ViewData toViewData(Clock clock) { - throw new UnsupportedOperationException("Not implemented."); - } - } +// /** +// * A {@link MutableViewData} for recording stats on distribution-based aggregations. +// */ +// static final class MutableDistributionViewData extends MutableViewData { +// +// /** +// * Constructs a new {@link MutableDistributionViewData}. +// */ +// static MutableDistributionViewData create( +// DistributionView distributionView, Timestamp start) { +// return new MutableDistributionViewData(distributionView, start); +// } +// +// @Override +// View getView() { +// return distributionView; +// } +// +// @Override +// void record(StatsContextImpl context, double value) { +// Map tags = context.tags; +// // TagKeys need to be unique within one view descriptor. +// final List tagKeys = this.distributionView.getColumns(); +// final List tagValues = new ArrayList(tagKeys.size()); +// +// // Record all the measures in a "Greedy" way. +// // Every view aggregates every measure. This is similar to doing a GROUPBY view’s keys. +// for (int i = 0; i < tagKeys.size(); ++i) { +// TagKey tagKey = tagKeys.get(i); +// if (!tags.containsKey(tagKey)) { +// // replace not found key values by “unknown/not set”. +// tagValues.add(UNKNOWN_TAG_VALUE); +// } else { +// tagValues.add(tags.get(tagKey)); +// } +// } +// +// if (!tagValueDistributionMap.containsKey(tagValues)) { +// final List bucketBoundaries = +// this.distributionView.getDistributionAggregation() +// .getBucketBoundaries(); +// final MutableDistribution distribution = +// bucketBoundaries == null ? MutableDistribution.create() +// : MutableDistribution.create(BucketBoundaries.create(bucketBoundaries)); +// tagValueDistributionMap.put(tagValues, distribution); +// } +// tagValueDistributionMap.get(tagValues).add(value); +// } +// +// @Override +// void record(StatsContextImpl tags, long value) { +// // TODO(songya): modify MutableDistribution to support long values. +// throw new UnsupportedOperationException("Not implemented."); +// } +// +// @Override +// final ViewData toViewData(Clock clock) { +// final List distributionAggregations = +// new ArrayList(); +// for (Entry, MutableDistribution> entry : tagValueDistributionMap.entrySet()){ +// MutableDistribution distribution = entry.getValue(); +// DistributionAggregate distributionAggregation = distribution.getBucketCounts() == null +// ? DistributionAggregate.create(distribution.getCount(), distribution.getMean(), +// distribution.getSum(), convertRange(distribution.getRange()), +// generateTags(entry.getKey())) +// : DistributionAggregate.create(distribution.getCount(), distribution.getMean(), +// distribution.getSum(), convertRange(distribution.getRange()), +// generateTags(entry.getKey()), distribution.getBucketCounts()); +// distributionAggregations.add(distributionAggregation); +// } +// return DistributionViewData.create(distributionView, distributionAggregations, start, +// clock.now()); +// } +// +// /** +// * Returns start timestamp for this aggregation. +// */ +// Timestamp getStart() { +// return start; +// } +// +// private final DistributionView distributionView; +// private final Map, MutableDistribution> tagValueDistributionMap = +// new HashMap, MutableDistribution>(); +// private final Timestamp start; +// +// private MutableDistributionViewData( +// DistributionView distributionView, Timestamp start) { +// this.distributionView = distributionView; +// this.start = start; +// } +// +// private final List generateTags(List tagValues) { +// final List tags = new ArrayList(tagValues.size()); +// int i = 0; +// for (TagKey tagKey : this.distributionView.getColumns()) { +// tags.add(Tag.create(tagKey, tagValues.get(i))); +// ++i; +// } +// return tags; +// } +// +// // TODO(songya): remove DistributionAggregate.Range, then remove this method +// private static final DistributionAggregate.Range convertRange( +// MutableDistribution.Range range) { +// return DistributionAggregate.Range.create(range.getMin(), range.getMax()); +// } +// } +// +// /** +// * A {@link MutableViewData} for recording stats on interval-based aggregations. +// */ +// static final class MutableIntervalViewData extends MutableViewData { +// +// /** +// * Constructs a new {@link MutableIntervalViewData}. +// */ +// static MutableIntervalViewData create(IntervalView view) { +// throw new UnsupportedOperationException("Not implemented."); +// } +// +// @Override +// View getView() { +// throw new UnsupportedOperationException("Not implemented."); +// } +// +// @Override +// void record(StatsContextImpl tags, double value) { +// throw new UnsupportedOperationException("Not implemented."); +// } +// +// @Override +// void record(StatsContextImpl tags, long value) { +// throw new UnsupportedOperationException("Not implemented."); +// } +// +// @Override +// final ViewData toViewData(Clock clock) { +// throw new UnsupportedOperationException("Not implemented."); +// } +// } } diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java index c18a5aea68..1ece888ed3 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java @@ -15,7 +15,6 @@ import io.opencensus.common.Clock; import io.opencensus.internal.EventQueue; -import io.opencensus.stats.View.DistributionView; /** Object that stores all views and stats. */ final class StatsManager { @@ -33,11 +32,8 @@ final class StatsManager { } void registerView(View view) { - // Only DistributionViews are supported currently. - // TODO(sebright): Remove this once all views are supported. - if (!(view instanceof DistributionView)) { - throw new UnsupportedOperationException( - "The prototype will only support distribution views."); + if (view.getWindow() instanceof View.Window.Interval) { + throw new UnsupportedOperationException("IntervalView not supported yet."); } measureToViewMap.registerView(view, clock); } diff --git a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java index 5eaa34ca41..12e12f4965 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java @@ -13,22 +13,14 @@ package io.opencensus.stats; -import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; - -import io.opencensus.common.Function; -import io.opencensus.common.Timestamp; -import io.opencensus.stats.View.DistributionView; -import io.opencensus.stats.ViewData.DistributionViewData; -import io.opencensus.stats.ViewData.IntervalViewData; -import io.opencensus.testing.common.TestClock; -import java.util.Arrays; -import org.junit.Test; +import org.junit.Ignore; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** Tests for {@link MeasureToViewMap}. */ +@Ignore @RunWith(JUnit4.class) +// TODO(songya): re-enable the tests once implementation is done. public class MeasureToViewMapTest { private static final Measure MEASURE = @@ -39,38 +31,38 @@ public class MeasureToViewMapTest { private static final View.Name VIEW_NAME = View.Name.create("my view"); - private static final View VIEW = - DistributionView.create( - VIEW_NAME, - "view description", - MEASURE, - DistributionAggregation.create(), - Arrays.asList(TagKey.create("my key"))); +// private static final View VIEW = +// DistributionView.create( +// VIEW_NAME, +// "view description", +// MEASURE, +// DistributionAggregation.create(), +// Arrays.asList(TagKey.create("my key"))); - @Test - public void testRegisterAndGetDistributionView() { - MeasureToViewMap measureToViewMap = new MeasureToViewMap(); - TestClock clock = TestClock.create(Timestamp.create(10, 20)); - measureToViewMap.registerView(VIEW, clock); - clock.setTime(Timestamp.create(30, 40)); - ViewData actual = measureToViewMap.getView(VIEW_NAME, clock); - actual.match( - new Function() { - @Override - public Void apply(DistributionViewData view) { - assertThat(view.getView()).isEqualTo(VIEW); - assertThat(view.getStart()).isEqualTo(Timestamp.create(10, 20)); - assertThat(view.getEnd()).isEqualTo(Timestamp.create(30, 40)); - assertThat(view.getDistributionAggregates()).isEmpty(); - return null; - } - }, - new Function() { - @Override - public Void apply(IntervalViewData view) { - fail("Wrong view type."); - return null; - } - }); - } +// @Test +// public void testRegisterAndGetDistributionView() { +// MeasureToViewMap measureToViewMap = new MeasureToViewMap(); +// TestClock clock = TestClock.create(Timestamp.create(10, 20)); +// measureToViewMap.registerView(VIEW, clock); +// clock.setTime(Timestamp.create(30, 40)); +// ViewData actual = measureToViewMap.getView(VIEW_NAME, clock); +// actual.match( +// new Function() { +// @Override +// public Void apply(DistributionViewData view) { +// assertThat(view.getView()).isEqualTo(VIEW); +// assertThat(view.getStart()).isEqualTo(Timestamp.create(10, 20)); +// assertThat(view.getEnd()).isEqualTo(Timestamp.create(30, 40)); +// assertThat(view.getDistributionAggregates()).isEmpty(); +// return null; +// } +// }, +// new Function() { +// @Override +// public Void apply(IntervalViewData view) { +// fail("Wrong view type."); +// return null; +// } +// }); +// } } diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index a81b826eb4..9256781f8e 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -14,16 +14,11 @@ package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; import com.google.common.collect.Collections2; import com.google.common.testing.EqualsTester; -import io.opencensus.common.Function; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.internal.VarInt; -import io.opencensus.stats.Measure.MeasureLong; -import io.opencensus.stats.ViewData.DistributionViewData; -import io.opencensus.stats.ViewData.IntervalViewData; import io.opencensus.testing.common.TestClock; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -116,74 +111,75 @@ public void testWithComposed() { .isEqualTo(context4); } - // The main tests for stats recording are in ViewManagerImplTest. - @Test - public void testRecordDouble() { - viewManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - ViewData beforeViewData = - viewManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - beforeViewData.match( - new Function() { - @Override - public Void apply(DistributionViewData view) { - assertThat(view.getDistributionAggregates()).isEmpty(); - return null; - } - }, - new Function() { - @Override - public Void apply(IntervalViewData view) { - fail("Expected a DistributionViewData"); - return null; - } - }); - StatsContext context = - defaultStatsContext.with( - RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); - MeasureMap measurements = - MeasureMap.builder() - .set(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); - context.record(measurements); - ViewData afterViewData = - viewManager.getView( - RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - afterViewData.match( - new Function() { - @Override - public Void apply(DistributionViewData view) { - assertThat(view.getDistributionAggregates()).hasSize(1); - DistributionAggregate agg = view.getDistributionAggregates().get(0); - assertThat(agg.getTags()) - .containsExactly( - Tag.create( - RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod"))); - assertThat(agg.getCount()).isEqualTo(1); - assertThat(agg.getMean()).isWithin(TOLERANCE).of(5.1); - return null; - } - }, - new Function() { - @Override - public Void apply(IntervalViewData view) { - fail("Expected a DistributionViewData"); - return null; - } - }); - } - - @Test - public void testRecordLong() { - MeasureLong measure = MeasureLong.create("long measure", "description", "1"); - viewManager.registerView( - View.DistributionView.create( - View.Name.create("name"), - "description", - measure, - DistributionAggregation.create(), - Arrays.asList(K1))); - thrown.expect(UnsupportedOperationException.class); - defaultStatsContext.with(K1, V1).record(MeasureMap.builder().set(measure,1L).build()); - } + // TODO(songya): re-enable the tests once implementation is done. +// // The main tests for stats recording are in ViewManagerImplTest. +// @Test +// public void testRecordDouble() { +// viewManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); +// ViewData beforeViewData = +// viewManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); +// beforeViewData.match( +// new Function() { +// @Override +// public Void apply(DistributionViewData view) { +// assertThat(view.getDistributionAggregates()).isEmpty(); +// return null; +// } +// }, +// new Function() { +// @Override +// public Void apply(IntervalViewData view) { +// fail("Expected a DistributionViewData"); +// return null; +// } +// }); +// StatsContext context = +// defaultStatsContext.with( +// RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); +// MeasureMap measurements = +// MeasureMap.builder() +// .set(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); +// context.record(measurements); +// ViewData afterViewData = +// viewManager.getView( +// RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); +// afterViewData.match( +// new Function() { +// @Override +// public Void apply(DistributionViewData view) { +// assertThat(view.getDistributionAggregates()).hasSize(1); +// DistributionAggregate agg = view.getDistributionAggregates().get(0); +// assertThat(agg.getTags()) +// .containsExactly( +// Tag.create( +// RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod"))); +// assertThat(agg.getCount()).isEqualTo(1); +// assertThat(agg.getMean()).isWithin(TOLERANCE).of(5.1); +// return null; +// } +// }, +// new Function() { +// @Override +// public Void apply(IntervalViewData view) { +// fail("Expected a DistributionViewData"); +// return null; +// } +// }); +// } +// +// @Test +// public void testRecordLong() { +// MeasureLong measure = MeasureLong.create("long measure", "description", "1"); +// viewManager.registerView( +// View.DistributionView.create( +// View.Name.create("name"), +// "description", +// measure, +// DistributionAggregation.create(), +// Arrays.asList(K1))); +// thrown.expect(UnsupportedOperationException.class); +// defaultStatsContext.with(K1, V1).record(MeasureMap.builder().set(measure,1L).build()); +// } @Test public void testSerializeDefault() throws Exception { diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index 6341daa473..46b2490766 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -13,28 +13,21 @@ package io.opencensus.stats; -import static com.google.common.truth.Truth.assertThat; -import static io.opencensus.stats.StatsTestUtil.createContext; - -import io.opencensus.common.Duration; -import io.opencensus.common.Timestamp; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.stats.Measure.MeasureDouble; -import io.opencensus.stats.ViewData.DistributionViewData; -import io.opencensus.stats.View.DistributionView; -import io.opencensus.stats.View.IntervalView; import io.opencensus.testing.common.TestClock; import java.util.Arrays; import java.util.Collection; -import java.util.List; +import org.junit.Ignore; import org.junit.Rule; -import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** Tests for {@link ViewManagerImpl}. */ +@Ignore @RunWith(JUnit4.class) +// TODO(songya): re-enable the tests once implementation is done. public class ViewManagerImplTest { @Rule @@ -79,393 +72,393 @@ public class ViewManagerImplTest { private final ViewManagerImpl viewManager = statsComponent.getViewManager(); private final StatsRecorder statsRecorder = statsComponent.getStatsRecorder(); - private static DistributionView createDistributionView() { - return createDistributionView( - VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); - } - - private static DistributionView createDistributionView( - View.Name name, - Measure measure, - DistributionAggregation distributionAggregation, - List keys) { - return DistributionView.create(name, VIEW_DESCRIPTION, measure, distributionAggregation, keys); - } - - @Test - public void testRegisterAndGetView() { - DistributionView view = createDistributionView(); - viewManager.registerView(view); - assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view); - } - - @Test - public void preventRegisteringIntervalView() { - View intervalView = - IntervalView.create( - VIEW_NAME, - VIEW_DESCRIPTION, - MEASURE, - IntervalAggregation.create(Arrays.asList(Duration.fromMillis(1000))), - Arrays.asList(KEY)); - thrown.expect(UnsupportedOperationException.class); - viewManager.registerView(intervalView); - } - - @Test - public void allowRegisteringSameViewTwice() { - DistributionView view = createDistributionView(); - viewManager.registerView(view); - viewManager.registerView(view); - assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view); - } - - @Test - public void preventRegisteringDifferentViewWithSameName() { - View view1 = - DistributionView.create( - VIEW_NAME, - "View description.", - MEASURE, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY)); - viewManager.registerView(view1); - View view2 = - DistributionView.create( - VIEW_NAME, - "This is a different description.", - MEASURE, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY)); - try { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("A different view with the same name is already registered"); - viewManager.registerView(view2); - } finally { - assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view1); - } - } - - @Test - public void disallowGettingNonexistentViewData() { - thrown.expect(IllegalArgumentException.class); - viewManager.getView(VIEW_NAME); - } - - @Test - public void testRecord() { - DistributionView view = - createDistributionView( - VIEW_NAME, - MEASURE, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY)); - clock.setTime(Timestamp.create(1, 2)); - viewManager.registerView(view); - StatsContextImpl tags = createContext(factory, KEY, VALUE); - for (double val : Arrays.asList(10.0, 20.0, 30.0, 40.0)) { - statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, val).build()); - } - clock.setTime(Timestamp.create(3, 4)); - DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertThat(viewData.getView()).isEqualTo(view); - assertThat(viewData.getStart()).isEqualTo(Timestamp.create(1, 2)); - assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(3, 4)); - assertDistributionAggregatesEquivalent( - viewData.getDistributionAggregates(), - Arrays.asList( - StatsTestUtil.createDistributionAggregate( - Arrays.asList(Tag.create(KEY, VALUE)), - BUCKET_BOUNDARIES, - Arrays.asList(10.0, 20.0, 30.0, 40.0)))); - } - - @Test - public void getViewDoesNotClearStats() { - DistributionView view = - createDistributionView( - VIEW_NAME, - MEASURE, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY)); - clock.setTime(Timestamp.create(10, 0)); - viewManager.registerView(view); - StatsContextImpl tags = createContext(factory, KEY, VALUE); - statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.1).build()); - clock.setTime(Timestamp.create(11, 0)); - DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(10, 0)); - assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(11, 0)); - assertDistributionAggregatesEquivalent( - viewData1.getDistributionAggregates(), - Arrays.asList( - StatsTestUtil.createDistributionAggregate( - Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(0.1)))); - statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.2).build()); - clock.setTime(Timestamp.create(12, 0)); - DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME); - - // The second view should have the same start time as the first view, and it should include both - // recorded values: - assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(10, 0)); - assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(12, 0)); - assertDistributionAggregatesEquivalent( - viewData2.getDistributionAggregates(), - Arrays.asList( - StatsTestUtil.createDistributionAggregate( - Arrays.asList(Tag.create(KEY, VALUE)), - BUCKET_BOUNDARIES, - Arrays.asList(0.1, 0.2)))); - } - - @Test - public void testRecordMultipleTagValues() { - viewManager.registerView( - createDistributionView( - VIEW_NAME, - MEASURE, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY))); - statsRecorder.record( - createContext(factory, KEY, VALUE), - MeasureMap.builder().set(MEASURE, 10.0).build()); - statsRecorder.record( - createContext(factory, KEY, VALUE_2), - MeasureMap.builder().set(MEASURE, 30.0).build()); - statsRecorder.record( - createContext(factory, KEY, VALUE_2), - MeasureMap.builder().set(MEASURE, 50.0).build()); - DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertDistributionAggregatesEquivalent( - viewData.getDistributionAggregates(), - Arrays.asList( - StatsTestUtil.createDistributionAggregate( - Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(10.0)), - StatsTestUtil.createDistributionAggregate( - Arrays.asList(Tag.create(KEY, VALUE_2)), - BUCKET_BOUNDARIES, - Arrays.asList(30.0, 50.0)))); - } - - // This test checks that StatsRecorder.record(...) does not throw an exception when no views are - // registered. - @Test - public void allowRecordingWithoutRegisteringMatchingViewData() { - statsRecorder.record( - createContext(factory, KEY, VALUE), - MeasureMap.builder().set(MEASURE, 10).build()); - } - - @Test - public void testRecordWithEmptyStatsContext() { - viewManager.registerView( - createDistributionView( - VIEW_NAME, - MEASURE, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY))); - // DEFAULT doesn't have tags, but the view has tag key "KEY". - statsRecorder.record(factory.getDefault(), - MeasureMap.builder().set(MEASURE, 10.0).build()); - DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertDistributionAggregatesEquivalent( - viewData.getDistributionAggregates(), - Arrays.asList( - StatsTestUtil.createDistributionAggregate( - // Tag is missing for associated measureValues, should use default tag value - // "unknown/not set" - Arrays.asList(Tag.create(KEY, MutableViewData.UNKNOWN_TAG_VALUE)), - BUCKET_BOUNDARIES, - // Should record stats with default tag value: "KEY" : "unknown/not set". - Arrays.asList(10.0)))); - } - - @Test - public void testRecordWithNonExistentMeasurement() { - viewManager.registerView( - createDistributionView( - VIEW_NAME, - Measure.MeasureDouble.create(MEASURE_NAME, "measure", MEASURE_UNIT), - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY))); - MeasureDouble measure2 = - Measure.MeasureDouble.create(MEASURE_NAME_2, "measure", MEASURE_UNIT); - statsRecorder.record(createContext(factory, KEY, VALUE), - MeasureMap.builder().set(measure2, 10.0).build()); - DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertThat(view.getDistributionAggregates()).isEmpty(); - } - - @Test - public void testRecordWithTagsThatDoNotMatchViewData() { - viewManager.registerView( - createDistributionView( - VIEW_NAME, - MEASURE, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY))); - statsRecorder.record( - createContext(factory, TagKey.create("wrong key"), VALUE), - MeasureMap.builder().set(MEASURE, 10.0).build()); - statsRecorder.record( - createContext(factory, TagKey.create("another wrong key"), VALUE), - MeasureMap.builder().set(MEASURE, 50.0).build()); - DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertDistributionAggregatesEquivalent( - view.getDistributionAggregates(), - Arrays.asList( - StatsTestUtil.createDistributionAggregate( - // Won't record the unregistered tag key, will use default tag instead: - // "KEY" : "unknown/not set". - Arrays.asList(Tag.create(KEY, MutableViewData.UNKNOWN_TAG_VALUE)), - BUCKET_BOUNDARIES, - // Should record stats with default tag value: "KEY" : "unknown/not set". - Arrays.asList(10.0, 50.0)))); - } - - @Test - public void testViewDataWithMultipleTagKeys() { - TagKey key1 = TagKey.create("Key-1"); - TagKey key2 = TagKey.create("Key-2"); - viewManager.registerView( - createDistributionView( - VIEW_NAME, - MEASURE, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(key1, key2))); - statsRecorder.record( - createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), - MeasureMap.builder().set(MEASURE, 1.1).build()); - statsRecorder.record( - createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v20")), - MeasureMap.builder().set(MEASURE, 2.2).build()); - statsRecorder.record( - createContext(factory, key1, TagValue.create("v2"), key2, TagValue.create("v10")), - MeasureMap.builder().set(MEASURE, 3.3).build()); - statsRecorder.record( - createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), - MeasureMap.builder().set(MEASURE, 4.4).build()); - DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertDistributionAggregatesEquivalent( - view.getDistributionAggregates(), - Arrays.asList( - StatsTestUtil.createDistributionAggregate( - Arrays.asList( - Tag.create(key1, TagValue.create("v1")), - Tag.create(key2, TagValue.create("v10"))), - BUCKET_BOUNDARIES, - Arrays.asList(1.1, 4.4)), - StatsTestUtil.createDistributionAggregate( - Arrays.asList( - Tag.create(key1, TagValue.create("v1")), - Tag.create(key2, TagValue.create("v20"))), - BUCKET_BOUNDARIES, - Arrays.asList(2.2)), - StatsTestUtil.createDistributionAggregate( - Arrays.asList( - Tag.create(key1, TagValue.create("v2")), - Tag.create(key2, TagValue.create("v10"))), - BUCKET_BOUNDARIES, - Arrays.asList(3.3)))); - } - - @Test - public void testMultipleViewDatasSameMeasure() { - View view1 = - createDistributionView( - VIEW_NAME, - MEASURE, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY)); - View view2 = - createDistributionView( - VIEW_NAME_2, - MEASURE, - DISTRIBUTION_AGGREGATION_DESCRIPTOR, - Arrays.asList(KEY)); - clock.setTime(Timestamp.create(1, 1)); - viewManager.registerView(view1); - clock.setTime(Timestamp.create(2, 2)); - viewManager.registerView(view2); - statsRecorder.record( - createContext(factory, KEY, VALUE), - MeasureMap.builder().set(MEASURE, 5.0).build()); - List expectedAggs = - Arrays.asList( - StatsTestUtil.createDistributionAggregate( - Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(5.0))); - clock.setTime(Timestamp.create(3, 3)); - DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); - clock.setTime(Timestamp.create(4, 4)); - DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME_2); - assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(1, 1)); - assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(3, 3)); - assertDistributionAggregatesEquivalent(viewData1.getDistributionAggregates(), expectedAggs); - assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(2, 2)); - assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(4, 4)); - assertDistributionAggregatesEquivalent(viewData2.getDistributionAggregates(), expectedAggs); - } - - @Test - public void testMultipleViewsDifferentMeasures() { - MeasureDouble measure1 = - Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); - MeasureDouble measure2 = - Measure.MeasureDouble.create(MEASURE_NAME_2, MEASURE_DESCRIPTION, MEASURE_UNIT); - View view1 = - createDistributionView( - VIEW_NAME, measure1, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); - View view2 = - createDistributionView( - VIEW_NAME_2, measure2, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); - clock.setTime(Timestamp.create(1, 0)); - viewManager.registerView(view1); - clock.setTime(Timestamp.create(2, 0)); - viewManager.registerView(view2); - statsRecorder.record( - createContext(factory, KEY, VALUE), - MeasureMap.builder().set(measure1, 1.1).set(measure2, 2.2).build()); - clock.setTime(Timestamp.create(3, 0)); - DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); - clock.setTime(Timestamp.create(4, 0)); - DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME_2); - assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(1, 0)); - assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(3, 0)); - assertDistributionAggregatesEquivalent( - viewData1.getDistributionAggregates(), - Arrays.asList( - StatsTestUtil.createDistributionAggregate( - Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(1.1)))); - assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(2, 0)); - assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(4, 0)); - assertDistributionAggregatesEquivalent( - viewData2.getDistributionAggregates(), - Arrays.asList( - StatsTestUtil.createDistributionAggregate( - Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(2.2)))); - } - - @Test - public void testGetDistributionViewDataWithoutBucketBoundaries() { - View view = - createDistributionView( - VIEW_NAME, MEASURE, DistributionAggregation.create(), - Arrays.asList(KEY)); - clock.setTime(Timestamp.create(1, 0)); - viewManager.registerView(view); - statsRecorder.record( - createContext(factory, KEY, VALUE), - MeasureMap.builder().set(MEASURE, 1.1).build()); - clock.setTime(Timestamp.create(3, 0)); - DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); - assertThat(viewData.getStart()).isEqualTo(Timestamp.create(1, 0)); - assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(3, 0)); - assertDistributionAggregatesEquivalent( - viewData.getDistributionAggregates(), - Arrays.asList( - StatsTestUtil.createDistributionAggregate( - Arrays.asList(Tag.create(KEY, VALUE)), Arrays.asList(1.1)))); - } +// private static DistributionView createDistributionView() { +// return createDistributionView( +// VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); +// } +// +// private static DistributionView createDistributionView( +// View.Name name, +// Measure measure, +// DistributionAggregation distributionAggregation, +// List keys) { +// return DistributionView.create(name, VIEW_DESCRIPTION, measure, distributionAggregation, keys); +// } +// +// @Test +// public void testRegisterAndGetView() { +// DistributionView view = createDistributionView(); +// viewManager.registerView(view); +// assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view); +// } +// +// @Test +// public void preventRegisteringIntervalView() { +// View intervalView = +// IntervalView.create( +// VIEW_NAME, +// VIEW_DESCRIPTION, +// MEASURE, +// IntervalAggregation.create(Arrays.asList(Duration.fromMillis(1000))), +// Arrays.asList(KEY)); +// thrown.expect(UnsupportedOperationException.class); +// viewManager.registerView(intervalView); +// } +// +// @Test +// public void allowRegisteringSameViewTwice() { +// DistributionView view = createDistributionView(); +// viewManager.registerView(view); +// viewManager.registerView(view); +// assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view); +// } +// +// @Test +// public void preventRegisteringDifferentViewWithSameName() { +// View view1 = +// DistributionView.create( +// VIEW_NAME, +// "View description.", +// MEASURE, +// DISTRIBUTION_AGGREGATION_DESCRIPTOR, +// Arrays.asList(KEY)); +// viewManager.registerView(view1); +// View view2 = +// DistributionView.create( +// VIEW_NAME, +// "This is a different description.", +// MEASURE, +// DISTRIBUTION_AGGREGATION_DESCRIPTOR, +// Arrays.asList(KEY)); +// try { +// thrown.expect(IllegalArgumentException.class); +// thrown.expectMessage("A different view with the same name is already registered"); +// viewManager.registerView(view2); +// } finally { +// assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view1); +// } +// } +// +// @Test +// public void disallowGettingNonexistentViewData() { +// thrown.expect(IllegalArgumentException.class); +// viewManager.getView(VIEW_NAME); +// } +// +// @Test +// public void testRecord() { +// DistributionView view = +// createDistributionView( +// VIEW_NAME, +// MEASURE, +// DISTRIBUTION_AGGREGATION_DESCRIPTOR, +// Arrays.asList(KEY)); +// clock.setTime(Timestamp.create(1, 2)); +// viewManager.registerView(view); +// StatsContextImpl tags = createContext(factory, KEY, VALUE); +// for (double val : Arrays.asList(10.0, 20.0, 30.0, 40.0)) { +// statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, val).build()); +// } +// clock.setTime(Timestamp.create(3, 4)); +// DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); +// assertThat(viewData.getView()).isEqualTo(view); +// assertThat(viewData.getStart()).isEqualTo(Timestamp.create(1, 2)); +// assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(3, 4)); +// assertDistributionAggregatesEquivalent( +// viewData.getDistributionAggregates(), +// Arrays.asList( +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList(Tag.create(KEY, VALUE)), +// BUCKET_BOUNDARIES, +// Arrays.asList(10.0, 20.0, 30.0, 40.0)))); +// } +// +// @Test +// public void getViewDoesNotClearStats() { +// DistributionView view = +// createDistributionView( +// VIEW_NAME, +// MEASURE, +// DISTRIBUTION_AGGREGATION_DESCRIPTOR, +// Arrays.asList(KEY)); +// clock.setTime(Timestamp.create(10, 0)); +// viewManager.registerView(view); +// StatsContextImpl tags = createContext(factory, KEY, VALUE); +// statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.1).build()); +// clock.setTime(Timestamp.create(11, 0)); +// DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); +// assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(10, 0)); +// assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(11, 0)); +// assertDistributionAggregatesEquivalent( +// viewData1.getDistributionAggregates(), +// Arrays.asList( +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(0.1)))); +// statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.2).build()); +// clock.setTime(Timestamp.create(12, 0)); +// DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME); +// +// // The second view should have the same start time as the first view, and it should include both +// // recorded values: +// assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(10, 0)); +// assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(12, 0)); +// assertDistributionAggregatesEquivalent( +// viewData2.getDistributionAggregates(), +// Arrays.asList( +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList(Tag.create(KEY, VALUE)), +// BUCKET_BOUNDARIES, +// Arrays.asList(0.1, 0.2)))); +// } +// +// @Test +// public void testRecordMultipleTagValues() { +// viewManager.registerView( +// createDistributionView( +// VIEW_NAME, +// MEASURE, +// DISTRIBUTION_AGGREGATION_DESCRIPTOR, +// Arrays.asList(KEY))); +// statsRecorder.record( +// createContext(factory, KEY, VALUE), +// MeasureMap.builder().set(MEASURE, 10.0).build()); +// statsRecorder.record( +// createContext(factory, KEY, VALUE_2), +// MeasureMap.builder().set(MEASURE, 30.0).build()); +// statsRecorder.record( +// createContext(factory, KEY, VALUE_2), +// MeasureMap.builder().set(MEASURE, 50.0).build()); +// DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); +// assertDistributionAggregatesEquivalent( +// viewData.getDistributionAggregates(), +// Arrays.asList( +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(10.0)), +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList(Tag.create(KEY, VALUE_2)), +// BUCKET_BOUNDARIES, +// Arrays.asList(30.0, 50.0)))); +// } +// +// // This test checks that StatsRecorder.record(...) does not throw an exception when no views are +// // registered. +// @Test +// public void allowRecordingWithoutRegisteringMatchingViewData() { +// statsRecorder.record( +// createContext(factory, KEY, VALUE), +// MeasureMap.builder().set(MEASURE, 10).build()); +// } +// +// @Test +// public void testRecordWithEmptyStatsContext() { +// viewManager.registerView( +// createDistributionView( +// VIEW_NAME, +// MEASURE, +// DISTRIBUTION_AGGREGATION_DESCRIPTOR, +// Arrays.asList(KEY))); +// // DEFAULT doesn't have tags, but the view has tag key "KEY". +// statsRecorder.record(factory.getDefault(), +// MeasureMap.builder().set(MEASURE, 10.0).build()); +// DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); +// assertDistributionAggregatesEquivalent( +// viewData.getDistributionAggregates(), +// Arrays.asList( +// StatsTestUtil.createDistributionAggregate( +// // Tag is missing for associated measureValues, should use default tag value +// // "unknown/not set" +// Arrays.asList(Tag.create(KEY, MutableViewData.UNKNOWN_TAG_VALUE)), +// BUCKET_BOUNDARIES, +// // Should record stats with default tag value: "KEY" : "unknown/not set". +// Arrays.asList(10.0)))); +// } +// +// @Test +// public void testRecordWithNonExistentMeasurement() { +// viewManager.registerView( +// createDistributionView( +// VIEW_NAME, +// Measure.MeasureDouble.create(MEASURE_NAME, "measure", MEASURE_UNIT), +// DISTRIBUTION_AGGREGATION_DESCRIPTOR, +// Arrays.asList(KEY))); +// MeasureDouble measure2 = +// Measure.MeasureDouble.create(MEASURE_NAME_2, "measure", MEASURE_UNIT); +// statsRecorder.record(createContext(factory, KEY, VALUE), +// MeasureMap.builder().set(measure2, 10.0).build()); +// DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); +// assertThat(view.getDistributionAggregates()).isEmpty(); +// } +// +// @Test +// public void testRecordWithTagsThatDoNotMatchViewData() { +// viewManager.registerView( +// createDistributionView( +// VIEW_NAME, +// MEASURE, +// DISTRIBUTION_AGGREGATION_DESCRIPTOR, +// Arrays.asList(KEY))); +// statsRecorder.record( +// createContext(factory, TagKey.create("wrong key"), VALUE), +// MeasureMap.builder().set(MEASURE, 10.0).build()); +// statsRecorder.record( +// createContext(factory, TagKey.create("another wrong key"), VALUE), +// MeasureMap.builder().set(MEASURE, 50.0).build()); +// DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); +// assertDistributionAggregatesEquivalent( +// view.getDistributionAggregates(), +// Arrays.asList( +// StatsTestUtil.createDistributionAggregate( +// // Won't record the unregistered tag key, will use default tag instead: +// // "KEY" : "unknown/not set". +// Arrays.asList(Tag.create(KEY, MutableViewData.UNKNOWN_TAG_VALUE)), +// BUCKET_BOUNDARIES, +// // Should record stats with default tag value: "KEY" : "unknown/not set". +// Arrays.asList(10.0, 50.0)))); +// } +// +// @Test +// public void testViewDataWithMultipleTagKeys() { +// TagKey key1 = TagKey.create("Key-1"); +// TagKey key2 = TagKey.create("Key-2"); +// viewManager.registerView( +// createDistributionView( +// VIEW_NAME, +// MEASURE, +// DISTRIBUTION_AGGREGATION_DESCRIPTOR, +// Arrays.asList(key1, key2))); +// statsRecorder.record( +// createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), +// MeasureMap.builder().set(MEASURE, 1.1).build()); +// statsRecorder.record( +// createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v20")), +// MeasureMap.builder().set(MEASURE, 2.2).build()); +// statsRecorder.record( +// createContext(factory, key1, TagValue.create("v2"), key2, TagValue.create("v10")), +// MeasureMap.builder().set(MEASURE, 3.3).build()); +// statsRecorder.record( +// createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), +// MeasureMap.builder().set(MEASURE, 4.4).build()); +// DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); +// assertDistributionAggregatesEquivalent( +// view.getDistributionAggregates(), +// Arrays.asList( +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList( +// Tag.create(key1, TagValue.create("v1")), +// Tag.create(key2, TagValue.create("v10"))), +// BUCKET_BOUNDARIES, +// Arrays.asList(1.1, 4.4)), +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList( +// Tag.create(key1, TagValue.create("v1")), +// Tag.create(key2, TagValue.create("v20"))), +// BUCKET_BOUNDARIES, +// Arrays.asList(2.2)), +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList( +// Tag.create(key1, TagValue.create("v2")), +// Tag.create(key2, TagValue.create("v10"))), +// BUCKET_BOUNDARIES, +// Arrays.asList(3.3)))); +// } +// +// @Test +// public void testMultipleViewDatasSameMeasure() { +// View view1 = +// createDistributionView( +// VIEW_NAME, +// MEASURE, +// DISTRIBUTION_AGGREGATION_DESCRIPTOR, +// Arrays.asList(KEY)); +// View view2 = +// createDistributionView( +// VIEW_NAME_2, +// MEASURE, +// DISTRIBUTION_AGGREGATION_DESCRIPTOR, +// Arrays.asList(KEY)); +// clock.setTime(Timestamp.create(1, 1)); +// viewManager.registerView(view1); +// clock.setTime(Timestamp.create(2, 2)); +// viewManager.registerView(view2); +// statsRecorder.record( +// createContext(factory, KEY, VALUE), +// MeasureMap.builder().set(MEASURE, 5.0).build()); +// List expectedAggs = +// Arrays.asList( +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(5.0))); +// clock.setTime(Timestamp.create(3, 3)); +// DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); +// clock.setTime(Timestamp.create(4, 4)); +// DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME_2); +// assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(1, 1)); +// assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(3, 3)); +// assertDistributionAggregatesEquivalent(viewData1.getDistributionAggregates(), expectedAggs); +// assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(2, 2)); +// assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(4, 4)); +// assertDistributionAggregatesEquivalent(viewData2.getDistributionAggregates(), expectedAggs); +// } +// +// @Test +// public void testMultipleViewsDifferentMeasures() { +// MeasureDouble measure1 = +// Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); +// MeasureDouble measure2 = +// Measure.MeasureDouble.create(MEASURE_NAME_2, MEASURE_DESCRIPTION, MEASURE_UNIT); +// View view1 = +// createDistributionView( +// VIEW_NAME, measure1, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); +// View view2 = +// createDistributionView( +// VIEW_NAME_2, measure2, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); +// clock.setTime(Timestamp.create(1, 0)); +// viewManager.registerView(view1); +// clock.setTime(Timestamp.create(2, 0)); +// viewManager.registerView(view2); +// statsRecorder.record( +// createContext(factory, KEY, VALUE), +// MeasureMap.builder().set(measure1, 1.1).set(measure2, 2.2).build()); +// clock.setTime(Timestamp.create(3, 0)); +// DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); +// clock.setTime(Timestamp.create(4, 0)); +// DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME_2); +// assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(1, 0)); +// assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(3, 0)); +// assertDistributionAggregatesEquivalent( +// viewData1.getDistributionAggregates(), +// Arrays.asList( +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(1.1)))); +// assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(2, 0)); +// assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(4, 0)); +// assertDistributionAggregatesEquivalent( +// viewData2.getDistributionAggregates(), +// Arrays.asList( +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(2.2)))); +// } +// +// @Test +// public void testGetDistributionViewDataWithoutBucketBoundaries() { +// View view = +// createDistributionView( +// VIEW_NAME, MEASURE, DistributionAggregation.create(), +// Arrays.asList(KEY)); +// clock.setTime(Timestamp.create(1, 0)); +// viewManager.registerView(view); +// statsRecorder.record( +// createContext(factory, KEY, VALUE), +// MeasureMap.builder().set(MEASURE, 1.1).build()); +// clock.setTime(Timestamp.create(3, 0)); +// DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); +// assertThat(viewData.getStart()).isEqualTo(Timestamp.create(1, 0)); +// assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(3, 0)); +// assertDistributionAggregatesEquivalent( +// viewData.getDistributionAggregates(), +// Arrays.asList( +// StatsTestUtil.createDistributionAggregate( +// Arrays.asList(Tag.create(KEY, VALUE)), Arrays.asList(1.1)))); +// } // TODO(sebright) Consider making this helper method work with larger ranges of double values and // moving it to StatsTestUtil. From a04fdcaaa2dede5c7554e71f632491379fa7edd7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 26 Jul 2017 12:24:20 -0700 Subject: [PATCH 0336/1581] Add a no-op TagsComponent to return when no implementation is available. The no-op TagsComponent will allow users to record stats without checking for null. If no implementation is available, the tagging operations should be very fast, because the no-op TagsComponent contains a no-op TagContextFactory, which will only ever return an empty TagContext. --- .../io/opencensus/tags/TagContextFactory.java | 17 ++++++++++++++ .../main/java/io/opencensus/tags/Tags.java | 7 ++---- .../io/opencensus/tags/TagsComponent.java | 23 +++++++++++++++++++ .../java/io/opencensus/tags/TagsTest.java | 5 ++-- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagContextFactory.java b/core/src/main/java/io/opencensus/tags/TagContextFactory.java index b68036b396..1103763e9c 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextFactory.java +++ b/core/src/main/java/io/opencensus/tags/TagContextFactory.java @@ -13,10 +13,27 @@ package io.opencensus.tags; +import javax.annotation.concurrent.Immutable; + /** * Factory for new {@link TagContext}s and {@code TagContext}s based on the current context. */ // TODO(sebright): Pick a more descriptive name for this class. public abstract class TagContextFactory { + private static final TagContextFactory NOOP_TAG_CONTEXT_FACTORY = new NoopTagContextFactory(); + // TODO(sebright): Add TagContext related methods to this class. + + /** + * Returns a {@code TagContextFactory} that only produces {@link TagContext}s with no tags. + * + * @return a {@code TagContextFactory} that only produces {@code TagContext}s with no tags. + */ + static TagContextFactory getNoopTagContextFactory() { + return NOOP_TAG_CONTEXT_FACTORY; + } + + @Immutable + private static final class NoopTagContextFactory extends TagContextFactory { + } } diff --git a/core/src/main/java/io/opencensus/tags/Tags.java b/core/src/main/java/io/opencensus/tags/Tags.java index bc0dbd0f65..dbec77f9c3 100644 --- a/core/src/main/java/io/opencensus/tags/Tags.java +++ b/core/src/main/java/io/opencensus/tags/Tags.java @@ -17,7 +17,6 @@ import io.opencensus.internal.Provider; import java.util.logging.Level; import java.util.logging.Logger; -import javax.annotation.Nullable; /** Class for accessing the default {@link TagsComponent}. */ public final class Tags { @@ -34,12 +33,11 @@ private Tags() {} * @return the default {@code TagContextFactory}. */ public static TagContextFactory getTagContextFactory() { - return tagsComponent == null ? null : tagsComponent.getTagContextFactory(); + return tagsComponent.getTagContextFactory(); } // Any provider that may be used for TagsComponent can be added here. @VisibleForTesting - @Nullable static TagsComponent loadTagsComponent(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. @@ -65,7 +63,6 @@ static TagsComponent loadTagsComponent(ClassLoader classLoader) { + "default implementation for TagsComponent.", e); } - // TODO: Add a no-op implementation. - return null; + return TagsComponent.getNoopTagsComponent(); } } diff --git a/core/src/main/java/io/opencensus/tags/TagsComponent.java b/core/src/main/java/io/opencensus/tags/TagsComponent.java index 67369ea850..14e2925c06 100644 --- a/core/src/main/java/io/opencensus/tags/TagsComponent.java +++ b/core/src/main/java/io/opencensus/tags/TagsComponent.java @@ -13,13 +13,36 @@ package io.opencensus.tags; +import javax.annotation.concurrent.Immutable; + /** * Class that holds the implementation for {@link TagContextFactory}. * *

All objects returned by methods on {@code TagsComponent} are cacheable. */ public abstract class TagsComponent { + private static final TagsComponent NOOP_TAGS_COMPONENT = new NoopTagsComponent(); /** Returns the {@link TagContextFactory} for this implementation. */ abstract TagContextFactory getTagContextFactory(); + + /** + * Returns a {@code TagsComponent} that has a no-op implementation for the {@link + * TagContextFactory}. + * + * @return a {@code TagsComponent} that has a no-op implementation for the {@code + * TagContextFactory}. + */ + static TagsComponent getNoopTagsComponent() { + return NOOP_TAGS_COMPONENT; + } + + @Immutable + private static final class NoopTagsComponent extends TagsComponent { + + @Override + TagContextFactory getTagContextFactory() { + return TagContextFactory.getNoopTagContextFactory(); + } + } } diff --git a/core/src/test/java/io/opencensus/tags/TagsTest.java b/core/src/test/java/io/opencensus/tags/TagsTest.java index c4530263ef..f80f8c5b87 100644 --- a/core/src/test/java/io/opencensus/tags/TagsTest.java +++ b/core/src/test/java/io/opencensus/tags/TagsTest.java @@ -49,11 +49,12 @@ public Class loadClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(); } }; - assertThat(Tags.loadTagsComponent(classLoader)).isNull(); + assertThat(Tags.loadTagsComponent(classLoader).getClass().getName()) + .isEqualTo("io.opencensus.tags.TagsComponent$NoopTagsComponent"); } @Test public void defaultTagContextFactory() { - assertThat(Tags.getTagContextFactory()).isNull(); + assertThat(Tags.getTagContextFactory()).isEqualTo(TagContextFactory.getNoopTagContextFactory()); } } From bacb356ebae6f1c2f5db1dec3753a37b1e9b36ee Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 27 Jul 2017 10:08:27 -0700 Subject: [PATCH 0337/1581] Move tagging implementation classes into io.opencensus.impl.tags. (part of #379) This change will ensure that the 'tags' implementation only accesses the API classes through their public API. That will help us maintain backwards compatibility. --- core/src/main/java/io/opencensus/tags/Tags.java | 4 ++-- core/src/main/java/io/opencensus/tags/TagsComponent.java | 4 ++-- .../io/opencensus/{ => impl}/tags/TagContextFactoryImpl.java | 4 +++- .../io/opencensus/{ => impl}/tags/TagsComponentImplBase.java | 5 ++++- .../io/opencensus/{ => impl}/tags/TagsComponentImplLite.java | 4 +++- .../test/java/io/opencensus/{ => impl}/tags/TagsTest.java | 4 +++- .../io/opencensus/{ => impl}/tags/TagsComponentImpl.java | 4 +++- .../test/java/io/opencensus/{ => impl}/tags/TagsTest.java | 4 +++- 8 files changed, 23 insertions(+), 10 deletions(-) rename core_impl/src/main/java/io/opencensus/{ => impl}/tags/TagContextFactoryImpl.java (89%) rename core_impl/src/main/java/io/opencensus/{ => impl}/tags/TagsComponentImplBase.java (88%) rename core_impl_android/src/main/java/io/opencensus/{ => impl}/tags/TagsComponentImplLite.java (90%) rename core_impl_android/src/test/java/io/opencensus/{ => impl}/tags/TagsTest.java (90%) rename core_impl_java/src/main/java/io/opencensus/{ => impl}/tags/TagsComponentImpl.java (90%) rename core_impl_java/src/test/java/io/opencensus/{ => impl}/tags/TagsTest.java (90%) diff --git a/core/src/main/java/io/opencensus/tags/Tags.java b/core/src/main/java/io/opencensus/tags/Tags.java index dbec77f9c3..ba88ca06ae 100644 --- a/core/src/main/java/io/opencensus/tags/Tags.java +++ b/core/src/main/java/io/opencensus/tags/Tags.java @@ -42,7 +42,7 @@ static TagsComponent loadTagsComponent(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. return Provider.createInstance( - Class.forName("io.opencensus.tags.TagsComponentImpl", true, classLoader), + Class.forName("io.opencensus.impl.tags.TagsComponentImpl", true, classLoader), TagsComponent.class); } catch (ClassNotFoundException e) { logger.log( @@ -54,7 +54,7 @@ static TagsComponent loadTagsComponent(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. return Provider.createInstance( - Class.forName("io.opencensus.tags.TagsComponentImplLite", true, classLoader), + Class.forName("io.opencensus.impl.tags.TagsComponentImplLite", true, classLoader), TagsComponent.class); } catch (ClassNotFoundException e) { logger.log( diff --git a/core/src/main/java/io/opencensus/tags/TagsComponent.java b/core/src/main/java/io/opencensus/tags/TagsComponent.java index 14e2925c06..a9c9258977 100644 --- a/core/src/main/java/io/opencensus/tags/TagsComponent.java +++ b/core/src/main/java/io/opencensus/tags/TagsComponent.java @@ -24,7 +24,7 @@ public abstract class TagsComponent { private static final TagsComponent NOOP_TAGS_COMPONENT = new NoopTagsComponent(); /** Returns the {@link TagContextFactory} for this implementation. */ - abstract TagContextFactory getTagContextFactory(); + public abstract TagContextFactory getTagContextFactory(); /** * Returns a {@code TagsComponent} that has a no-op implementation for the {@link @@ -41,7 +41,7 @@ static TagsComponent getNoopTagsComponent() { private static final class NoopTagsComponent extends TagsComponent { @Override - TagContextFactory getTagContextFactory() { + public TagContextFactory getTagContextFactory() { return TagContextFactory.getNoopTagContextFactory(); } } diff --git a/core_impl/src/main/java/io/opencensus/tags/TagContextFactoryImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java similarity index 89% rename from core_impl/src/main/java/io/opencensus/tags/TagContextFactoryImpl.java rename to core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java index 248a851bed..9ab62a6887 100644 --- a/core_impl/src/main/java/io/opencensus/tags/TagContextFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java @@ -11,7 +11,9 @@ * limitations under the License. */ -package io.opencensus.tags; +package io.opencensus.impl.tags; + +import io.opencensus.tags.TagContextFactory; final class TagContextFactoryImpl extends TagContextFactory { } diff --git a/core_impl/src/main/java/io/opencensus/tags/TagsComponentImplBase.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java similarity index 88% rename from core_impl/src/main/java/io/opencensus/tags/TagsComponentImplBase.java rename to core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java index 3f789bf68e..9c85858536 100644 --- a/core_impl/src/main/java/io/opencensus/tags/TagsComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java @@ -11,7 +11,10 @@ * limitations under the License. */ -package io.opencensus.tags; +package io.opencensus.impl.tags; + +import io.opencensus.tags.TagContextFactory; +import io.opencensus.tags.TagsComponent; /** Base implementation of {@link TagsComponent}. */ public abstract class TagsComponentImplBase extends TagsComponent { diff --git a/core_impl_android/src/main/java/io/opencensus/tags/TagsComponentImplLite.java b/core_impl_android/src/main/java/io/opencensus/impl/tags/TagsComponentImplLite.java similarity index 90% rename from core_impl_android/src/main/java/io/opencensus/tags/TagsComponentImplLite.java rename to core_impl_android/src/main/java/io/opencensus/impl/tags/TagsComponentImplLite.java index ec232e21f7..3a66d3192d 100644 --- a/core_impl_android/src/main/java/io/opencensus/tags/TagsComponentImplLite.java +++ b/core_impl_android/src/main/java/io/opencensus/impl/tags/TagsComponentImplLite.java @@ -11,7 +11,9 @@ * limitations under the License. */ -package io.opencensus.tags; +package io.opencensus.impl.tags; + +import io.opencensus.tags.TagsComponent; /** Android-compatible implementation of {@link TagsComponent}. */ public final class TagsComponentImplLite extends TagsComponentImplBase {} diff --git a/core_impl_android/src/test/java/io/opencensus/tags/TagsTest.java b/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java similarity index 90% rename from core_impl_android/src/test/java/io/opencensus/tags/TagsTest.java rename to core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java index e9457b1224..bb6c3fd6b5 100644 --- a/core_impl_android/src/test/java/io/opencensus/tags/TagsTest.java +++ b/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java @@ -11,10 +11,12 @@ * limitations under the License. */ -package io.opencensus.tags; +package io.opencensus.impl.tags; import static com.google.common.truth.Truth.assertThat; +import io.opencensus.tags.Tags; +import io.opencensus.tags.TagsComponent; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core_impl_java/src/main/java/io/opencensus/tags/TagsComponentImpl.java b/core_impl_java/src/main/java/io/opencensus/impl/tags/TagsComponentImpl.java similarity index 90% rename from core_impl_java/src/main/java/io/opencensus/tags/TagsComponentImpl.java rename to core_impl_java/src/main/java/io/opencensus/impl/tags/TagsComponentImpl.java index 9c9404bd3c..c360ae602d 100644 --- a/core_impl_java/src/main/java/io/opencensus/tags/TagsComponentImpl.java +++ b/core_impl_java/src/main/java/io/opencensus/impl/tags/TagsComponentImpl.java @@ -11,7 +11,9 @@ * limitations under the License. */ -package io.opencensus.tags; +package io.opencensus.impl.tags; + +import io.opencensus.tags.TagsComponent; /** Java 7 and 8 implementation of {@link TagsComponent}. */ public final class TagsComponentImpl extends TagsComponentImplBase {} diff --git a/core_impl_java/src/test/java/io/opencensus/tags/TagsTest.java b/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java similarity index 90% rename from core_impl_java/src/test/java/io/opencensus/tags/TagsTest.java rename to core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java index e9457b1224..bb6c3fd6b5 100644 --- a/core_impl_java/src/test/java/io/opencensus/tags/TagsTest.java +++ b/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java @@ -11,10 +11,12 @@ * limitations under the License. */ -package io.opencensus.tags; +package io.opencensus.impl.tags; import static com.google.common.truth.Truth.assertThat; +import io.opencensus.tags.Tags; +import io.opencensus.tags.TagsComponent; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; From 157ea92ea81a63d82bdbe4caaf01bf1a1b519674 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 27 Jul 2017 14:06:32 -0700 Subject: [PATCH 0338/1581] Add initial package-info.java to the 'tags' package. --- .../java/io/opencensus/tags/package-info.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 core/src/main/java/io/opencensus/tags/package-info.java diff --git a/core/src/main/java/io/opencensus/tags/package-info.java b/core/src/main/java/io/opencensus/tags/package-info.java new file mode 100644 index 0000000000..5e60c7bd6b --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/package-info.java @@ -0,0 +1,27 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * API for associating tags with scoped operations. + * + *

This package manages a set of tags in the {@code io.grpc.Context}. The tags can be used to + * label anything that is associated with a specific operation. For example, the {@link + * io.opencensus.stats} package labels all measurements with the current tags. + * + *

{@link io.opencensus.tags.Tag Tags} are key-value pairs. The {@link io.opencensus.tags.TagKey + * keys} are wrapped {@code String}s, but the values can have multiple types, such as {@code + * String}, {@code long}, and {@code boolean}. They are stored as a map in a {@link + * io.opencensus.tags.TagContext}. + */ +// TODO(sebright): Add code examples after the API is updated to use a TagContext factory. +package io.opencensus.tags; From 0251f240c9ff2139de47620e581c5c1d3e191321 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 28 Jul 2017 04:29:42 +0200 Subject: [PATCH 0339/1581] Add a test for avoiding double duty context propagation for Executors. Oh, well, it turns out I have to leave a TODO there for now. The previous commit does work, but there's another unneeded context propagation that could be removed. At least for CurrentContextExecutor I have an idea, but not yet sure about FixedContextExecutor. --- .../agent/ExecutorInstrumentationTest.java | 42 +++++++++++++++++++ .../agent/ExecutorInstrumentation.java | 6 ++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java index 563ae120e5..c94b4b5a40 100644 --- a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java +++ b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java @@ -148,4 +148,46 @@ public void run() { assertThat(future.get()).isSameAs(result); assertThat(tested.get()).isTrue(); } + + @Test(timeout = 5000) + public void currentContextExecutor() throws Exception { + final Thread callerThread = Thread.currentThread(); + final Context context = Context.current().withValue(KEY, "myvalue"); + previousContext = context.attach(); + + final AtomicBoolean tested = new AtomicBoolean(false); + + Context.currentContextExecutor(executor).execute(new Runnable() { + @Override + public void run() { + StackTraceElement[] ste = new Exception().fillInStackTrace().getStackTrace(); + assertThat(ste[0].getClassName()).doesNotContain("Context"); + assertThat(ste[1].getClassName()).startsWith("io.grpc.Context$"); + // NB: Actually, we want the Runnable to be wrapped only once, but currently it is still + // wrapped twice. The two places where the Runnable is wrapped are: (1) the executor + // implementation itself, e.g. ThreadPoolExecutor, to which the Agent added automatic + // context propagation, (2) CurrentContextExecutor. + // ExecutorInstrumentation already avoids adding the automatic context propagation to + // CurrentContextExecutor, but does not make it a no-op yet. Also see + // ExecutorInstrumentation#createMatcher. + assertThat(ste[2].getClassName()).startsWith("io.grpc.Context$"); + assertThat(ste[3].getClassName()).doesNotContain("Context"); + + assertThat(Thread.currentThread()).isNotSameAs(callerThread); + assertThat(Context.current()).isSameAs(context); + assertThat(KEY.get()).isEqualTo("myvalue"); + tested.set(true); + + synchronized (tested) { + tested.notify(); + } + } + }); + + synchronized (tested) { + tested.wait(); + } + + assertThat(tested.get()).isTrue(); + } } diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java index 19cf181df0..a6d09e301e 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java @@ -47,8 +47,12 @@ public DynamicType.Builder transform(DynamicType.Builder builder, } static ElementMatcher.Junction createMatcher() { - // Matches implementations of Executor, but excludes CurrentContextExecutor and + // This matcher matches implementations of Executor, but excludes CurrentContextExecutor and // FixedContextExecutor from io.grpc.Context, which already propagate the context. + // TODO(stschmidt): As the executor implementation itself (e.g. ThreadPoolExecutor) is + // instrumented by the agent for automatic context propagation, CurrentContextExecutor could be + // turned into a no-op to avoid another unneeded context propagation. Likewise, when using + // FixedContextExecutor, the automatic context propagation added by the agent is unneeded. return isSubTypeOf(Executor.class) .and(not(isAbstract())) .and(not(nameStartsWith("io.grpc.Context$") From c22acb06ea32b44bc84d8250437e08d6771c0db7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Jul 2017 13:43:50 -0700 Subject: [PATCH 0340/1581] Improve class-level documentation for TagKey and TagValueString. --- core/src/main/java/io/opencensus/tags/TagKey.java | 13 +++++++++++-- .../java/io/opencensus/tags/TagValueString.java | 9 +++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index 9d90235939..c8d2256732 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -20,10 +20,19 @@ import io.opencensus.internal.StringUtil; import javax.annotation.concurrent.Immutable; -/** A key to a value stored in a {@link TagContext}. */ +/** + * A key to a value stored in a {@link TagContext}. + * + *

There is one {@code TagKey} subclass corresponding to each tag value type, so that each key + * can only be paired with a single type of value. For example, {@link TagKeyString} can only be + * used to set {@link TagValueString} values in a {@code TagContext}. + * + *

Each {@code TagKey} has a {@code String} name. Names have a maximum length of {@link + * #MAX_LENGTH} and contain only printable ASCII characters. + */ @Immutable public abstract class TagKey { - /** The maximum length for a tag key name. */ + /** The maximum length for a tag key name. The value is {@value #MAX_LENGTH}. */ public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; TagKey() {} diff --git a/core/src/main/java/io/opencensus/tags/TagValueString.java b/core/src/main/java/io/opencensus/tags/TagValueString.java index 5f3e5bdaee..4c032f8f12 100644 --- a/core/src/main/java/io/opencensus/tags/TagValueString.java +++ b/core/src/main/java/io/opencensus/tags/TagValueString.java @@ -19,11 +19,16 @@ import io.opencensus.tags.TagKey.TagKeyString; import javax.annotation.concurrent.Immutable; -/** A validated tag value associated with a {@link TagKeyString}. */ +/** + * A validated tag value associated with a {@link TagKeyString}. + * + *

Validation ensures that the {@code String} has a maximum length of {@link #MAX_LENGTH} and + * contains only printable ASCII characters. + */ @Immutable @AutoValue public abstract class TagValueString { - /** The maximum length for a {@code String} tag value. */ + /** The maximum length for a {@code String} tag value. The value is {@value #MAX_LENGTH}. */ public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; TagValueString() {} From 026ea6e76264812e19d2a51b3840c56359da841f Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Jul 2017 17:10:08 -0700 Subject: [PATCH 0341/1581] Remove a Javadoc link from the 'tags' package to the 'stats' package. --- core/src/main/java/io/opencensus/tags/package-info.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/io/opencensus/tags/package-info.java b/core/src/main/java/io/opencensus/tags/package-info.java index 5e60c7bd6b..ca0ae0061c 100644 --- a/core/src/main/java/io/opencensus/tags/package-info.java +++ b/core/src/main/java/io/opencensus/tags/package-info.java @@ -15,7 +15,7 @@ * API for associating tags with scoped operations. * *

This package manages a set of tags in the {@code io.grpc.Context}. The tags can be used to - * label anything that is associated with a specific operation. For example, the {@link + * label anything that is associated with a specific operation. For example, the {@code * io.opencensus.stats} package labels all measurements with the current tags. * *

{@link io.opencensus.tags.Tag Tags} are key-value pairs. The {@link io.opencensus.tags.TagKey From 6f4ad199faa5e065ff98f6b1d7b7994ae6a56e6c Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Jul 2017 17:19:23 -0700 Subject: [PATCH 0342/1581] Reword a Javadoc comment. --- core/src/main/java/io/opencensus/tags/package-info.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/io/opencensus/tags/package-info.java b/core/src/main/java/io/opencensus/tags/package-info.java index ca0ae0061c..e5792ac307 100644 --- a/core/src/main/java/io/opencensus/tags/package-info.java +++ b/core/src/main/java/io/opencensus/tags/package-info.java @@ -16,7 +16,7 @@ * *

This package manages a set of tags in the {@code io.grpc.Context}. The tags can be used to * label anything that is associated with a specific operation. For example, the {@code - * io.opencensus.stats} package labels all measurements with the current tags. + * io.opencensus.stats} package labels all stats with the current tags. * *

{@link io.opencensus.tags.Tag Tags} are key-value pairs. The {@link io.opencensus.tags.TagKey * keys} are wrapped {@code String}s, but the values can have multiple types, such as {@code From e82e10e9a1c15314d44bb9469c739920f352ea21 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Jul 2017 17:11:46 -0700 Subject: [PATCH 0343/1581] Explain that trace ID is not included in the TagContext. --- core/src/main/java/io/opencensus/tags/package-info.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/io/opencensus/tags/package-info.java b/core/src/main/java/io/opencensus/tags/package-info.java index e5792ac307..11d1b09df5 100644 --- a/core/src/main/java/io/opencensus/tags/package-info.java +++ b/core/src/main/java/io/opencensus/tags/package-info.java @@ -22,6 +22,9 @@ * keys} are wrapped {@code String}s, but the values can have multiple types, such as {@code * String}, {@code long}, and {@code boolean}. They are stored as a map in a {@link * io.opencensus.tags.TagContext}. + * + *

Note that tags are independent of the tracing data that is propagated in the {@code + * io.grpc.Context}, such as trace ID. */ // TODO(sebright): Add code examples after the API is updated to use a TagContext factory. package io.opencensus.tags; From bc3f453474efb4808bc48722e310e1d59e76a489 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 31 Jul 2017 00:37:41 +0200 Subject: [PATCH 0344/1581] Add JMH benchmarks for Executor#execute with and without context propagation. --- contrib/agent/build.gradle | 38 +++++++++ .../ExecutorInstrumentationBenchmark.java | 81 +++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 1cf4f5d032..741a9674fa 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.github.johnrengelman.shadow' version '2.0.1' id 'me.tatarka.retrolambda' version '3.6.0' + id "me.champeau.gradle.jmh" version "0.4.4" } description = 'OpenCensus Agent' @@ -157,3 +158,40 @@ task integrationTest(type: Test) { check.dependsOn integrationTest integrationTest.mustRunAfter test + +// JMH benchmarks + +dependencies { + jmh libraries.grpc_context +} + +// Disable checkstyle for JMH benchmarks if not java8. +checkstyleJmh.enabled = JavaVersion.current().isJava8Compatible() + +// Generate html report for findbugsJmh. +findbugsJmh { + reports { + xml.enabled = false + html.enabled = true + } +} + +// Make the agent JAR available using a fixed file name so that we don't have to modify the JMH +// benchmarks whenever the version changes. +task agentJar(type: Copy) { + dependsOn shadowJar + + from shadowJar.archivePath + into libsDir + rename { 'agent.jar' } +} + +jmhJar.dependsOn agentJar + +jmh { + jmhVersion = '1.19' + warmupIterations = 10 + iterations = 10 + fork = 1 + failOnError = true +} diff --git a/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java new file mode 100644 index 0000000000..41bb74db31 --- /dev/null +++ b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent; + +import com.google.common.util.concurrent.MoreExecutors; +import io.grpc.Context; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.infra.Blackhole; + +/** Benchmarks for automatic context propagation added by {@link ExecutorInstrumentation}. */ +public class ExecutorInstrumentationBenchmark { + + private static class MyRunnable implements Runnable { + + private final Blackhole blackhole; + + private MyRunnable(Blackhole blackhole) { + this.blackhole = blackhole; + } + + @Override + public void run() { + blackhole.consume(Context.current()); + } + } + + /** + * This benchmark attempts to measure the performance without any context propagation. + * + * @param blackhole a {@Blackhole} object supplied by JMH + */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @Fork + public void none(final Blackhole blackhole) { + MoreExecutors.directExecutor().execute(new MyRunnable(blackhole)); + } + + /** + * This benchmark attempts to measure the performance with manual context propagation. + * + * @param blackhole a {@Blackhole} object supplied by JMH + */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @Fork + public void manual(final Blackhole blackhole) { + MoreExecutors.directExecutor().execute(Context.current().wrap(new MyRunnable(blackhole))); + } + + /** + * This benchmark attempts to measure the performance with automatic context propagation. + * + * @param blackhole a {@Blackhole} object supplied by JMH + */ + @Benchmark + @BenchmarkMode(Mode.SampleTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @Fork(jvmArgsAppend = "-javaagent:contrib/agent/build/libs/agent.jar") + public void automatic(final Blackhole blackhole) { + MoreExecutors.directExecutor().execute(new MyRunnable(blackhole)); + } +} From a3eab60a0b886cb32d5875404c7fa941298e56fb Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 31 Jul 2017 17:17:55 +0200 Subject: [PATCH 0345/1581] Fix Javadoc. --- .../contrib/agent/ExecutorInstrumentationBenchmark.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java index 41bb74db31..3f3b45664a 100644 --- a/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java +++ b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java @@ -43,7 +43,7 @@ public void run() { /** * This benchmark attempts to measure the performance without any context propagation. * - * @param blackhole a {@Blackhole} object supplied by JMH + * @param blackhole a {@link Blackhole} object supplied by JMH */ @Benchmark @BenchmarkMode(Mode.SampleTime) @@ -56,7 +56,7 @@ public void none(final Blackhole blackhole) { /** * This benchmark attempts to measure the performance with manual context propagation. * - * @param blackhole a {@Blackhole} object supplied by JMH + * @param blackhole a {@link Blackhole} object supplied by JMH */ @Benchmark @BenchmarkMode(Mode.SampleTime) @@ -69,7 +69,7 @@ public void manual(final Blackhole blackhole) { /** * This benchmark attempts to measure the performance with automatic context propagation. * - * @param blackhole a {@Blackhole} object supplied by JMH + * @param blackhole a {@link Blackhole} object supplied by JMH */ @Benchmark @BenchmarkMode(Mode.SampleTime) From a88ec1d206d90cc65df126ebbc34b568cc3cc816 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 31 Jul 2017 17:30:36 +0200 Subject: [PATCH 0346/1581] Also enable Mode.AverageTime in addition to Mode.SampleTime. --- .../contrib/agent/ExecutorInstrumentationBenchmark.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java index 3f3b45664a..80aaf1911d 100644 --- a/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java +++ b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java @@ -46,7 +46,7 @@ public void run() { * @param blackhole a {@link Blackhole} object supplied by JMH */ @Benchmark - @BenchmarkMode(Mode.SampleTime) + @BenchmarkMode({Mode.AverageTime, Mode.SampleTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) @Fork public void none(final Blackhole blackhole) { @@ -59,7 +59,7 @@ public void none(final Blackhole blackhole) { * @param blackhole a {@link Blackhole} object supplied by JMH */ @Benchmark - @BenchmarkMode(Mode.SampleTime) + @BenchmarkMode({Mode.AverageTime, Mode.SampleTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) @Fork public void manual(final Blackhole blackhole) { @@ -72,7 +72,7 @@ public void manual(final Blackhole blackhole) { * @param blackhole a {@link Blackhole} object supplied by JMH */ @Benchmark - @BenchmarkMode(Mode.SampleTime) + @BenchmarkMode({Mode.AverageTime, Mode.SampleTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) @Fork(jvmArgsAppend = "-javaagent:contrib/agent/build/libs/agent.jar") public void automatic(final Blackhole blackhole) { From e24b08ae25c05a37bacae0a7db936b294b08ac95 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 31 Jul 2017 23:38:11 +0200 Subject: [PATCH 0347/1581] Removed Mode.SampeTime because the histograms are of poor quality and often misleading. --- .../contrib/agent/ExecutorInstrumentationBenchmark.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java index 80aaf1911d..980797060d 100644 --- a/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java +++ b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java @@ -46,7 +46,7 @@ public void run() { * @param blackhole a {@link Blackhole} object supplied by JMH */ @Benchmark - @BenchmarkMode({Mode.AverageTime, Mode.SampleTime}) + @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @Fork public void none(final Blackhole blackhole) { @@ -59,7 +59,7 @@ public void none(final Blackhole blackhole) { * @param blackhole a {@link Blackhole} object supplied by JMH */ @Benchmark - @BenchmarkMode({Mode.AverageTime, Mode.SampleTime}) + @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @Fork public void manual(final Blackhole blackhole) { @@ -72,7 +72,7 @@ public void manual(final Blackhole blackhole) { * @param blackhole a {@link Blackhole} object supplied by JMH */ @Benchmark - @BenchmarkMode({Mode.AverageTime, Mode.SampleTime}) + @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @Fork(jvmArgsAppend = "-javaagent:contrib/agent/build/libs/agent.jar") public void automatic(final Blackhole blackhole) { From 3b2d1f4e7f776797fe9a07dace077ca341ef32ea Mon Sep 17 00:00:00 2001 From: Yang Song Date: Mon, 31 Jul 2017 14:47:49 -0700 Subject: [PATCH 0348/1581] Add MutableAggregation and tests. (#480) --- .../io/opencensus/stats/BucketBoundaries.java | 8 +- .../opencensus/stats/MutableAggregation.java | 353 ++++++++++++++++++ .../stats/MutableAggregationTest.java | 195 ++++++++++ 3 files changed, 551 insertions(+), 5 deletions(-) create mode 100644 core_impl/src/main/java/io/opencensus/stats/MutableAggregation.java create mode 100644 core_impl/src/test/java/io/opencensus/stats/MutableAggregationTest.java diff --git a/core/src/main/java/io/opencensus/stats/BucketBoundaries.java b/core/src/main/java/io/opencensus/stats/BucketBoundaries.java index adcbefbcc4..4fd0a126ce 100644 --- a/core/src/main/java/io/opencensus/stats/BucketBoundaries.java +++ b/core/src/main/java/io/opencensus/stats/BucketBoundaries.java @@ -22,16 +22,14 @@ import java.util.List; import javax.annotation.concurrent.Immutable; -/** - * The optional histogram bucket boundaries for an {@link Aggregation.Histogram}. - */ +/** The histogram bucket boundaries for an {@link Aggregation.Histogram}. */ @Immutable @AutoValue public abstract class BucketBoundaries { /** - * @param bucketBoundaries the boundaries for the buckets in the underlying - * {@link Aggregation.Histogram}. + * @param bucketBoundaries the boundaries for the buckets in the underlying {@link + * Aggregation.Histogram}. * @return a new {@code BucketBoundaries} with the specified boundaries. * @throws NullPointerException if {@code bucketBoundaries} is null. * @throws IllegalArgumentException if {@code bucketBoundaries} is not sorted. diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableAggregation.java b/core_impl/src/main/java/io/opencensus/stats/MutableAggregation.java new file mode 100644 index 0000000000..b044683d87 --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/stats/MutableAggregation.java @@ -0,0 +1,353 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.opencensus.common.Function; + +import java.util.Arrays; + +/** Mutable version of {@link Aggregation} that supports adding values. */ +abstract class MutableAggregation { + + private MutableAggregation() { + } + + /** + * Put a new value into the MutableAggregation. + * + * @param value new value to be added to population + */ + abstract void add(double value); + + /** + * Applies the given match function to the underlying data type. + */ + abstract T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5); + + /** Calculate sum on aggregated {@code MeasureValue}s. */ + static final class MutableSum extends MutableAggregation { + + private double sum = 0.0; + + private MutableSum() { + } + + /** + * Construct a {@code MutableSum}. + * + * @return an empty {@code MutableSum}. + */ + static MutableSum create() { + return new MutableSum(); + } + + @Override + void add(double value) { + sum += value; + } + + /** + * Returns the aggregated sum. + * + * @return the aggregated sum. + */ + double getSum() { + return sum; + } + + @Override + final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5) { + return p0.apply(this); + } + } + + /** Calculate count on aggregated {@code MeasureValue}s. */ + static final class MutableCount extends MutableAggregation { + + private long count = 0; + + private MutableCount() { + } + + /** + * Construct a {@code MutableCount}. + * + * @return an empty {@code MutableCount}. + */ + static MutableCount create() { + return new MutableCount(); + } + + @Override + void add(double value) { + count++; + } + + /** + * Returns the aggregated count. + * + * @return the aggregated count. + */ + long getCount() { + return count; + } + + @Override + final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5) { + return p1.apply(this); + } + } + + /** Calculate histogram on aggregated {@code MeasureValue}s. */ + static final class MutableHistogram extends MutableAggregation { + + private final BucketBoundaries bucketBoundaries; + private final long[] bucketCounts; + + private MutableHistogram(BucketBoundaries bucketBoundaries) { + this.bucketBoundaries = bucketBoundaries; + this.bucketCounts = new long[bucketBoundaries.getBoundaries().size() + 1]; + } + + /** + * Construct a {@code MutableHistogram}. + * + * @return an empty {@code MutableHistogram}. + */ + static MutableHistogram create(BucketBoundaries bucketBoundaries) { + checkNotNull(bucketBoundaries, "bucketBoundaries should not be null."); + return new MutableHistogram(bucketBoundaries); + } + + @Override + void add(double value) { + for (int i = 0; i < bucketBoundaries.getBoundaries().size(); i++) { + if (value < bucketBoundaries.getBoundaries().get(i)) { + bucketCounts[i]++; + return; + } + } + bucketCounts[bucketCounts.length - 1]++; + } + + /** + * Returns the aggregated bucket count. + * + * @return the aggregated bucket count. + */ + long[] getBucketCounts() { + return Arrays.copyOf(bucketCounts, bucketCounts.length); + } + + @Override + final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5) { + return p2.apply(this); + } + } + + /** Calculate range on aggregated {@code MeasureValue}s. */ + static final class MutableRange extends MutableAggregation { + + // Initial "impossible" values, that will get reset as soon as first value is added. + private double min = Double.POSITIVE_INFINITY; + private double max = Double.NEGATIVE_INFINITY; + + private MutableRange() { + } + + /** + * Construct a {@code MutableRange}. + * + * @return an empty {@code MutableRange}. + */ + static MutableRange create() { + return new MutableRange(); + } + + /** + * The minimum of the population values. + * + * @return The minimum of the population values. + */ + double getMin() { + return min; + } + + /** + * The maximum of the population values. + * + * @return The maximum of the population values. + */ + double getMax() { + return max; + } + + /** + * Put a new value into the Range. Sets min and max values if appropriate. + * + * @param value the new value + */ + @Override + void add(double value) { + if (value < min) { + min = value; + } + if (value > max) { + max = value; + } + } + + @Override + final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5) { + return p3.apply(this); + } + } + + /** Calculate mean on aggregated {@code MeasureValue}s. */ + static final class MutableMean extends MutableAggregation { + + private double mean = 0.0; + private long count = 0; + + private MutableMean() { + } + + /** + * Construct a {@code MutableMean}. + * + * @return an empty {@code MutableMean}. + */ + static MutableMean create() { + return new MutableMean(); + } + + @Override + void add(double value) { + count++; + double deltaFromMean = value - mean; + mean += deltaFromMean / count; + } + + /** + * Returns the aggregated mean. + * + * @return the aggregated mean. + */ + double getMean() { + return mean; + } + + @Override + final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5) { + return p4.apply(this); + } + } + + /** Calculate standard deviation on aggregated {@code MeasureValue}s. */ + static final class MutableStdDev extends MutableAggregation { + + private double sumOfSquaredDeviations = 0.0; + private double mean = 0.0; + private long count = 0; + + private MutableStdDev() { + } + + /** + * Construct a {@code MutableStdDev}. + * + * @return an empty {@code MutableStdDev}. + */ + static MutableStdDev create() { + return new MutableStdDev(); + } + + /** + * Update the sum of squared deviations from the mean with the given value. For values + * x_i this is Sum[i=1..n]((x_i - mean)^2) + * + *

Computed using Welfords method (see + * https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance, or Knuth, "The Art of + * Computer Programming", Vol. 2, page 323, 3rd edition) + */ + @Override + void add(double value) { + count++; + double deltaFromMean = value - mean; + mean += deltaFromMean / count; + double deltaFromMean2 = value - mean; + sumOfSquaredDeviations += deltaFromMean * deltaFromMean2; + } + + /** + * Returns the aggregated standard deviations. + * + *

If count is zero then this value will also be zero. + * + * @return the aggregated standard deviations. + */ + double getStdDev() { + return count == 0 ? 0 : Math.sqrt(sumOfSquaredDeviations / count); + } + + @Override + final T match( + Function p0, + Function p1, + Function p2, + Function p3, + Function p4, + Function p5) { + return p5.apply(this); + } + } +} diff --git a/core_impl/src/test/java/io/opencensus/stats/MutableAggregationTest.java b/core_impl/src/test/java/io/opencensus/stats/MutableAggregationTest.java new file mode 100644 index 0000000000..960f9f1089 --- /dev/null +++ b/core_impl/src/test/java/io/opencensus/stats/MutableAggregationTest.java @@ -0,0 +1,195 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.common.Function; +import io.opencensus.stats.MutableAggregation.MutableCount; +import io.opencensus.stats.MutableAggregation.MutableHistogram; +import io.opencensus.stats.MutableAggregation.MutableMean; +import io.opencensus.stats.MutableAggregation.MutableRange; +import io.opencensus.stats.MutableAggregation.MutableStdDev; +import io.opencensus.stats.MutableAggregation.MutableSum; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link io.opencensus.stats.MutableAggregation}. */ +@RunWith(JUnit4.class) +public class MutableAggregationTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private static final double TOLERANCE = 1e-6; + + @Test + public void testCreateEmpty() { + BucketBoundaries bucketBoundaries = BucketBoundaries.create(Arrays.asList(0.1, 2.2, 33.3)); + + assertThat(MutableSum.create().getSum()).isWithin(TOLERANCE).of(0); + assertThat(MutableCount.create().getCount()).isEqualTo(0); + assertThat(MutableHistogram.create(bucketBoundaries).getBucketCounts()) + .isEqualTo(new long[4]); + assertThat(MutableRange.create().getMin()).isPositiveInfinity(); + assertThat(MutableRange.create().getMax()).isNegativeInfinity(); + assertThat(MutableMean.create().getMean()).isWithin(TOLERANCE).of(0); + assertThat(MutableStdDev.create().getStdDev()).isWithin(TOLERANCE).of(0); + } + + @Test + public void testNullBucketBoundaries() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("bucketBoundaries should not be null."); + MutableHistogram.create(null); + } + + @Test + public void testNoBoundaries() { + List buckets = Arrays.asList(); + MutableHistogram noBoundaries = + MutableHistogram.create(BucketBoundaries.create(buckets)); + assertThat(noBoundaries.getBucketCounts().length).isEqualTo(1); + assertThat(noBoundaries.getBucketCounts()[0]).isEqualTo(0); + } + + @Test + public void testAdd() { + List aggregations = Arrays.asList( + MutableSum.create(), + MutableCount.create(), + MutableHistogram.create( + BucketBoundaries.create(Arrays.asList(-10.0, 0.0, 10.0))), + MutableRange.create(), + MutableMean.create(), + MutableStdDev.create()); + + List values = Arrays.asList(-1.0, 1.0, -5.0, 20.0, 5.0); + + for (double value : values) { + for (MutableAggregation aggregation : aggregations) { + aggregation.add(value); + } + } + + for (MutableAggregation aggregation : aggregations) { + aggregation.match( + new Function() { + @Override + public Void apply(MutableSum arg) { + assertThat(arg.getSum()).isWithin(TOLERANCE).of(20.0); + return null; + } + }, + new Function() { + @Override + public Void apply(MutableCount arg) { + assertThat(arg.getCount()).isEqualTo(5); + return null; + } + }, + new Function() { + @Override + public Void apply(MutableHistogram arg) { + assertThat(arg.getBucketCounts()).isEqualTo(new long[]{0, 2, 2, 1}); + return null; + } + }, + new Function() { + @Override + public Void apply(MutableRange arg) { + assertThat(arg.getMin()).isWithin(TOLERANCE).of(-5.0); + assertThat(arg.getMax()).isWithin(TOLERANCE).of(20.0); + return null; + } + }, + new Function() { + @Override + public Void apply(MutableMean arg) { + assertThat(arg.getMean()).isWithin(TOLERANCE).of(4.0); + return null; + } + }, + new Function() { + @Override + public Void apply(MutableStdDev arg) { + assertThat(arg.getStdDev()).isWithin(TOLERANCE).of(Math.sqrt(372 / 5.0)); + return null; + } + }); + } + } + + @Test + public void testMatch() { + List aggregations = Arrays.asList( + MutableSum.create(), + MutableCount.create(), + MutableHistogram.create( + BucketBoundaries.create(Arrays.asList(-10.0, 1.0, 5.0))), + MutableRange.create(), + MutableMean.create(), + MutableStdDev.create()); + + List actual = new ArrayList(); + for (MutableAggregation aggregation : aggregations) { + actual.add(aggregation.match( + new Function() { + @Override + public String apply(MutableSum arg) { + return "SUM"; + } + }, + new Function() { + @Override + public String apply(MutableCount arg) { + return "COUNT"; + } + }, + new Function() { + @Override + public String apply(MutableHistogram arg) { + return "HISTOGRAM"; + } + }, + new Function() { + @Override + public String apply(MutableRange arg) { + return "RANGE"; + } + }, + new Function() { + @Override + public String apply(MutableMean arg) { + return "MEAN"; + } + }, + new Function() { + @Override + public String apply(MutableStdDev arg) { + return "STDDEV"; + } + })); + } + + assertThat(actual) + .isEqualTo(Arrays.asList("SUM", "COUNT", "HISTOGRAM", "RANGE", "MEAN", "STDDEV")); + } +} From ef8947407b832095eb65358a13b4ae02d3e4ec77 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 20 Jul 2017 14:10:09 -0700 Subject: [PATCH 0349/1581] Add TagContextFactory and TagContextBuilder, and make TagContext abstract. This commit splits TagContext into an abstract class in the API library and an implementation (TagContextImpl) in the implementation library. TagContextFactory has methods for creating TagContexts and working with the current TagContext. (TagContextFactory should probably be renamed, because it has more functionality than a factory.) Advantages of making TagContext abstract and moving its implementation to the core implementation library: - The 'stats' and 'tags' implementation classes are in the same library. That means that the 'stats' package is free to access TagContextImpl's internal state without any risk of compatibility issues. There are no restrictions on optimizations to TagContextImpl's internal state or the 'tags' package's use of that state. - The 'tags' package can provide a no-op TagContext implementation when no 'tags' implementation library is available. The no-op implementation could reduce the overhead of setting tags and recording stats when the stats aren't needed. - The factory class gives us more flexibility to change TagContext in the future. Changes to the API: - TagContexts must be created through builders provided by the TagContextFactory, which is contained in the TagsComponent. Previously, TagContext had a method for creating builders. - TagContextBuilder is a top-level class, instead of a nested class within TagContext. - TagContext implements Iterable. TagContext.iterator() is necessary because the 'stats' and 'tags' packages have some methods that take values of type TagContext. It is possible that the TagContext is not a TagContextImpl, and, in that case, the code can't use implementation-specific methods to get the tags. TagContext must provide a public accessor. --- .../tags/CurrentTagContextUtils.java | 2 + .../src/main/java/io/opencensus/tags/Tag.java | 6 +- .../java/io/opencensus/tags/TagContext.java | 152 ++---------------- .../io/opencensus/tags/TagContextBuilder.java | 122 ++++++++++++++ .../io/opencensus/tags/TagContextFactory.java | 73 ++++++++- .../opencensus/tags/unsafe/ContextUtils.java | 2 +- .../tags/CurrentTagContextUtilsTest.java | 32 ++-- .../io/opencensus/tags/TagContextTest.java | 80 --------- .../impl/tags/TagContextBuilderImpl.java | 68 ++++++++ .../impl/tags/TagContextFactoryImpl.java | 28 ++++ .../opencensus/impl/tags/TagContextImpl.java | 124 ++++++++++++++ .../opencensus/impl/tags/TagContextUtils.java | 81 ++++++++++ .../impl/tags/TagContextFactoryImplTest.java | 107 ++++++++++++ .../impl/tags/TagContextImplTest.java | 98 +++++++++++ .../tags/UnreleasedApiAccessor.java | 43 +++++ 15 files changed, 781 insertions(+), 237 deletions(-) create mode 100644 core/src/main/java/io/opencensus/tags/TagContextBuilder.java delete mode 100644 core/src/test/java/io/opencensus/tags/TagContextTest.java create mode 100644 core_impl/src/main/java/io/opencensus/impl/tags/TagContextBuilderImpl.java create mode 100644 core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java create mode 100644 core_impl/src/main/java/io/opencensus/impl/tags/TagContextUtils.java create mode 100644 core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java create mode 100644 core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java create mode 100644 core_impl/src/test/java/io/opencensus/tags/UnreleasedApiAccessor.java diff --git a/core/src/main/java/io/opencensus/tags/CurrentTagContextUtils.java b/core/src/main/java/io/opencensus/tags/CurrentTagContextUtils.java index 9c2f06d56b..e187b9c288 100644 --- a/core/src/main/java/io/opencensus/tags/CurrentTagContextUtils.java +++ b/core/src/main/java/io/opencensus/tags/CurrentTagContextUtils.java @@ -16,6 +16,7 @@ import io.grpc.Context; import io.opencensus.common.Scope; import io.opencensus.tags.unsafe.ContextUtils; +import javax.annotation.Nullable; /** * Utility methods for accessing the {@link TagContext} contained in the {@link io.grpc.Context}. @@ -29,6 +30,7 @@ private CurrentTagContextUtils() {} * * @return the {@code TagContext} from the current context. */ + @Nullable static TagContext getCurrentTagContext() { return ContextUtils.TAG_CONTEXT_KEY.get(Context.current()); } diff --git a/core/src/main/java/io/opencensus/tags/Tag.java b/core/src/main/java/io/opencensus/tags/Tag.java index c9dd9cfd69..02a8db2ded 100644 --- a/core/src/main/java/io/opencensus/tags/Tag.java +++ b/core/src/main/java/io/opencensus/tags/Tag.java @@ -142,8 +142,7 @@ public abstract static class TagLong extends Tag { * @param value the tag value. * @return a {@code TagLong} with the given key and value. */ - // TODO(sebright): Make this public once we support types other than String. - static TagLong create(TagKeyLong key, long value) { + public static TagLong create(TagKeyLong key, long value) { return new AutoValue_Tag_TagLong(key, value); } @@ -180,8 +179,7 @@ public abstract static class TagBoolean extends Tag { * @param value the tag value. * @return a {@code TagBoolean} with the given key and value. */ - // TODO(sebright): Make this public once we support types other than String. - static TagBoolean create(TagKeyBoolean key, boolean value) { + public static TagBoolean create(TagKeyBoolean key, boolean value) { return new AutoValue_Tag_TagBoolean(key, value); } diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java index dd4fe2083f..03539bb90f 100644 --- a/core/src/main/java/io/opencensus/tags/TagContext.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -13,15 +13,8 @@ package io.opencensus.tags; -import static com.google.common.base.Preconditions.checkNotNull; - -import io.opencensus.common.Scope; -import io.opencensus.tags.TagKey.TagKeyBoolean; -import io.opencensus.tags.TagKey.TagKeyLong; -import io.opencensus.tags.TagKey.TagKeyString; import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.Iterator; import javax.annotation.concurrent.Immutable; /** @@ -32,143 +25,28 @@ * information. */ @Immutable -public final class TagContext { - - /** The empty {@code TagContext}. */ - public static final TagContext EMPTY = emptyBuilder().build(); - - // The types of the TagKey and value must match for each entry. - private final Map tags; - - TagContext(Map tags) { - this.tags = Collections.unmodifiableMap(new HashMap(tags)); - } +public abstract class TagContext implements Iterable { + private static final TagContext NOOP_TAG_CONTEXT = new NoopTagContext(); - Map getTags() { - return tags; - } + @Override + public abstract Iterator iterator(); /** - * Returns the current {@code TagContext}. + * Returns a {@code TagContext} that does not contain any tags. * - * @return the current {@code TagContext}. + * @return a {@code TagContext} that does not contain any tags. */ - public static TagContext getCurrentTags() { - return CurrentTagContextUtils.getCurrentTagContext(); + static TagContext getNoopTagContext() { + return NOOP_TAG_CONTEXT; } - /** - * Returns a new empty {@code Builder}. - * - * @return a new empty {@code Builder}. - */ - public static Builder emptyBuilder() { - return new Builder(); - } - - /** - * Returns a new {@code Builder} created from the current {@code TagContext}. - * - * @return a new {@code Builder} created from the current {@code TagContext}. - */ - public static Builder currentBuilder() { - return getCurrentTags().toBuilder(); - } - - /** - * Returns a builder based on this {@code TagContext}. - * - * @return a builder based on this {@code TagContext}. - */ - public Builder toBuilder() { - return new Builder(getTags()); - } - - /** Builder for the {@link TagContext} class. */ - public static final class Builder { - private final Map tags; - - private Builder(Map tags) { - this.tags = new HashMap(tags); - } - - Builder() { - this.tags = new HashMap(); - } - - /** - * Adds the key/value pair regardless of whether the key is present. - * - * @param key the {@code TagKey} which will be set. - * @param value the value to set for the given key. - * @return this - * @throws IllegalArgumentException if either argument is null. - */ - public Builder set(TagKeyString key, TagValueString value) { - return setInternal(key, checkNotNull(value, "value")); - } - - /** - * Adds the key/value pair regardless of whether the key is present. - * - * @param key the {@code TagKey} which will be set. - * @param value the value to set for the given key. - * @return this - * @throws IllegalArgumentException if the key is null. - */ - // TODO(sebright): Make this public once we support types other than String. - Builder set(TagKeyLong key, long value) { - return setInternal(key, value); - } - - /** - * Adds the key/value pair regardless of whether the key is present. - * - * @param key the {@code TagKey} which will be set. - * @param value the value to set for the given key. - * @return this - * @throws IllegalArgumentException if the key is null. - */ - // TODO(sebright): Make this public once we support types other than String. - Builder set(TagKeyBoolean key, boolean value) { - return setInternal(key, value); - } - - private Builder setInternal(TagKey key, Object value) { - tags.put(checkNotNull(key), value); - return this; - } - - /** - * Removes the key if it exists. - * - * @param key the {@code TagKey} which will be cleared. - * @return this - */ - public Builder clear(TagKey key) { - tags.remove(key); - return this; - } - - /** - * Creates a {@code TagContext} from this builder. - * - * @return a {@code TagContext} with the same tags as this builder. - */ - public TagContext build() { - return new TagContext(tags); - } + @Immutable + private static final class NoopTagContext extends TagContext { - /** - * Enters the scope of code where the {@link TagContext} created from this builder is in the - * current context and returns an object that represents that scope. The scope is exited when - * the returned object is closed. - * - * @return an object that defines a scope where the {@code TagContext} created from this builder - * is set to the current context. - */ - public Scope buildScoped() { - return CurrentTagContextUtils.withTagContext(build()); + // TODO(sebright): Is there any way to let the user know that their tags were ignored? + @Override + public Iterator iterator() { + return Collections.emptySet().iterator(); } } } diff --git a/core/src/main/java/io/opencensus/tags/TagContextBuilder.java b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java new file mode 100644 index 0000000000..26983993e7 --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java @@ -0,0 +1,122 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import io.opencensus.common.Scope; +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; +import io.opencensus.tags.TagKey.TagKeyString; +import javax.annotation.concurrent.Immutable; + +/** Builder for the {@link TagContext} class. */ +public abstract class TagContextBuilder { + private static final TagContextBuilder NOOP_TAG_CONTEXT_BUILDER = new NoopTagContextBuilder(); + + /** + * Adds the key/value pair regardless of whether the key is present. + * + * @param key the {@code TagKey} which will be set. + * @param value the value to set for the given key. + * @return this + * @throws IllegalArgumentException if either argument is null. + */ + public abstract TagContextBuilder set(TagKeyString key, TagValueString value); + + /** + * Adds the key/value pair regardless of whether the key is present. + * + * @param key the {@code TagKey} which will be set. + * @param value the value to set for the given key. + * @return this + * @throws IllegalArgumentException if the key is null. + */ + // TODO(sebright): Make this public once we support types other than String. + protected abstract TagContextBuilder set(TagKeyLong key, long value); + + /** + * Adds the key/value pair regardless of whether the key is present. + * + * @param key the {@code TagKey} which will be set. + * @param value the value to set for the given key. + * @return this + * @throws IllegalArgumentException if the key is null. + */ + // TODO(sebright): Make this public once we support types other than String. + protected abstract TagContextBuilder set(TagKeyBoolean key, boolean value); + + /** + * Removes the key if it exists. + * + * @param key the {@code TagKey} which will be cleared. + * @return this + */ + public abstract TagContextBuilder clear(TagKey key); + + /** + * Creates a {@code TagContext} from this builder. + * + * @return a {@code TagContext} with the same tags as this builder. + */ + public abstract TagContext build(); + + /** + * Enters the scope of code where the {@link TagContextBuilder} created from this builder is in + * the current context and returns an object that represents that scope. The scope is exited when + * the returned object is closed. + * + * @return an object that defines a scope where the {@code TagContext} created from this builder + * is set to the current context. + */ + public final Scope buildScoped() { + return CurrentTagContextUtils.withTagContext(build()); + } + + /** + * Returns a {@code TagContextBuilder} that ignores all calls to {@link #set}. + * + * @return a {@code TagContextBuilder} that ignores all calls to {@link #set}. + */ + static TagContextBuilder getNoopTagContextBuilder() { + return NOOP_TAG_CONTEXT_BUILDER; + } + + @Immutable + private static final class NoopTagContextBuilder extends TagContextBuilder { + + @Override + public TagContextBuilder set(TagKeyString key, TagValueString value) { + return this; + } + + @Override + protected TagContextBuilder set(TagKeyLong key, long value) { + return this; + } + + @Override + protected TagContextBuilder set(TagKeyBoolean key, boolean value) { + return this; + } + + @Override + public TagContextBuilder clear(TagKey key) { + return this; + } + + @Override + public TagContext build() { + return TagContext.getNoopTagContext(); + } + } +} diff --git a/core/src/main/java/io/opencensus/tags/TagContextFactory.java b/core/src/main/java/io/opencensus/tags/TagContextFactory.java index 1103763e9c..7755cc620d 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextFactory.java +++ b/core/src/main/java/io/opencensus/tags/TagContextFactory.java @@ -13,16 +13,72 @@ package io.opencensus.tags; +import io.opencensus.common.Scope; import javax.annotation.concurrent.Immutable; /** * Factory for new {@link TagContext}s and {@code TagContext}s based on the current context. + * + *

This class returns {@link TagContextBuilder builders} that can be used to create the + * implementation-dependent {@link TagContext}s. */ // TODO(sebright): Pick a more descriptive name for this class. public abstract class TagContextFactory { private static final TagContextFactory NOOP_TAG_CONTEXT_FACTORY = new NoopTagContextFactory(); - // TODO(sebright): Add TagContext related methods to this class. + /** + * Returns an empty {@code TagContext}. + * + * @return an empty {@code TagContext}. + */ + public abstract TagContext empty(); + + /** + * Returns the current {@code TagContext}. + * + * @return the current {@code TagContext}. + */ + // TODO(sebright): Should we let the implementation override this method? + public final TagContext getCurrentTagContext() { + TagContext tags = CurrentTagContextUtils.getCurrentTagContext(); + return tags == null ? empty() : tags; + } + + /** + * Returns a new empty {@code Builder}. + * + * @return a new empty {@code Builder}. + */ + public abstract TagContextBuilder emptyBuilder(); + + /** + * Returns a builder based on this {@code TagContext}. + * + * @return a builder based on this {@code TagContext}. + */ + public abstract TagContextBuilder toBuilder(TagContext tags); + + /** + * Returns a new builder created from the current {@code TagContext}. + * + * @return a new builder created from the current {@code TagContext}. + */ + public final TagContextBuilder currentBuilder() { + return toBuilder(getCurrentTagContext()); + } + + /** + * Enters the scope of code where the given {@code TagContext} is in the current context and + * returns an object that represents that scope. The scope is exited when the returned object is + * closed. + * + * @param tags the {@code TagContext} to be set to the current context. + * @return an object that defines a scope where the given {@code TagContext} is set to the current + * context. + */ + public final Scope withTagContext(TagContext tags) { + return CurrentTagContextUtils.withTagContext(tags); + } /** * Returns a {@code TagContextFactory} that only produces {@link TagContext}s with no tags. @@ -35,5 +91,20 @@ static TagContextFactory getNoopTagContextFactory() { @Immutable private static final class NoopTagContextFactory extends TagContextFactory { + + @Override + public TagContext empty() { + return TagContext.getNoopTagContext(); + } + + @Override + public TagContextBuilder emptyBuilder() { + return TagContextBuilder.getNoopTagContextBuilder(); + } + + @Override + public TagContextBuilder toBuilder(TagContext tags) { + return TagContextBuilder.getNoopTagContextBuilder(); + } } } diff --git a/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java b/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java index e8a5e0da73..f34b7c7e72 100644 --- a/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java +++ b/core/src/main/java/io/opencensus/tags/unsafe/ContextUtils.java @@ -30,5 +30,5 @@ private ContextUtils() {} * {@link io.grpc.Context}. */ public static final Context.Key TAG_CONTEXT_KEY = - Context.keyWithDefault("opencensus-tag-context-key", TagContext.EMPTY); + Context.key("opencensus-tag-context-key"); } diff --git a/core/src/test/java/io/opencensus/tags/CurrentTagContextUtilsTest.java b/core/src/test/java/io/opencensus/tags/CurrentTagContextUtilsTest.java index 0a867094e9..c6df81214f 100644 --- a/core/src/test/java/io/opencensus/tags/CurrentTagContextUtilsTest.java +++ b/core/src/test/java/io/opencensus/tags/CurrentTagContextUtilsTest.java @@ -15,9 +15,10 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.common.collect.ImmutableSet; import io.grpc.Context; import io.opencensus.common.Scope; -import io.opencensus.tags.TagKey.TagKeyString; +import java.util.Iterator; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -25,35 +26,38 @@ /** Unit tests for {@link CurrentTagContextUtils}. */ @RunWith(JUnit4.class) public class CurrentTagContextUtilsTest { + private final TagContext tagContext = + new TagContext() { - private static final TagContext TAG_CONTEXT = - TagContext.emptyBuilder() - .set(TagKeyString.create("Key"), TagValueString.create("Value")) - .build(); + @Override + public Iterator iterator() { + return ImmutableSet.of().iterator(); + } + }; @Test public void testGetCurrentTagContext_WhenNoContext() { - assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isNull(); } @Test public void testWithTagContext() { - assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); - Scope scopedTags = CurrentTagContextUtils.withTagContext(TAG_CONTEXT); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isNull(); + Scope scopedTags = CurrentTagContextUtils.withTagContext(tagContext); try { - assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(tagContext); } finally { scopedTags.close(); } - assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isNull(); } @Test public void testWithTagContextUsingWrap() { Runnable runnable; - Scope scopedTags = CurrentTagContextUtils.withTagContext(TAG_CONTEXT); + Scope scopedTags = CurrentTagContextUtils.withTagContext(tagContext); try { - assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TAG_CONTEXT); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(tagContext); runnable = Context.current() .wrap( @@ -61,13 +65,13 @@ public void testWithTagContextUsingWrap() { @Override public void run() { assertThat(CurrentTagContextUtils.getCurrentTagContext()) - .isEqualTo(TAG_CONTEXT); + .isEqualTo(tagContext); } }); } finally { scopedTags.close(); } - assertThat(CurrentTagContextUtils.getCurrentTagContext()).isEqualTo(TagContext.EMPTY); + assertThat(CurrentTagContextUtils.getCurrentTagContext()).isNull(); // When we run the runnable we will have the TagContext in the current Context. runnable.run(); } diff --git a/core/src/test/java/io/opencensus/tags/TagContextTest.java b/core/src/test/java/io/opencensus/tags/TagContextTest.java deleted file mode 100644 index bb19bd65e4..0000000000 --- a/core/src/test/java/io/opencensus/tags/TagContextTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.tags; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.collect.ImmutableMap; -import io.opencensus.tags.TagKey.TagKeyBoolean; -import io.opencensus.tags.TagKey.TagKeyLong; -import io.opencensus.tags.TagKey.TagKeyString; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Tests for {@link TagContext}. */ -// TODO(sebright): Add more tests once the API is finalized. -@RunWith(JUnit4.class) -public class TagContextTest { - - private static final TagKeyString KS1 = TagKeyString.create("k1"); - private static final TagKeyString KS2 = TagKeyString.create("k2"); - - private static final TagValueString V1 = TagValueString.create("v1"); - private static final TagValueString V2 = TagValueString.create("v2"); - - @Test - public void testEmpty() { - assertThat(TagContext.EMPTY.getTags()).isEmpty(); - } - - @Test - public void applyBuilderOperationsInOrder() { - assertThat(TagContext.emptyBuilder().set(KS1, V1).set(KS1, V2).build().getTags()) - .containsExactly(KS1, V2); - } - - @Test - public void allowMutlipleKeysWithSameNameButDifferentTypes() { - TagKeyString stringKey = TagKeyString.create("key"); - TagKeyLong longKey = TagKeyLong.create("key"); - TagKeyBoolean boolKey = TagKeyBoolean.create("key"); - assertThat( - TagContext.emptyBuilder() - .set(stringKey, TagValueString.create("value")) - .set(longKey, 123) - .set(boolKey, true) - .build() - .getTags()) - .containsExactly(stringKey, TagValueString.create("value"), longKey, 123L, boolKey, true); - } - - @Test - public void testSet() { - TagContext tags = singletonTagContext(KS1, V1); - assertThat(tags.toBuilder().set(KS1, V2).build().getTags()).containsExactly(KS1, V2); - assertThat(tags.toBuilder().set(KS2, V2).build().getTags()).containsExactly(KS1, V1, KS2, V2); - } - - @Test - public void testClear() { - TagContext tags = singletonTagContext(KS1, V1); - assertThat(tags.toBuilder().clear(KS1).build().getTags()).isEmpty(); - assertThat(tags.toBuilder().clear(KS2).build().getTags()).containsExactly(KS1, V1); - } - - private static TagContext singletonTagContext(TagKey key, Object value) { - return new TagContext(ImmutableMap.of(key, value)); - } -} diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextBuilderImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextBuilderImpl.java new file mode 100644 index 0000000000..6f87f0ad8d --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextBuilderImpl.java @@ -0,0 +1,68 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.tags; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.opencensus.tags.TagContextBuilder; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; +import java.util.HashMap; +import java.util.Map; + +final class TagContextBuilderImpl extends TagContextBuilder { + private final Map tags; + + TagContextBuilderImpl(Map tags) { + this.tags = new HashMap(tags); + } + + TagContextBuilderImpl() { + this.tags = new HashMap(); + } + + @Override + public TagContextBuilderImpl set(TagKeyString key, TagValueString value) { + return setInternal(key, checkNotNull(value, "value")); + } + + @Override + protected TagContextBuilderImpl set(TagKeyLong key, long value) { + return setInternal(key, value); + } + + @Override + protected TagContextBuilderImpl set(TagKeyBoolean key, boolean value) { + return setInternal(key, value); + } + + private TagContextBuilderImpl setInternal(TagKey key, Object value) { + tags.put(checkNotNull(key), value); + return this; + } + + @Override + public TagContextBuilderImpl clear(TagKey key) { + tags.remove(key); + return this; + } + + @Override + public TagContextImpl build() { + return new TagContextImpl(tags); + } +} diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java index 9ab62a6887..c0465bf3da 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java @@ -13,7 +13,35 @@ package io.opencensus.impl.tags; +import io.opencensus.tags.Tag; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContextBuilder; import io.opencensus.tags.TagContextFactory; final class TagContextFactoryImpl extends TagContextFactory { + TagContextFactoryImpl() {} + + @Override + public TagContextImpl empty() { + return TagContextImpl.EMPTY; + } + + @Override + public TagContextBuilder emptyBuilder() { + return new TagContextBuilderImpl(); + } + + @Override + public TagContextBuilder toBuilder(TagContext tags) { + // Copy the tags more efficiently in the expected case, when the TagContext is a TagContextImpl. + if (tags instanceof TagContextImpl) { + return new TagContextBuilderImpl(((TagContextImpl) tags).getTags()); + } else { + TagContextBuilderImpl builder = new TagContextBuilderImpl(); + for (Tag tag : tags) { + TagContextUtils.addTagToBuilder(tag, builder); + } + return builder; + } + } } diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java new file mode 100644 index 0000000000..0b6dacb433 --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java @@ -0,0 +1,124 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.tags; + +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.tags.Tag; +import io.opencensus.tags.Tag.TagBoolean; +import io.opencensus.tags.Tag.TagLong; +import io.opencensus.tags.Tag.TagString; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import javax.annotation.concurrent.Immutable; + +@Immutable +final class TagContextImpl extends TagContext { + + static final TagContextImpl EMPTY = new TagContextImpl(Collections.emptyMap()); + + // The types of the TagKey and value must match for each entry. + private final Map tags; + + TagContextImpl(Map tags) { + this.tags = Collections.unmodifiableMap(new HashMap(tags)); + } + + Map getTags() { + return tags; + } + + @Override + public Iterator iterator() { + return new TagIterator(tags); + } + + private static final class TagIterator implements Iterator { + Iterator> iterator; + + TagIterator(Map tags) { + iterator = tags.entrySet().iterator(); + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public Tag next() { + final Entry next = iterator.next(); + Object value = next.getValue(); + return next.getKey() + .match( + new NewTagString(value), + new NewTagLong(value), + new NewTagBoolean(value), + Functions.throwAssertionError()); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("TagIterator.remove()"); + } + + private static class NewTagString implements Function { + private final Object value; + + NewTagString(Object value) { + this.value = value; + } + + @Override + public Tag apply(TagKeyString key) { + return TagString.create(key, (TagValueString) value); + } + } + + private static class NewTagLong implements Function { + private final Object value; + + NewTagLong(Object value) { + this.value = value; + } + + @Override + public Tag apply(TagKeyLong key) { + return TagLong.create(key, (Long) value); + } + } + + private static class NewTagBoolean implements Function { + private final Object value; + + NewTagBoolean(Object value) { + this.value = value; + } + + @Override + public Tag apply(TagKeyBoolean key) { + return TagBoolean.create(key, (Boolean) value); + } + } + } +} diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextUtils.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextUtils.java new file mode 100644 index 0000000000..58561fd828 --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextUtils.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.tags; + +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.tags.Tag; +import io.opencensus.tags.Tag.TagBoolean; +import io.opencensus.tags.Tag.TagLong; +import io.opencensus.tags.Tag.TagString; + +final class TagContextUtils { + private TagContextUtils() {} + + /** + * Add a {@code Tag} of any type to a builder. + * + * @param tag tag containing the key and value to set. + * @param builder the builder to update. + */ + static void addTagToBuilder(Tag tag, TagContextBuilderImpl builder) { + tag.match( + new AddTagString(builder), + new AddTagLong(builder), + new AddTagBoolean(builder), + Functions.throwAssertionError()); + } + + private static class AddTagString implements Function { + private final TagContextBuilderImpl builder; + + AddTagString(TagContextBuilderImpl builder) { + this.builder = builder; + } + + @Override + public Void apply(TagString tag) { + builder.set(tag.getKey(), tag.getValue()); + return null; + } + } + + private static class AddTagLong implements Function { + private final TagContextBuilderImpl builder; + + AddTagLong(TagContextBuilderImpl builder) { + this.builder = builder; + } + + @Override + public Void apply(TagLong tag) { + builder.set(tag.getKey(), tag.getValue()); + return null; + } + } + + private static class AddTagBoolean implements Function { + private final TagContextBuilderImpl builder; + + AddTagBoolean(TagContextBuilderImpl builder) { + this.builder = builder; + } + + @Override + public Void apply(TagBoolean tag) { + builder.set(tag.getKey(), tag.getValue()); + return null; + } + } +} diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java new file mode 100644 index 0000000000..1af9be3dc4 --- /dev/null +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java @@ -0,0 +1,107 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import io.opencensus.tags.Tag; +import io.opencensus.tags.Tag.TagBoolean; +import io.opencensus.tags.Tag.TagLong; +import io.opencensus.tags.Tag.TagString; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContextFactory; +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; +import io.opencensus.tags.UnreleasedApiAccessor; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link TagContextFactoryImpl}. */ +@RunWith(JUnit4.class) +public class TagContextFactoryImplTest { + private final TagContextFactory factory = new TagContextFactoryImpl(); + + private static final TagKeyString KS = TagKeyString.create("ks"); + private static final TagKeyLong KL = UnreleasedApiAccessor.createTagKeyLong("kl"); + private static final TagKeyBoolean KB = UnreleasedApiAccessor.createTagKeyBoolean("kb"); + + private static final TagValueString V1 = TagValueString.create("v1"); + private static final TagValueString V2 = TagValueString.create("v2"); + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void empty() { + assertThat(asList(factory.empty())).isEmpty(); + } + + @Test + public void emptyBuilder() { + assertThat(asList(factory.emptyBuilder().build())).isEmpty(); + } + + @Test + public void toBuilder_ConvertUnknownTagContextToTagContextImpl() { + Tag tag1 = TagString.create(KS, V1); + Tag tag2 = TagLong.create(KL, 10L); + Tag tag3 = TagBoolean.create(KB, false); + TagContext unknownTagContext = new SimpleTagContext(tag1, tag2, tag3); + TagContext newTagContext = factory.toBuilder(unknownTagContext).build(); + assertThat(asList(newTagContext)).containsExactly(tag1, tag2, tag3); + assertThat(newTagContext).isInstanceOf(TagContextImpl.class); + } + + @Test + public void toBuilder_RemoveDuplicatesFromUnknownTagContext() { + Tag tag1 = TagString.create(KS, V1); + Tag tag2 = TagString.create(KS, V2); + TagContext unknownTagContext = new SimpleTagContext(tag1, tag2); + TagContext newTagContext = factory.toBuilder(unknownTagContext).build(); + assertThat(asList(newTagContext)).containsExactly(tag2); + } + + @Test + public void toBuilder_HandleNullTag() { + TagContext unknownTagContext = + new SimpleTagContext(TagString.create(KS, V2), null, TagLong.create(KL, 5L)); + thrown.expect(NullPointerException.class); + factory.toBuilder(unknownTagContext).build(); + } + + private static List asList(TagContext tags) { + return Lists.newArrayList(tags.iterator()); + } + + private static final class SimpleTagContext extends TagContext { + private final List tags; + + SimpleTagContext(Tag... tags) { + this.tags = Collections.unmodifiableList(Lists.newArrayList(tags)); + } + + @Override + public Iterator iterator() { + return tags.iterator(); + } + } +} diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java new file mode 100644 index 0000000000..e023907b94 --- /dev/null +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import io.opencensus.tags.Tag; +import io.opencensus.tags.Tag.TagBoolean; +import io.opencensus.tags.Tag.TagLong; +import io.opencensus.tags.Tag.TagString; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContextBuilder; +import io.opencensus.tags.TagContextFactory; +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; +import io.opencensus.tags.UnreleasedApiAccessor; +import java.util.Iterator; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link TagContextImpl} and {@link TagContextBuilderImpl}. */ +// TODO(sebright): Add more tests once the API is finalized. +@RunWith(JUnit4.class) +public class TagContextImplTest { + private final TagContextFactory factory = new TagContextFactoryImpl(); + + private static final TagKeyString KS1 = TagKeyString.create("k1"); + private static final TagKeyString KS2 = TagKeyString.create("k2"); + + private static final TagValueString V1 = TagValueString.create("v1"); + private static final TagValueString V2 = TagValueString.create("v2"); + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void allowMutlipleKeysWithSameNameButDifferentTypes() { + TagKeyString stringKey = TagKeyString.create("key"); + TagKeyLong longKey = UnreleasedApiAccessor.createTagKeyLong("key"); + TagKeyBoolean boolKey = UnreleasedApiAccessor.createTagKeyBoolean("key"); + TagContextBuilder builder = factory.emptyBuilder(); + builder.set(stringKey, TagValueString.create("value")); + UnreleasedApiAccessor.addLongToBuilder(builder, longKey, 123); + UnreleasedApiAccessor.addBooleanToBuilder(builder, boolKey, true); + assertThat(asList(builder.build())) + .containsExactly( + TagString.create(stringKey, TagValueString.create("value")), + TagLong.create(longKey, 123L), + TagBoolean.create(boolKey, true)); + } + + @Test + public void testSet() { + TagContext tags = factory.emptyBuilder().set(KS1, V1).build(); + assertThat(asList(factory.toBuilder(tags).set(KS1, V2).build())) + .containsExactly(TagString.create(KS1, V2)); + assertThat(asList(factory.toBuilder(tags).set(KS2, V2).build())) + .containsExactly(TagString.create(KS1, V1), TagString.create(KS2, V2)); + } + + @Test + public void testClear() { + TagContext tags = factory.emptyBuilder().set(KS1, V1).build(); + assertThat(asList(factory.toBuilder(tags).clear(KS1).build())).isEmpty(); + assertThat(asList(factory.toBuilder(tags).clear(KS2).build())) + .containsExactly(TagString.create(KS1, V1)); + } + + @Test + public void disallowCallingRemoveOnIterator() { + TagContext tags = factory.emptyBuilder().set(KS1, V1).set(KS2, V2).build(); + Iterator i = tags.iterator(); + i.next(); + thrown.expect(UnsupportedOperationException.class); + i.remove(); + } + + private static List asList(TagContext tags) { + return Lists.newArrayList(tags.iterator()); + } +} diff --git a/core_impl/src/test/java/io/opencensus/tags/UnreleasedApiAccessor.java b/core_impl/src/test/java/io/opencensus/tags/UnreleasedApiAccessor.java new file mode 100644 index 0000000000..ace0f689fa --- /dev/null +++ b/core_impl/src/test/java/io/opencensus/tags/UnreleasedApiAccessor.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; + +/** + * Class for accessing methods in the {@code io.opencensus.tags} package that haven't been made + * public yet. + */ +public final class UnreleasedApiAccessor { + private UnreleasedApiAccessor() {} + + public static TagKeyLong createTagKeyLong(String name) { + return TagKeyLong.create(name); + } + + public static TagKeyBoolean createTagKeyBoolean(String name) { + return TagKeyBoolean.create(name); + } + + public static TagContextBuilder addLongToBuilder( + TagContextBuilder builder, TagKeyLong key, long value) { + return builder.set(key, value); + } + + public static TagContextBuilder addBooleanToBuilder( + TagContextBuilder builder, TagKeyBoolean key, boolean value) { + return builder.set(key, value); + } +} From 23845cb05e2a8453b60eb971a9cb59d888a92e92 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Jul 2017 16:09:59 -0700 Subject: [PATCH 0350/1581] Temporarily remove methods for working with the current context. The current context APIs will take more design work. --- .../io/opencensus/tags/TagContextBuilder.java | 13 ------- .../io/opencensus/tags/TagContextFactory.java | 36 +------------------ 2 files changed, 1 insertion(+), 48 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagContextBuilder.java b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java index 26983993e7..137f396fd3 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextBuilder.java +++ b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java @@ -13,7 +13,6 @@ package io.opencensus.tags; -import io.opencensus.common.Scope; import io.opencensus.tags.TagKey.TagKeyBoolean; import io.opencensus.tags.TagKey.TagKeyLong; import io.opencensus.tags.TagKey.TagKeyString; @@ -70,18 +69,6 @@ public abstract class TagContextBuilder { */ public abstract TagContext build(); - /** - * Enters the scope of code where the {@link TagContextBuilder} created from this builder is in - * the current context and returns an object that represents that scope. The scope is exited when - * the returned object is closed. - * - * @return an object that defines a scope where the {@code TagContext} created from this builder - * is set to the current context. - */ - public final Scope buildScoped() { - return CurrentTagContextUtils.withTagContext(build()); - } - /** * Returns a {@code TagContextBuilder} that ignores all calls to {@link #set}. * diff --git a/core/src/main/java/io/opencensus/tags/TagContextFactory.java b/core/src/main/java/io/opencensus/tags/TagContextFactory.java index 7755cc620d..a485867207 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextFactory.java +++ b/core/src/main/java/io/opencensus/tags/TagContextFactory.java @@ -13,11 +13,10 @@ package io.opencensus.tags; -import io.opencensus.common.Scope; import javax.annotation.concurrent.Immutable; /** - * Factory for new {@link TagContext}s and {@code TagContext}s based on the current context. + * Factory for new {@link TagContext}s. * *

This class returns {@link TagContextBuilder builders} that can be used to create the * implementation-dependent {@link TagContext}s. @@ -33,17 +32,6 @@ public abstract class TagContextFactory { */ public abstract TagContext empty(); - /** - * Returns the current {@code TagContext}. - * - * @return the current {@code TagContext}. - */ - // TODO(sebright): Should we let the implementation override this method? - public final TagContext getCurrentTagContext() { - TagContext tags = CurrentTagContextUtils.getCurrentTagContext(); - return tags == null ? empty() : tags; - } - /** * Returns a new empty {@code Builder}. * @@ -58,28 +46,6 @@ public final TagContext getCurrentTagContext() { */ public abstract TagContextBuilder toBuilder(TagContext tags); - /** - * Returns a new builder created from the current {@code TagContext}. - * - * @return a new builder created from the current {@code TagContext}. - */ - public final TagContextBuilder currentBuilder() { - return toBuilder(getCurrentTagContext()); - } - - /** - * Enters the scope of code where the given {@code TagContext} is in the current context and - * returns an object that represents that scope. The scope is exited when the returned object is - * closed. - * - * @param tags the {@code TagContext} to be set to the current context. - * @return an object that defines a scope where the given {@code TagContext} is set to the current - * context. - */ - public final Scope withTagContext(TagContext tags) { - return CurrentTagContextUtils.withTagContext(tags); - } - /** * Returns a {@code TagContextFactory} that only produces {@link TagContext}s with no tags. * From 010dd6463df86172a205c3ec636f9b64a0157faf Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 28 Jul 2017 16:19:23 -0700 Subject: [PATCH 0351/1581] Add TODOs about deciding whether to remove TagContext.iterator(). --- core/src/main/java/io/opencensus/tags/TagContext.java | 2 ++ .../java/io/opencensus/impl/tags/TagContextFactoryImpl.java | 3 +++ 2 files changed, 5 insertions(+) diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java index 03539bb90f..2b45dfd84f 100644 --- a/core/src/main/java/io/opencensus/tags/TagContext.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -24,6 +24,8 @@ *

For example, {@code TagContext}s can be used to label stats, log messages, or debugging * information. */ +// TODO(sebright): Consider removing TagContext.iterator() so that we don't need to support fast +// access to tags. @Immutable public abstract class TagContext implements Iterable { private static final TagContext NOOP_TAG_CONTEXT = new NoopTagContext(); diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java index c0465bf3da..22fd840002 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java @@ -33,6 +33,9 @@ public TagContextBuilder emptyBuilder() { @Override public TagContextBuilder toBuilder(TagContext tags) { + // TODO(sebright): Consider treating an unknown TagContext as empty. That would allow us to + // remove TagContext.iterator(). + // Copy the tags more efficiently in the expected case, when the TagContext is a TagContextImpl. if (tags instanceof TagContextImpl) { return new TagContextBuilderImpl(((TagContextImpl) tags).getTags()); From 7f18eb2c4177807007da3429480d20eeee15c814 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 31 Jul 2017 10:48:03 -0700 Subject: [PATCH 0352/1581] Remove incorrect comment about IllegalArgumentException. --- core/src/main/java/io/opencensus/tags/TagContextBuilder.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagContextBuilder.java b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java index 137f396fd3..8217e94fa7 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextBuilder.java +++ b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java @@ -28,7 +28,6 @@ public abstract class TagContextBuilder { * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this - * @throws IllegalArgumentException if either argument is null. */ public abstract TagContextBuilder set(TagKeyString key, TagValueString value); @@ -38,7 +37,6 @@ public abstract class TagContextBuilder { * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this - * @throws IllegalArgumentException if the key is null. */ // TODO(sebright): Make this public once we support types other than String. protected abstract TagContextBuilder set(TagKeyLong key, long value); @@ -49,7 +47,6 @@ public abstract class TagContextBuilder { * @param key the {@code TagKey} which will be set. * @param value the value to set for the given key. * @return this - * @throws IllegalArgumentException if the key is null. */ // TODO(sebright): Make this public once we support types other than String. protected abstract TagContextBuilder set(TagKeyBoolean key, boolean value); From 49918ecd3b86275f92d49858aaf168ad9d862b0f Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 31 Jul 2017 17:37:48 -0700 Subject: [PATCH 0353/1581] Rename TagContextFactory to TagContexts. --- ...agContextFactory.java => TagContexts.java} | 17 ++++++++-------- .../main/java/io/opencensus/tags/Tags.java | 8 ++++---- .../io/opencensus/tags/TagsComponent.java | 16 +++++++-------- .../java/io/opencensus/tags/TagsTest.java | 4 ++-- ...tFactoryImpl.java => TagContextsImpl.java} | 6 +++--- .../impl/tags/TagsComponentImplBase.java | 8 ++++---- .../impl/tags/TagContextFactoryImplTest.java | 16 +++++++-------- .../impl/tags/TagContextImplTest.java | 20 +++++++++---------- .../io/opencensus/impl/tags/TagsTest.java | 4 ++-- .../io/opencensus/impl/tags/TagsTest.java | 4 ++-- 10 files changed, 50 insertions(+), 53 deletions(-) rename core/src/main/java/io/opencensus/tags/{TagContextFactory.java => TagContexts.java} (73%) rename core_impl/src/main/java/io/opencensus/impl/tags/{TagContextFactoryImpl.java => TagContextsImpl.java} (91%) diff --git a/core/src/main/java/io/opencensus/tags/TagContextFactory.java b/core/src/main/java/io/opencensus/tags/TagContexts.java similarity index 73% rename from core/src/main/java/io/opencensus/tags/TagContextFactory.java rename to core/src/main/java/io/opencensus/tags/TagContexts.java index a485867207..16a9d74397 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextFactory.java +++ b/core/src/main/java/io/opencensus/tags/TagContexts.java @@ -16,14 +16,13 @@ import javax.annotation.concurrent.Immutable; /** - * Factory for new {@link TagContext}s. + * Object for creating new {@link TagContext}s. * *

This class returns {@link TagContextBuilder builders} that can be used to create the * implementation-dependent {@link TagContext}s. */ -// TODO(sebright): Pick a more descriptive name for this class. -public abstract class TagContextFactory { - private static final TagContextFactory NOOP_TAG_CONTEXT_FACTORY = new NoopTagContextFactory(); +public abstract class TagContexts { + private static final TagContexts NOOP_TAG_CONTEXTS = new NoopTagContexts(); /** * Returns an empty {@code TagContext}. @@ -47,16 +46,16 @@ public abstract class TagContextFactory { public abstract TagContextBuilder toBuilder(TagContext tags); /** - * Returns a {@code TagContextFactory} that only produces {@link TagContext}s with no tags. + * Returns a {@code TagContexts} that only produces {@link TagContext}s with no tags. * - * @return a {@code TagContextFactory} that only produces {@code TagContext}s with no tags. + * @return a {@code TagContexts} that only produces {@code TagContext}s with no tags. */ - static TagContextFactory getNoopTagContextFactory() { - return NOOP_TAG_CONTEXT_FACTORY; + static TagContexts getNoopTagContexts() { + return NOOP_TAG_CONTEXTS; } @Immutable - private static final class NoopTagContextFactory extends TagContextFactory { + private static final class NoopTagContexts extends TagContexts { @Override public TagContext empty() { diff --git a/core/src/main/java/io/opencensus/tags/Tags.java b/core/src/main/java/io/opencensus/tags/Tags.java index ba88ca06ae..df1f01885a 100644 --- a/core/src/main/java/io/opencensus/tags/Tags.java +++ b/core/src/main/java/io/opencensus/tags/Tags.java @@ -28,12 +28,12 @@ public final class Tags { private Tags() {} /** - * Returns the default {@code TagContextFactory}. + * Returns the default {@code TagContexts}. * - * @return the default {@code TagContextFactory}. + * @return the default {@code TagContexts}. */ - public static TagContextFactory getTagContextFactory() { - return tagsComponent.getTagContextFactory(); + public static TagContexts getTagContexts() { + return tagsComponent.getTagContexts(); } // Any provider that may be used for TagsComponent can be added here. diff --git a/core/src/main/java/io/opencensus/tags/TagsComponent.java b/core/src/main/java/io/opencensus/tags/TagsComponent.java index a9c9258977..0629f916e9 100644 --- a/core/src/main/java/io/opencensus/tags/TagsComponent.java +++ b/core/src/main/java/io/opencensus/tags/TagsComponent.java @@ -16,22 +16,20 @@ import javax.annotation.concurrent.Immutable; /** - * Class that holds the implementation for {@link TagContextFactory}. + * Class that holds the implementation for {@link TagContexts}. * *

All objects returned by methods on {@code TagsComponent} are cacheable. */ public abstract class TagsComponent { private static final TagsComponent NOOP_TAGS_COMPONENT = new NoopTagsComponent(); - /** Returns the {@link TagContextFactory} for this implementation. */ - public abstract TagContextFactory getTagContextFactory(); + /** Returns the {@link TagContexts} for this implementation. */ + public abstract TagContexts getTagContexts(); /** - * Returns a {@code TagsComponent} that has a no-op implementation for the {@link - * TagContextFactory}. + * Returns a {@code TagsComponent} that has a no-op implementation for the {@link TagContexts}. * - * @return a {@code TagsComponent} that has a no-op implementation for the {@code - * TagContextFactory}. + * @return a {@code TagsComponent} that has a no-op implementation for the {@code TagContexts}. */ static TagsComponent getNoopTagsComponent() { return NOOP_TAGS_COMPONENT; @@ -41,8 +39,8 @@ static TagsComponent getNoopTagsComponent() { private static final class NoopTagsComponent extends TagsComponent { @Override - public TagContextFactory getTagContextFactory() { - return TagContextFactory.getNoopTagContextFactory(); + public TagContexts getTagContexts() { + return TagContexts.getNoopTagContexts(); } } } diff --git a/core/src/test/java/io/opencensus/tags/TagsTest.java b/core/src/test/java/io/opencensus/tags/TagsTest.java index f80f8c5b87..1a66253896 100644 --- a/core/src/test/java/io/opencensus/tags/TagsTest.java +++ b/core/src/test/java/io/opencensus/tags/TagsTest.java @@ -54,7 +54,7 @@ public Class loadClass(String name) throws ClassNotFoundException { } @Test - public void defaultTagContextFactory() { - assertThat(Tags.getTagContextFactory()).isEqualTo(TagContextFactory.getNoopTagContextFactory()); + public void defaultTagContexts() { + assertThat(Tags.getTagContexts()).isEqualTo(TagContexts.getNoopTagContexts()); } } diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextsImpl.java similarity index 91% rename from core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java rename to core_impl/src/main/java/io/opencensus/impl/tags/TagContextsImpl.java index 22fd840002..682b943cd9 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextFactoryImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextsImpl.java @@ -16,10 +16,10 @@ import io.opencensus.tags.Tag; import io.opencensus.tags.TagContext; import io.opencensus.tags.TagContextBuilder; -import io.opencensus.tags.TagContextFactory; +import io.opencensus.tags.TagContexts; -final class TagContextFactoryImpl extends TagContextFactory { - TagContextFactoryImpl() {} +final class TagContextsImpl extends TagContexts { + TagContextsImpl() {} @Override public TagContextImpl empty() { diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java index 9c85858536..9fed97e85b 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java @@ -13,15 +13,15 @@ package io.opencensus.impl.tags; -import io.opencensus.tags.TagContextFactory; +import io.opencensus.tags.TagContexts; import io.opencensus.tags.TagsComponent; /** Base implementation of {@link TagsComponent}. */ public abstract class TagsComponentImplBase extends TagsComponent { - private final TagContextFactory tagContextFactory = new TagContextFactoryImpl(); + private final TagContexts tagContexts = new TagContextsImpl(); @Override - public TagContextFactory getTagContextFactory() { - return tagContextFactory; + public TagContexts getTagContexts() { + return tagContexts; } } diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java index 1af9be3dc4..85c2e7ee95 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java @@ -21,7 +21,7 @@ import io.opencensus.tags.Tag.TagLong; import io.opencensus.tags.Tag.TagString; import io.opencensus.tags.TagContext; -import io.opencensus.tags.TagContextFactory; +import io.opencensus.tags.TagContexts; import io.opencensus.tags.TagKey.TagKeyBoolean; import io.opencensus.tags.TagKey.TagKeyLong; import io.opencensus.tags.TagKey.TagKeyString; @@ -36,10 +36,10 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link TagContextFactoryImpl}. */ +/** Tests for {@link TagContextsImpl}. */ @RunWith(JUnit4.class) public class TagContextFactoryImplTest { - private final TagContextFactory factory = new TagContextFactoryImpl(); + private final TagContexts tagContexts = new TagContextsImpl(); private static final TagKeyString KS = TagKeyString.create("ks"); private static final TagKeyLong KL = UnreleasedApiAccessor.createTagKeyLong("kl"); @@ -52,12 +52,12 @@ public class TagContextFactoryImplTest { @Test public void empty() { - assertThat(asList(factory.empty())).isEmpty(); + assertThat(asList(tagContexts.empty())).isEmpty(); } @Test public void emptyBuilder() { - assertThat(asList(factory.emptyBuilder().build())).isEmpty(); + assertThat(asList(tagContexts.emptyBuilder().build())).isEmpty(); } @Test @@ -66,7 +66,7 @@ public void toBuilder_ConvertUnknownTagContextToTagContextImpl() { Tag tag2 = TagLong.create(KL, 10L); Tag tag3 = TagBoolean.create(KB, false); TagContext unknownTagContext = new SimpleTagContext(tag1, tag2, tag3); - TagContext newTagContext = factory.toBuilder(unknownTagContext).build(); + TagContext newTagContext = tagContexts.toBuilder(unknownTagContext).build(); assertThat(asList(newTagContext)).containsExactly(tag1, tag2, tag3); assertThat(newTagContext).isInstanceOf(TagContextImpl.class); } @@ -76,7 +76,7 @@ public void toBuilder_RemoveDuplicatesFromUnknownTagContext() { Tag tag1 = TagString.create(KS, V1); Tag tag2 = TagString.create(KS, V2); TagContext unknownTagContext = new SimpleTagContext(tag1, tag2); - TagContext newTagContext = factory.toBuilder(unknownTagContext).build(); + TagContext newTagContext = tagContexts.toBuilder(unknownTagContext).build(); assertThat(asList(newTagContext)).containsExactly(tag2); } @@ -85,7 +85,7 @@ public void toBuilder_HandleNullTag() { TagContext unknownTagContext = new SimpleTagContext(TagString.create(KS, V2), null, TagLong.create(KL, 5L)); thrown.expect(NullPointerException.class); - factory.toBuilder(unknownTagContext).build(); + tagContexts.toBuilder(unknownTagContext).build(); } private static List asList(TagContext tags) { diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java index e023907b94..cbc7abd3d8 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java @@ -22,7 +22,7 @@ import io.opencensus.tags.Tag.TagString; import io.opencensus.tags.TagContext; import io.opencensus.tags.TagContextBuilder; -import io.opencensus.tags.TagContextFactory; +import io.opencensus.tags.TagContexts; import io.opencensus.tags.TagKey.TagKeyBoolean; import io.opencensus.tags.TagKey.TagKeyLong; import io.opencensus.tags.TagKey.TagKeyString; @@ -40,7 +40,7 @@ // TODO(sebright): Add more tests once the API is finalized. @RunWith(JUnit4.class) public class TagContextImplTest { - private final TagContextFactory factory = new TagContextFactoryImpl(); + private final TagContexts tagContexts = new TagContextsImpl(); private static final TagKeyString KS1 = TagKeyString.create("k1"); private static final TagKeyString KS2 = TagKeyString.create("k2"); @@ -55,7 +55,7 @@ public void allowMutlipleKeysWithSameNameButDifferentTypes() { TagKeyString stringKey = TagKeyString.create("key"); TagKeyLong longKey = UnreleasedApiAccessor.createTagKeyLong("key"); TagKeyBoolean boolKey = UnreleasedApiAccessor.createTagKeyBoolean("key"); - TagContextBuilder builder = factory.emptyBuilder(); + TagContextBuilder builder = tagContexts.emptyBuilder(); builder.set(stringKey, TagValueString.create("value")); UnreleasedApiAccessor.addLongToBuilder(builder, longKey, 123); UnreleasedApiAccessor.addBooleanToBuilder(builder, boolKey, true); @@ -68,24 +68,24 @@ public void allowMutlipleKeysWithSameNameButDifferentTypes() { @Test public void testSet() { - TagContext tags = factory.emptyBuilder().set(KS1, V1).build(); - assertThat(asList(factory.toBuilder(tags).set(KS1, V2).build())) + TagContext tags = tagContexts.emptyBuilder().set(KS1, V1).build(); + assertThat(asList(tagContexts.toBuilder(tags).set(KS1, V2).build())) .containsExactly(TagString.create(KS1, V2)); - assertThat(asList(factory.toBuilder(tags).set(KS2, V2).build())) + assertThat(asList(tagContexts.toBuilder(tags).set(KS2, V2).build())) .containsExactly(TagString.create(KS1, V1), TagString.create(KS2, V2)); } @Test public void testClear() { - TagContext tags = factory.emptyBuilder().set(KS1, V1).build(); - assertThat(asList(factory.toBuilder(tags).clear(KS1).build())).isEmpty(); - assertThat(asList(factory.toBuilder(tags).clear(KS2).build())) + TagContext tags = tagContexts.emptyBuilder().set(KS1, V1).build(); + assertThat(asList(tagContexts.toBuilder(tags).clear(KS1).build())).isEmpty(); + assertThat(asList(tagContexts.toBuilder(tags).clear(KS2).build())) .containsExactly(TagString.create(KS1, V1)); } @Test public void disallowCallingRemoveOnIterator() { - TagContext tags = factory.emptyBuilder().set(KS1, V1).set(KS2, V2).build(); + TagContext tags = tagContexts.emptyBuilder().set(KS1, V1).set(KS2, V2).build(); Iterator i = tags.iterator(); i.next(); thrown.expect(UnsupportedOperationException.class); diff --git a/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java b/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java index bb6c3fd6b5..6554c91480 100644 --- a/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java +++ b/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java @@ -25,7 +25,7 @@ @RunWith(JUnit4.class) public final class TagsTest { @Test - public void getTagContextFactory() { - assertThat(Tags.getTagContextFactory()).isInstanceOf(TagContextFactoryImpl.class); + public void getTagContexts() { + assertThat(Tags.getTagContexts()).isInstanceOf(TagContextsImpl.class); } } diff --git a/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java b/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java index bb6c3fd6b5..6554c91480 100644 --- a/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java +++ b/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java @@ -25,7 +25,7 @@ @RunWith(JUnit4.class) public final class TagsTest { @Test - public void getTagContextFactory() { - assertThat(Tags.getTagContextFactory()).isInstanceOf(TagContextFactoryImpl.class); + public void getTagContexts() { + assertThat(Tags.getTagContexts()).isInstanceOf(TagContextsImpl.class); } } From 2dd0c87361b4e6786b3c5edc59e52c37b7ecf7dd Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 31 Jul 2017 19:21:16 -0700 Subject: [PATCH 0354/1581] Make all TagContextBuilder.set methods public. This commit exposes the methods for setting values with TagKeyLongs and TagKeyBooleans. They don't need to be hidden, since we are already hiding the TagKeyLong and TagKeyBoolean factory methods. Exposing the 'set' methods makes it easier to show how different types of keys could be used. --- .../java/io/opencensus/tags/TagContextBuilder.java | 10 ++++------ .../opencensus/impl/tags/TagContextBuilderImpl.java | 4 ++-- .../io/opencensus/impl/tags/TagContextImplTest.java | 13 +++++++------ .../io/opencensus/tags/UnreleasedApiAccessor.java | 10 ---------- 4 files changed, 13 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagContextBuilder.java b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java index 8217e94fa7..251651b37d 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextBuilder.java +++ b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java @@ -38,8 +38,7 @@ public abstract class TagContextBuilder { * @param value the value to set for the given key. * @return this */ - // TODO(sebright): Make this public once we support types other than String. - protected abstract TagContextBuilder set(TagKeyLong key, long value); + public abstract TagContextBuilder set(TagKeyLong key, long value); /** * Adds the key/value pair regardless of whether the key is present. @@ -48,8 +47,7 @@ public abstract class TagContextBuilder { * @param value the value to set for the given key. * @return this */ - // TODO(sebright): Make this public once we support types other than String. - protected abstract TagContextBuilder set(TagKeyBoolean key, boolean value); + public abstract TagContextBuilder set(TagKeyBoolean key, boolean value); /** * Removes the key if it exists. @@ -84,12 +82,12 @@ public TagContextBuilder set(TagKeyString key, TagValueString value) { } @Override - protected TagContextBuilder set(TagKeyLong key, long value) { + public TagContextBuilder set(TagKeyLong key, long value) { return this; } @Override - protected TagContextBuilder set(TagKeyBoolean key, boolean value) { + public TagContextBuilder set(TagKeyBoolean key, boolean value) { return this; } diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextBuilderImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextBuilderImpl.java index 6f87f0ad8d..5b0de78e6a 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextBuilderImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextBuilderImpl.java @@ -41,12 +41,12 @@ public TagContextBuilderImpl set(TagKeyString key, TagValueString value) { } @Override - protected TagContextBuilderImpl set(TagKeyLong key, long value) { + public TagContextBuilderImpl set(TagKeyLong key, long value) { return setInternal(key, value); } @Override - protected TagContextBuilderImpl set(TagKeyBoolean key, boolean value) { + public TagContextBuilderImpl set(TagKeyBoolean key, boolean value) { return setInternal(key, value); } diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java index cbc7abd3d8..02f9e31e0e 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java @@ -21,7 +21,6 @@ import io.opencensus.tags.Tag.TagLong; import io.opencensus.tags.Tag.TagString; import io.opencensus.tags.TagContext; -import io.opencensus.tags.TagContextBuilder; import io.opencensus.tags.TagContexts; import io.opencensus.tags.TagKey.TagKeyBoolean; import io.opencensus.tags.TagKey.TagKeyLong; @@ -55,11 +54,13 @@ public void allowMutlipleKeysWithSameNameButDifferentTypes() { TagKeyString stringKey = TagKeyString.create("key"); TagKeyLong longKey = UnreleasedApiAccessor.createTagKeyLong("key"); TagKeyBoolean boolKey = UnreleasedApiAccessor.createTagKeyBoolean("key"); - TagContextBuilder builder = tagContexts.emptyBuilder(); - builder.set(stringKey, TagValueString.create("value")); - UnreleasedApiAccessor.addLongToBuilder(builder, longKey, 123); - UnreleasedApiAccessor.addBooleanToBuilder(builder, boolKey, true); - assertThat(asList(builder.build())) + assertThat( + tagContexts + .emptyBuilder() + .set(stringKey, TagValueString.create("value")) + .set(longKey, 123) + .set(boolKey, true) + .build()) .containsExactly( TagString.create(stringKey, TagValueString.create("value")), TagLong.create(longKey, 123L), diff --git a/core_impl/src/test/java/io/opencensus/tags/UnreleasedApiAccessor.java b/core_impl/src/test/java/io/opencensus/tags/UnreleasedApiAccessor.java index ace0f689fa..ffe929cba5 100644 --- a/core_impl/src/test/java/io/opencensus/tags/UnreleasedApiAccessor.java +++ b/core_impl/src/test/java/io/opencensus/tags/UnreleasedApiAccessor.java @@ -30,14 +30,4 @@ public static TagKeyLong createTagKeyLong(String name) { public static TagKeyBoolean createTagKeyBoolean(String name) { return TagKeyBoolean.create(name); } - - public static TagContextBuilder addLongToBuilder( - TagContextBuilder builder, TagKeyLong key, long value) { - return builder.set(key, value); - } - - public static TagContextBuilder addBooleanToBuilder( - TagContextBuilder builder, TagKeyBoolean key, boolean value) { - return builder.set(key, value); - } } From 9a32d03d0507db51c1b87f8931002c11c57eba1f Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 31 Jul 2017 18:28:09 -0700 Subject: [PATCH 0355/1581] Explain why TagKeyLong and TagKeyBoolean factory methods aren't exposed. --- .../main/java/io/opencensus/tags/TagContext.java | 3 +++ core/src/main/java/io/opencensus/tags/TagKey.java | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java index 2b45dfd84f..834ac502e7 100644 --- a/core/src/main/java/io/opencensus/tags/TagContext.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -23,6 +23,9 @@ * *

For example, {@code TagContext}s can be used to label stats, log messages, or debugging * information. + * + *

Keys have type {@link TagKey}. Values have type {@link TagValueString}, though the library + * will support more types in the future, including {@code long} and {@code boolean}. */ // TODO(sebright): Consider removing TagContext.iterator() so that we don't need to support fast // access to tags. diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index c8d2256732..bd76a70882 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -143,7 +143,12 @@ public final T match( } } - /** A {@code TagKey} for values of type {@code long}. */ + /** + * A {@code TagKey} for values of type {@code long}. + * + *

Note that {@link TagKeyLong} isn't supported by the implementation yet, so the factory + * method isn't exposed. + */ @Immutable @AutoValue public abstract static class TagKeyLong extends TagKey { @@ -178,7 +183,12 @@ public final T match( } } - /** A {@code TagKey} for values of type {@code boolean}. */ + /** + * A {@code TagKey} for values of type {@code boolean}. + * + *

Note that {@link TagKeyBoolean} isn't supported by the implementation yet, so the factory + * method isn't exposed. + */ @Immutable @AutoValue public abstract static class TagKeyBoolean extends TagKey { From c60fda7882ae89415a01806cf2f0b2089696fd0d Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 31 Jul 2017 19:41:07 -0700 Subject: [PATCH 0356/1581] Explain the TagKey class. --- core/src/main/java/io/opencensus/tags/TagKey.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index bd76a70882..94359a03a9 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -29,6 +29,10 @@ * *

Each {@code TagKey} has a {@code String} name. Names have a maximum length of {@link * #MAX_LENGTH} and contain only printable ASCII characters. + * + *

{@code TagKey}s are designed to be used as constants. Declaring each key as a constant ensures + * that the keys have consistent value types and prevents key names from being validated multiple + * times. */ @Immutable public abstract class TagKey { From fc609b3a161b2c97ff8f8238c921ba5bf950ddea Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 1 Aug 2017 16:01:04 +0200 Subject: [PATCH 0357/1581] Fix an equality check. --- contrib/agent/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 1cf4f5d032..1af1150bfe 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -128,7 +128,7 @@ shadowJar { // Assert that there's nothing obviously wrong with the JAR's contents. new java.util.zip.ZipFile(shadowJar.archivePath).withCloseable { // Must have bundled the bootstrap.jar. - assert it.entries().any { it.name = agentBootstrapJar } + assert it.entries().any { it.name == agentBootstrapJar } it.entries().each { // Must not contain anything outside of ${agentPackage}, except for the manifest. From 7e4063a42db039e197785c04dc548e0d4ef4038a Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 1 Aug 2017 16:26:19 +0200 Subject: [PATCH 0358/1581] Slightly refactor the index check of the agent JAR in anticipation of future additions to the list of expected entries. --- contrib/agent/build.gradle | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 1cf4f5d032..c5685cd0e3 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -130,14 +130,15 @@ shadowJar { // Must have bundled the bootstrap.jar. assert it.entries().any { it.name = agentBootstrapJar } - it.entries().each { - // Must not contain anything outside of ${agentPackage}, except for the manifest. - assert it.name.startsWith(agentPackageDir) || - (it.isDirectory() && agentPackageDir.startsWith(it.name)) || - it.name == 'META-INF/' || - it.name == 'META-INF/MANIFEST.MF' + it.entries().each { entry -> + // Must not contain anything outside of ${agentPackage}, ... + assert entry.name.startsWith(agentPackageDir) || + // ... except for the expected entries. + [ agentPackageDir, + 'META-INF/MANIFEST.MF', + ].any { entry.isDirectory() ? it.startsWith(entry.name) : it == entry.name } // Also, should not have the bootstrap classes. - assert !it.name.startsWith(agentBootstrapPackageDir) + assert !entry.name.startsWith(agentBootstrapPackageDir) } } } From d698ecce642fa42a0bfa40ea1daea1a41c661f26 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 7 Aug 2017 23:04:02 +0200 Subject: [PATCH 0359/1581] Make inner class final. --- .../contrib/agent/ExecutorInstrumentationBenchmark.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java index 980797060d..ee6b714581 100644 --- a/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java +++ b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java @@ -26,7 +26,7 @@ /** Benchmarks for automatic context propagation added by {@link ExecutorInstrumentation}. */ public class ExecutorInstrumentationBenchmark { - private static class MyRunnable implements Runnable { + private static final class MyRunnable implements Runnable { private final Blackhole blackhole; From 6bbd674f5a185693549386af975fc473a1773367 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Tue, 8 Aug 2017 11:21:09 -0700 Subject: [PATCH 0360/1581] Modify stats-impl to use the new APIs and data models (#463) * Modify the implementaion based on new APIs. * change anonymous inner Functions to named static ones. * Remove redudant constructors. --- .../io/opencensus/stats/MeasureToViewMap.java | 8 +- .../io/opencensus/stats/MutableViewData.java | 423 +++++++++++------- 2 files changed, 273 insertions(+), 158 deletions(-) diff --git a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java index e06bbdf847..fe4fc38c9d 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java +++ b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java @@ -80,13 +80,7 @@ synchronized void registerView(View view, Clock clock) { } } registeredViews.put(view.getName(), view); - // TODO(songya): update to use refactored implementation. - // MutableViewData mutableViewData = - // view.match( - // new CreateMutableDistributionViewDataFunction(clock), - // new CreateMutableIntervalViewDataFunction()); - // mutableMap.put( - // view.getMeasure().getName(), mutableViewData); + mutableMap.put(view.getMeasure().getName(), MutableViewData.create(view, clock.now())); } // Records stats with a set of tags. diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java index 7d4214dab3..a04ef93291 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java +++ b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java @@ -14,180 +14,301 @@ package io.opencensus.stats; import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import io.opencensus.common.Clock; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.common.Timestamp; +import io.opencensus.stats.Aggregation.Count; +import io.opencensus.stats.Aggregation.Histogram; +import io.opencensus.stats.Aggregation.Mean; +import io.opencensus.stats.Aggregation.Range; +import io.opencensus.stats.Aggregation.StdDev; +import io.opencensus.stats.Aggregation.Sum; +import io.opencensus.stats.AggregationData.CountData; +import io.opencensus.stats.AggregationData.HistogramData; +import io.opencensus.stats.AggregationData.MeanData; +import io.opencensus.stats.AggregationData.RangeData; +import io.opencensus.stats.AggregationData.StdDevData; +import io.opencensus.stats.AggregationData.SumData; +import io.opencensus.stats.MutableAggregation.MutableCount; +import io.opencensus.stats.MutableAggregation.MutableHistogram; +import io.opencensus.stats.MutableAggregation.MutableMean; +import io.opencensus.stats.MutableAggregation.MutableRange; +import io.opencensus.stats.MutableAggregation.MutableStdDev; +import io.opencensus.stats.MutableAggregation.MutableSum; +import io.opencensus.stats.View.Window.Cumulative; +import io.opencensus.stats.View.Window.Interval; +import io.opencensus.stats.ViewData.WindowData.CumulativeData; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import javax.annotation.Nullable; /** * A mutable version of {@link ViewData}, used for recording stats and start/end time. */ -// TODO(songya): update to use refactored implementation. -abstract class MutableViewData { +final class MutableViewData { // TODO(songya): might want to update the default tag value later. @VisibleForTesting static final TagValue UNKNOWN_TAG_VALUE = TagValue.create("unknown/not set"); + private final View view; + private final Map, List> tagValueAggregationMap = + Maps.newHashMap(); + @Nullable private final Timestamp start; + + private MutableViewData(View view, @Nullable Timestamp start) { + this.view = view; + this.start = start; + } + + /** + * Constructs a new {@link MutableViewData}. + * + * @param view the {@code View} linked with this {@code MutableViewData}. + * @param start the start {@code Timestamp}. Not needed for {@code Interval} based {@code View}s. + * @return a {@code MutableViewData}. + */ + static MutableViewData create(final View view, @Nullable final Timestamp start) { + return view.getWindow().match( + new Function() { + @Override + public MutableViewData apply(Cumulative arg) { + return new MutableViewData(view, start); + } + }, + new Function() { + @Override + public MutableViewData apply(Interval arg) { + // TODO(songya): support IntervalView. + throw new UnsupportedOperationException("Interval views not supported yet."); + } + }, + Functions.throwIllegalArgumentException()); + } + /** * The {@link View} associated with this {@link ViewData}. */ - abstract View getView(); + View getView() { + return view; + } /** * Record double stats with the given tags. */ - abstract void record(StatsContextImpl tags, double value); + void record(StatsContextImpl context, double value) { + List tagValues = getTagValues(context.tags, view.getColumns()); + if (!tagValueAggregationMap.containsKey(tagValues)) { + List aggregations = Lists.newArrayList(); + for (Aggregation aggregation : view.getAggregations()) { + aggregations.add(createMutableAggregation(aggregation)); + } + tagValueAggregationMap.put(tagValues, aggregations); + } + for (MutableAggregation aggregation : tagValueAggregationMap.get(tagValues)) { + aggregation.add(value); + } + } /** * Record long stats with the given tags. */ - abstract void record(StatsContextImpl tags, long value); + void record(StatsContextImpl tags, long value) { + // TODO(songya): modify MutableDistribution to support long values. + throw new UnsupportedOperationException("Not implemented."); + } /** * Convert this {@link MutableViewData} to {@link ViewData}. */ - abstract ViewData toViewData(Clock clock); - - private MutableViewData() { - } - -// /** -// * A {@link MutableViewData} for recording stats on distribution-based aggregations. -// */ -// static final class MutableDistributionViewData extends MutableViewData { -// -// /** -// * Constructs a new {@link MutableDistributionViewData}. -// */ -// static MutableDistributionViewData create( -// DistributionView distributionView, Timestamp start) { -// return new MutableDistributionViewData(distributionView, start); -// } -// -// @Override -// View getView() { -// return distributionView; -// } -// -// @Override -// void record(StatsContextImpl context, double value) { -// Map tags = context.tags; -// // TagKeys need to be unique within one view descriptor. -// final List tagKeys = this.distributionView.getColumns(); -// final List tagValues = new ArrayList(tagKeys.size()); -// -// // Record all the measures in a "Greedy" way. -// // Every view aggregates every measure. This is similar to doing a GROUPBY view’s keys. -// for (int i = 0; i < tagKeys.size(); ++i) { -// TagKey tagKey = tagKeys.get(i); -// if (!tags.containsKey(tagKey)) { -// // replace not found key values by “unknown/not set”. -// tagValues.add(UNKNOWN_TAG_VALUE); -// } else { -// tagValues.add(tags.get(tagKey)); -// } -// } -// -// if (!tagValueDistributionMap.containsKey(tagValues)) { -// final List bucketBoundaries = -// this.distributionView.getDistributionAggregation() -// .getBucketBoundaries(); -// final MutableDistribution distribution = -// bucketBoundaries == null ? MutableDistribution.create() -// : MutableDistribution.create(BucketBoundaries.create(bucketBoundaries)); -// tagValueDistributionMap.put(tagValues, distribution); -// } -// tagValueDistributionMap.get(tagValues).add(value); -// } -// -// @Override -// void record(StatsContextImpl tags, long value) { -// // TODO(songya): modify MutableDistribution to support long values. -// throw new UnsupportedOperationException("Not implemented."); -// } -// -// @Override -// final ViewData toViewData(Clock clock) { -// final List distributionAggregations = -// new ArrayList(); -// for (Entry, MutableDistribution> entry : tagValueDistributionMap.entrySet()){ -// MutableDistribution distribution = entry.getValue(); -// DistributionAggregate distributionAggregation = distribution.getBucketCounts() == null -// ? DistributionAggregate.create(distribution.getCount(), distribution.getMean(), -// distribution.getSum(), convertRange(distribution.getRange()), -// generateTags(entry.getKey())) -// : DistributionAggregate.create(distribution.getCount(), distribution.getMean(), -// distribution.getSum(), convertRange(distribution.getRange()), -// generateTags(entry.getKey()), distribution.getBucketCounts()); -// distributionAggregations.add(distributionAggregation); -// } -// return DistributionViewData.create(distributionView, distributionAggregations, start, -// clock.now()); -// } -// -// /** -// * Returns start timestamp for this aggregation. -// */ -// Timestamp getStart() { -// return start; -// } -// -// private final DistributionView distributionView; -// private final Map, MutableDistribution> tagValueDistributionMap = -// new HashMap, MutableDistribution>(); -// private final Timestamp start; -// -// private MutableDistributionViewData( -// DistributionView distributionView, Timestamp start) { -// this.distributionView = distributionView; -// this.start = start; -// } -// -// private final List generateTags(List tagValues) { -// final List tags = new ArrayList(tagValues.size()); -// int i = 0; -// for (TagKey tagKey : this.distributionView.getColumns()) { -// tags.add(Tag.create(tagKey, tagValues.get(i))); -// ++i; -// } -// return tags; -// } -// -// // TODO(songya): remove DistributionAggregate.Range, then remove this method -// private static final DistributionAggregate.Range convertRange( -// MutableDistribution.Range range) { -// return DistributionAggregate.Range.create(range.getMin(), range.getMax()); -// } -// } -// -// /** -// * A {@link MutableViewData} for recording stats on interval-based aggregations. -// */ -// static final class MutableIntervalViewData extends MutableViewData { -// -// /** -// * Constructs a new {@link MutableIntervalViewData}. -// */ -// static MutableIntervalViewData create(IntervalView view) { -// throw new UnsupportedOperationException("Not implemented."); -// } -// -// @Override -// View getView() { -// throw new UnsupportedOperationException("Not implemented."); -// } -// -// @Override -// void record(StatsContextImpl tags, double value) { -// throw new UnsupportedOperationException("Not implemented."); -// } -// -// @Override -// void record(StatsContextImpl tags, long value) { -// throw new UnsupportedOperationException("Not implemented."); -// } -// -// @Override -// final ViewData toViewData(Clock clock) { -// throw new UnsupportedOperationException("Not implemented."); -// } -// } + ViewData toViewData(Clock clock) { + Map, List> map = Maps.newHashMap(); + for (Entry, List> entry : + tagValueAggregationMap.entrySet()) { + List aggregates = Lists.newArrayList(); + for (MutableAggregation aggregation : entry.getValue()) { + aggregates.add(createAggregationData(aggregation)); + } + map.put(entry.getKey(), aggregates); + } + return ViewData.create(view, map, CumulativeData.create(start, clock.now())); + } + + /** + * Returns start timestamp for this aggregation. + */ + @Nullable + Timestamp getStart() { + return start; + } + + @VisibleForTesting + static List getTagValues(Map tags, List columns) { + List tagValues = new ArrayList(columns.size()); + // Record all the measures in a "Greedy" way. + // Every view aggregates every measure. This is similar to doing a GROUPBY view’s keys. + for (int i = 0; i < columns.size(); ++i) { + TagKey tagKey = columns.get(i); + if (!tags.containsKey(tagKey)) { + // replace not found key values by “unknown/not set”. + tagValues.add(UNKNOWN_TAG_VALUE); + } else { + tagValues.add(tags.get(tagKey)); + } + } + return tagValues; + } + + /** + * Create an empty {@link MutableAggregation} based on the given {@link Aggregation}. + * + * @param aggregation {@code Aggregation}. + * @return an empty {@code MutableAggregation}. + */ + @VisibleForTesting + static MutableAggregation createMutableAggregation(Aggregation aggregation) { + return aggregation.match( + CreateMutableSum.INSTANCE, + CreateMutableCount.INSTANCE, + CreateMutableHistogram.INSTANCE, + CreateMutableRange.INSTANCE, + CreateMutableMean.INSTANCE, + CreateMutableStdDev.INSTANCE, + Functions.throwIllegalArgumentException()); + } + + /** + * Create an {@link AggregationData} snapshot based on the given {@link MutableAggregation}. + * + * @param aggregation {@code MutableAggregation} + * @return an {@code AggregationData} which is the snapshot of current summary statistics. + */ + @VisibleForTesting + static AggregationData createAggregationData(MutableAggregation aggregation) { + return aggregation.match( + CreateSumData.INSTANCE, + CreateCountData.INSTANCE, + CreateHistogramData.INSTANCE, + CreateRangeData.INSTANCE, + CreateMeanData.INSTANCE, + CreateStdDevData.INSTANCE); + } + + // static inner Function classes + + private static final class CreateMutableSum implements Function { + @Override + public MutableAggregation apply(Sum arg) { + return MutableSum.create(); + } + + private static final CreateMutableSum INSTANCE = new CreateMutableSum(); + } + + private static final class CreateMutableCount implements Function { + @Override + public MutableAggregation apply(Count arg) { + return MutableCount.create(); + } + + private static final CreateMutableCount INSTANCE = new CreateMutableCount(); + } + + private static final class CreateMutableHistogram + implements Function { + @Override + public MutableAggregation apply(Histogram arg) { + return MutableHistogram.create(arg.getBucketBoundaries()); + } + + private static final CreateMutableHistogram INSTANCE = new CreateMutableHistogram(); + } + + private static final class CreateMutableRange implements Function { + @Override + public MutableAggregation apply(Range arg) { + return MutableRange.create(); + } + + private static final CreateMutableRange INSTANCE = new CreateMutableRange(); + } + + private static final class CreateMutableMean implements Function { + @Override + public MutableAggregation apply(Mean arg) { + return MutableMean.create(); + } + + private static final CreateMutableMean INSTANCE = new CreateMutableMean(); + } + + private static final class CreateMutableStdDev implements Function { + @Override + public MutableAggregation apply(StdDev arg) { + return MutableStdDev.create(); + } + + private static final CreateMutableStdDev INSTANCE = new CreateMutableStdDev(); + } + + + private static final class CreateSumData implements Function { + @Override + public AggregationData apply(MutableSum arg) { + return SumData.create(arg.getSum()); + } + + private static final CreateSumData INSTANCE = new CreateSumData(); + } + + private static final class CreateCountData implements Function { + @Override + public AggregationData apply(MutableCount arg) { + return CountData.create(arg.getCount()); + } + + private static final CreateCountData INSTANCE = new CreateCountData(); + } + + private static final class CreateHistogramData + implements Function { + @Override + public AggregationData apply(MutableHistogram arg) { + return HistogramData.create(arg.getBucketCounts()); + } + + private static final CreateHistogramData INSTANCE = new CreateHistogramData(); + } + + private static final class CreateRangeData implements Function { + @Override + public AggregationData apply(MutableRange arg) { + return RangeData.create(arg.getMin(), arg.getMax()); + } + + private static final CreateRangeData INSTANCE = new CreateRangeData(); + } + + private static final class CreateMeanData implements Function { + @Override + public AggregationData apply(MutableMean arg) { + return MeanData.create(arg.getMean()); + } + + private static final CreateMeanData INSTANCE = new CreateMeanData(); + } + + private static final class CreateStdDevData implements Function { + @Override + public AggregationData apply(MutableStdDev arg) { + return StdDevData.create(arg.getStdDev()); + } + + private static final CreateStdDevData INSTANCE = new CreateStdDevData(); + } } From 4464c0da4364e67ad11990c6ad9ee8382f3eaf5b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 8 Aug 2017 12:25:39 -0700 Subject: [PATCH 0361/1581] Change TagContext.iterator() to TagContext.unsafeGetIterator(). --- .../java/io/opencensus/tags/TagContext.java | 11 +++++------ .../tags/CurrentTagContextUtilsTest.java | 2 +- .../io/opencensus/impl/tags/TagContextImpl.java | 2 +- .../opencensus/impl/tags/TagContextsImpl.java | 7 ++++--- .../impl/tags/TagContextFactoryImplTest.java | 4 ++-- .../impl/tags/TagContextImplTest.java | 17 +++++++++-------- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java index 834ac502e7..a2f3867a81 100644 --- a/core/src/main/java/io/opencensus/tags/TagContext.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -27,14 +27,13 @@ *

Keys have type {@link TagKey}. Values have type {@link TagValueString}, though the library * will support more types in the future, including {@code long} and {@code boolean}. */ -// TODO(sebright): Consider removing TagContext.iterator() so that we don't need to support fast -// access to tags. @Immutable -public abstract class TagContext implements Iterable { +public abstract class TagContext { private static final TagContext NOOP_TAG_CONTEXT = new NoopTagContext(); - @Override - public abstract Iterator iterator(); + // TODO(sebright): Consider removing TagContext.unsafeGetIterator() so that we don't need to + // support fast access to tags. + public abstract Iterator unsafeGetIterator(); /** * Returns a {@code TagContext} that does not contain any tags. @@ -50,7 +49,7 @@ private static final class NoopTagContext extends TagContext { // TODO(sebright): Is there any way to let the user know that their tags were ignored? @Override - public Iterator iterator() { + public Iterator unsafeGetIterator() { return Collections.emptySet().iterator(); } } diff --git a/core/src/test/java/io/opencensus/tags/CurrentTagContextUtilsTest.java b/core/src/test/java/io/opencensus/tags/CurrentTagContextUtilsTest.java index c6df81214f..1c5805d294 100644 --- a/core/src/test/java/io/opencensus/tags/CurrentTagContextUtilsTest.java +++ b/core/src/test/java/io/opencensus/tags/CurrentTagContextUtilsTest.java @@ -30,7 +30,7 @@ public class CurrentTagContextUtilsTest { new TagContext() { @Override - public Iterator iterator() { + public Iterator unsafeGetIterator() { return ImmutableSet.of().iterator(); } }; diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java index 0b6dacb433..a9fca43bd6 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java @@ -49,7 +49,7 @@ Map getTags() { } @Override - public Iterator iterator() { + public Iterator unsafeGetIterator() { return new TagIterator(tags); } diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextsImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextsImpl.java index 682b943cd9..c75eb954f5 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextsImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextsImpl.java @@ -17,6 +17,7 @@ import io.opencensus.tags.TagContext; import io.opencensus.tags.TagContextBuilder; import io.opencensus.tags.TagContexts; +import java.util.Iterator; final class TagContextsImpl extends TagContexts { TagContextsImpl() {} @@ -34,15 +35,15 @@ public TagContextBuilder emptyBuilder() { @Override public TagContextBuilder toBuilder(TagContext tags) { // TODO(sebright): Consider treating an unknown TagContext as empty. That would allow us to - // remove TagContext.iterator(). + // remove TagContext.unsafeGetIterator(). // Copy the tags more efficiently in the expected case, when the TagContext is a TagContextImpl. if (tags instanceof TagContextImpl) { return new TagContextBuilderImpl(((TagContextImpl) tags).getTags()); } else { TagContextBuilderImpl builder = new TagContextBuilderImpl(); - for (Tag tag : tags) { - TagContextUtils.addTagToBuilder(tag, builder); + for (Iterator i = tags.unsafeGetIterator(); i.hasNext(); ) { + TagContextUtils.addTagToBuilder(i.next(), builder); } return builder; } diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java index 85c2e7ee95..6347a740b6 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java @@ -89,7 +89,7 @@ public void toBuilder_HandleNullTag() { } private static List asList(TagContext tags) { - return Lists.newArrayList(tags.iterator()); + return Lists.newArrayList(tags.unsafeGetIterator()); } private static final class SimpleTagContext extends TagContext { @@ -100,7 +100,7 @@ private static final class SimpleTagContext extends TagContext { } @Override - public Iterator iterator() { + public Iterator unsafeGetIterator() { return tags.iterator(); } } diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java index 02f9e31e0e..b830287d29 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java @@ -55,12 +55,13 @@ public void allowMutlipleKeysWithSameNameButDifferentTypes() { TagKeyLong longKey = UnreleasedApiAccessor.createTagKeyLong("key"); TagKeyBoolean boolKey = UnreleasedApiAccessor.createTagKeyBoolean("key"); assertThat( - tagContexts - .emptyBuilder() - .set(stringKey, TagValueString.create("value")) - .set(longKey, 123) - .set(boolKey, true) - .build()) + asList( + tagContexts + .emptyBuilder() + .set(stringKey, TagValueString.create("value")) + .set(longKey, 123) + .set(boolKey, true) + .build())) .containsExactly( TagString.create(stringKey, TagValueString.create("value")), TagLong.create(longKey, 123L), @@ -87,13 +88,13 @@ public void testClear() { @Test public void disallowCallingRemoveOnIterator() { TagContext tags = tagContexts.emptyBuilder().set(KS1, V1).set(KS2, V2).build(); - Iterator i = tags.iterator(); + Iterator i = tags.unsafeGetIterator(); i.next(); thrown.expect(UnsupportedOperationException.class); i.remove(); } private static List asList(TagContext tags) { - return Lists.newArrayList(tags.iterator()); + return Lists.newArrayList(tags.unsafeGetIterator()); } } From 214493b270132007c615932294e17fcb30cd832f Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 8 Aug 2017 12:41:41 -0700 Subject: [PATCH 0362/1581] Add default implementation of TagContexts.emptyBuilder(). --- core/src/main/java/io/opencensus/tags/TagContexts.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/io/opencensus/tags/TagContexts.java b/core/src/main/java/io/opencensus/tags/TagContexts.java index 16a9d74397..c72175647c 100644 --- a/core/src/main/java/io/opencensus/tags/TagContexts.java +++ b/core/src/main/java/io/opencensus/tags/TagContexts.java @@ -36,7 +36,9 @@ public abstract class TagContexts { * * @return a new empty {@code Builder}. */ - public abstract TagContextBuilder emptyBuilder(); + public TagContextBuilder emptyBuilder() { + return toBuilder(empty()); + } /** * Returns a builder based on this {@code TagContext}. @@ -62,11 +64,6 @@ public TagContext empty() { return TagContext.getNoopTagContext(); } - @Override - public TagContextBuilder emptyBuilder() { - return TagContextBuilder.getNoopTagContextBuilder(); - } - @Override public TagContextBuilder toBuilder(TagContext tags) { return TagContextBuilder.getNoopTagContextBuilder(); From 643cb045062e24961d093df696d004c1c65fecda Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 8 Aug 2017 12:52:56 -0700 Subject: [PATCH 0363/1581] Add test for TagContext iterator. --- .../opencensus/impl/tags/TagContextImplTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java index b830287d29..912de58757 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java @@ -14,6 +14,8 @@ package io.opencensus.impl.tags; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.common.collect.Lists; import io.opencensus.tags.Tag; @@ -29,6 +31,7 @@ import io.opencensus.tags.UnreleasedApiAccessor; import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -85,6 +88,19 @@ public void testClear() { .containsExactly(TagString.create(KS1, V1)); } + @Test + public void testIterator() { + TagContext tags = tagContexts.emptyBuilder().set(KS1, V1).set(KS2, V2).build(); + Iterator i = tags.unsafeGetIterator(); + assertTrue(i.hasNext()); + assertThat(i.next()).isEqualTo(TagString.create(KS1, V1)); + assertTrue(i.hasNext()); + assertThat(i.next()).isEqualTo(TagString.create(KS2, V2)); + assertFalse(i.hasNext()); + thrown.expect(NoSuchElementException.class); + i.next(); + } + @Test public void disallowCallingRemoveOnIterator() { TagContext tags = tagContexts.emptyBuilder().set(KS1, V1).set(KS2, V2).build(); From eeadd62b723cd4b217e6d4a947838beffcae830b Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 8 Aug 2017 14:07:52 -0700 Subject: [PATCH 0364/1581] Don't test order of tags in TagContext iterator. --- .../java/io/opencensus/impl/tags/TagContextImplTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java index 912de58757..0639e31c95 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextImplTest.java @@ -29,6 +29,7 @@ import io.opencensus.tags.TagKey.TagKeyString; import io.opencensus.tags.TagValueString; import io.opencensus.tags.UnreleasedApiAccessor; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; @@ -93,10 +94,12 @@ public void testIterator() { TagContext tags = tagContexts.emptyBuilder().set(KS1, V1).set(KS2, V2).build(); Iterator i = tags.unsafeGetIterator(); assertTrue(i.hasNext()); - assertThat(i.next()).isEqualTo(TagString.create(KS1, V1)); + Tag tag1 = i.next(); assertTrue(i.hasNext()); - assertThat(i.next()).isEqualTo(TagString.create(KS2, V2)); + Tag tag2 = i.next(); assertFalse(i.hasNext()); + assertThat(Arrays.asList(tag1, tag2)) + .containsExactly(TagString.create(KS1, V1), TagString.create(KS2, V2)); thrown.expect(NoSuchElementException.class); i.next(); } From 5ded7f45971eef541bb3d8c6d3bfd7a718bf3809 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Wed, 9 Aug 2017 13:33:14 -0700 Subject: [PATCH 0365/1581] Update tests on implementations. (#489) --- .../stats/MeasureToViewMapTest.java | 66 +++--- .../opencensus/stats/MutableViewDataTest.java | 96 ++++++++- .../io/opencensus/stats/StatsContextTest.java | 123 +++++------ .../io/opencensus/stats/StatsTestUtil.java | 192 +++++++++--------- .../opencensus/stats/ViewManagerImplTest.java | 8 - 5 files changed, 275 insertions(+), 210 deletions(-) diff --git a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java index 12e12f4965..948622f18d 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java @@ -13,14 +13,20 @@ package io.opencensus.stats; -import org.junit.Ignore; +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.common.Timestamp; +import io.opencensus.stats.ViewData.WindowData.CumulativeData; +import io.opencensus.testing.common.TestClock; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** Tests for {@link MeasureToViewMap}. */ -@Ignore @RunWith(JUnit4.class) -// TODO(songya): re-enable the tests once implementation is done. public class MeasureToViewMapTest { private static final Measure MEASURE = @@ -31,38 +37,26 @@ public class MeasureToViewMapTest { private static final View.Name VIEW_NAME = View.Name.create("my view"); -// private static final View VIEW = -// DistributionView.create( -// VIEW_NAME, -// "view description", -// MEASURE, -// DistributionAggregation.create(), -// Arrays.asList(TagKey.create("my key"))); + private static final List AGGREGATIONS_NO_HISTOGRAM = Arrays.asList( + Aggregation.Sum.create(), Aggregation.Count.create(), Aggregation.Range.create(), + Aggregation.Mean.create(), Aggregation.StdDev.create()); + + private static final View.Window.Cumulative CUMULATIVE = View.Window.Cumulative.create(); + + private static final View VIEW = + View.create(VIEW_NAME, "view description", MEASURE, AGGREGATIONS_NO_HISTOGRAM, + Arrays.asList(TagKey.create("my key")), CUMULATIVE); -// @Test -// public void testRegisterAndGetDistributionView() { -// MeasureToViewMap measureToViewMap = new MeasureToViewMap(); -// TestClock clock = TestClock.create(Timestamp.create(10, 20)); -// measureToViewMap.registerView(VIEW, clock); -// clock.setTime(Timestamp.create(30, 40)); -// ViewData actual = measureToViewMap.getView(VIEW_NAME, clock); -// actual.match( -// new Function() { -// @Override -// public Void apply(DistributionViewData view) { -// assertThat(view.getView()).isEqualTo(VIEW); -// assertThat(view.getStart()).isEqualTo(Timestamp.create(10, 20)); -// assertThat(view.getEnd()).isEqualTo(Timestamp.create(30, 40)); -// assertThat(view.getDistributionAggregates()).isEmpty(); -// return null; -// } -// }, -// new Function() { -// @Override -// public Void apply(IntervalViewData view) { -// fail("Wrong view type."); -// return null; -// } -// }); -// } + @Test + public void testRegisterAndGetView() { + MeasureToViewMap measureToViewMap = new MeasureToViewMap(); + TestClock clock = TestClock.create(Timestamp.create(10, 20)); + measureToViewMap.registerView(VIEW, clock); + clock.setTime(Timestamp.create(30, 40)); + ViewData viewData = measureToViewMap.getView(VIEW_NAME, clock); + assertThat(viewData.getView()).isEqualTo(VIEW); + assertThat(viewData.getWindowData()).isEqualTo( + CumulativeData.create(Timestamp.create(10, 20), Timestamp.create(30, 40))); + assertThat(viewData.getAggregationMap()).isEmpty(); + } } diff --git a/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java b/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java index 460cf44ab8..35d86f47cb 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java @@ -15,19 +15,109 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.common.collect.ImmutableMap; +import io.opencensus.stats.Aggregation.Count; +import io.opencensus.stats.Aggregation.Histogram; +import io.opencensus.stats.Aggregation.Mean; +import io.opencensus.stats.Aggregation.Range; +import io.opencensus.stats.Aggregation.StdDev; +import io.opencensus.stats.Aggregation.Sum; +import io.opencensus.stats.AggregationData.CountData; +import io.opencensus.stats.AggregationData.HistogramData; +import io.opencensus.stats.AggregationData.MeanData; +import io.opencensus.stats.AggregationData.RangeData; +import io.opencensus.stats.AggregationData.StdDevData; +import io.opencensus.stats.AggregationData.SumData; +import io.opencensus.stats.MutableAggregation.MutableCount; +import io.opencensus.stats.MutableAggregation.MutableHistogram; +import io.opencensus.stats.MutableAggregation.MutableMean; +import io.opencensus.stats.MutableAggregation.MutableRange; +import io.opencensus.stats.MutableAggregation.MutableStdDev; +import io.opencensus.stats.MutableAggregation.MutableSum; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link MutableViewData}. - */ +/** Tests for {@link MutableViewData}. */ @RunWith(JUnit4.class) public class MutableViewDataTest { + private static final double EPSILON = 1e-7; + + private static final TagKey ORIGINATOR = TagKey.create("originator"); + private static final TagKey CALLER = TagKey.create("caller"); + private static final TagKey METHOD = TagKey.create("method"); + private static final TagValue CALLER_V = TagValue.create("some caller"); + private static final TagValue METHOD_V = TagValue.create("some method"); + @Test public void testConstants() { assertThat(MutableViewData.UNKNOWN_TAG_VALUE.asString()).isEqualTo("unknown/not set"); } + @Test + public void testGetTagValues() { + List columns = Arrays.asList(CALLER, METHOD, ORIGINATOR); + Map tags = ImmutableMap.of(CALLER, CALLER_V, METHOD, METHOD_V); + + assertThat(MutableViewData.getTagValues(tags, columns)) + .containsExactly(CALLER_V, METHOD_V, MutableViewData.UNKNOWN_TAG_VALUE) + .inOrder(); + } + + @Test + public void createMutableAggregation() { + BucketBoundaries bucketBoundaries = BucketBoundaries.create(Arrays.asList(-1.0, 0.0, 1.0)); + + assertThat( + ((MutableSum) MutableViewData.createMutableAggregation(Sum.create())).getSum()) + .isWithin(EPSILON).of(0.0); + assertThat( + ((MutableCount) MutableViewData.createMutableAggregation(Count.create())).getCount()) + .isEqualTo(0L); + assertThat( + ((MutableHistogram) MutableViewData.createMutableAggregation( + Histogram.create(bucketBoundaries))).getBucketCounts()) + .isEqualTo(new long[]{0, 0, 0, 0}); + assertThat( + ((MutableRange) MutableViewData.createMutableAggregation(Range.create())).getMin()) + .isPositiveInfinity(); + assertThat( + ((MutableRange) MutableViewData.createMutableAggregation(Range.create())).getMax()) + .isNegativeInfinity(); + assertThat( + ((MutableMean) MutableViewData.createMutableAggregation(Mean.create())).getMean()) + .isWithin(EPSILON).of(0D); + assertThat( + ((MutableStdDev) MutableViewData.createMutableAggregation(StdDev.create())).getStdDev()) + .isWithin(EPSILON).of(0D); + } + + @Test + public void createAggregationData() { + BucketBoundaries bucketBoundaries = BucketBoundaries.create(Arrays.asList(-1.0, 0.0, 1.0)); + List mutableAggregations = Arrays.asList( + MutableSum.create(), + MutableCount.create(), + MutableHistogram.create(bucketBoundaries), + MutableRange.create(), + MutableMean.create(), + MutableStdDev.create()); + List aggregates = new ArrayList(); + for (MutableAggregation mutableAggregation : mutableAggregations) { + aggregates.add(MutableViewData.createAggregationData(mutableAggregation)); + } + assertThat(aggregates).containsExactly( + SumData.create(0), + CountData.create(0), + HistogramData.create(0, 0, 0, 0), + RangeData.create(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY), + MeanData.create(0), + StdDevData.create(0)) + .inOrder(); + } } diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index 9256781f8e..a972071ccf 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -19,6 +19,7 @@ import com.google.common.testing.EqualsTester; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.internal.VarInt; +import io.opencensus.stats.Measure.MeasureLong; import io.opencensus.testing.common.TestClock; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -27,6 +28,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Map.Entry; import java.util.Set; import org.junit.Rule; import org.junit.Test; @@ -34,9 +36,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link StatsContext}. - */ +/** Tests for {@link StatsContext}. */ @RunWith(JUnit4.class) public class StatsContextTest { @@ -76,6 +76,12 @@ public class StatsContextTest { private static final Tag T3 = Tag.create(K3, V3); private static final Tag T4 = Tag.create(K4, V4); + private static final List AGGREGATIONS_NO_HISTOGRAM = Arrays.asList( + Aggregation.Sum.create(), Aggregation.Count.create(), Aggregation.Range.create(), + Aggregation.Mean.create(), Aggregation.StdDev.create()); + + private static final View.Window.Cumulative CUMULATIVE = View.Window.Cumulative.create(); + @Test public void testWith() { assertThat(defaultStatsContext.builder().set(K1, V1).build()) @@ -111,75 +117,48 @@ public void testWithComposed() { .isEqualTo(context4); } - // TODO(songya): re-enable the tests once implementation is done. -// // The main tests for stats recording are in ViewManagerImplTest. -// @Test -// public void testRecordDouble() { -// viewManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); -// ViewData beforeViewData = -// viewManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); -// beforeViewData.match( -// new Function() { -// @Override -// public Void apply(DistributionViewData view) { -// assertThat(view.getDistributionAggregates()).isEmpty(); -// return null; -// } -// }, -// new Function() { -// @Override -// public Void apply(IntervalViewData view) { -// fail("Expected a DistributionViewData"); -// return null; -// } -// }); -// StatsContext context = -// defaultStatsContext.with( -// RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); -// MeasureMap measurements = -// MeasureMap.builder() -// .set(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); -// context.record(measurements); -// ViewData afterViewData = -// viewManager.getView( -// RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); -// afterViewData.match( -// new Function() { -// @Override -// public Void apply(DistributionViewData view) { -// assertThat(view.getDistributionAggregates()).hasSize(1); -// DistributionAggregate agg = view.getDistributionAggregates().get(0); -// assertThat(agg.getTags()) -// .containsExactly( -// Tag.create( -// RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod"))); -// assertThat(agg.getCount()).isEqualTo(1); -// assertThat(agg.getMean()).isWithin(TOLERANCE).of(5.1); -// return null; -// } -// }, -// new Function() { -// @Override -// public Void apply(IntervalViewData view) { -// fail("Expected a DistributionViewData"); -// return null; -// } -// }); -// } -// -// @Test -// public void testRecordLong() { -// MeasureLong measure = MeasureLong.create("long measure", "description", "1"); -// viewManager.registerView( -// View.DistributionView.create( -// View.Name.create("name"), -// "description", -// measure, -// DistributionAggregation.create(), -// Arrays.asList(K1))); -// thrown.expect(UnsupportedOperationException.class); -// defaultStatsContext.with(K1, V1).record(MeasureMap.builder().set(measure,1L).build()); -// } + // The main tests for stats recording are in ViewManagerImplTest. + @Test + public void testRecordDouble() { + viewManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + ViewData beforeViewData = + viewManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + assertThat(beforeViewData.getAggregationMap()).isEmpty(); + StatsContext context = + defaultStatsContext.with( + RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); + MeasureMap measurements = + MeasureMap.builder() + .set(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); + context.record(measurements); + ViewData afterViewData = + viewManager.getView( + RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + assertThat(afterViewData.getAggregationMap()).hasSize(1); + for (Entry, List> entry : + afterViewData.getAggregationMap().entrySet()) { + assertThat(entry.getKey()).containsExactly(TagValue.create("myMethod")); + assertThat(entry.getValue()).hasSize(3); + // TODO(songya): update this using assertAggregationDataListEquals() + for (AggregationData aggregate : entry.getValue()) { + StatsTestUtil.assertAggregationDataEquals(aggregate, 5.1, 1L, + StatsTestUtil.removeTrailingZeros(0, 0, 0, 0, 0, 0, 1), null, null, null, null, + TOLERANCE); + } + } + } + + @Test + public void testRecordLong() { + MeasureLong measure = MeasureLong.create("long measure", "description", "1"); + viewManager.registerView(View.create( + View.Name.create("name"), "description", measure, AGGREGATIONS_NO_HISTOGRAM, + Arrays.asList(K1), CUMULATIVE)); + MeasureMap measureMap = MeasureMap.builder().set(measure, 1L).build(); + StatsContext context = defaultStatsContext.with(K1, V1); + thrown.expect(UnsupportedOperationException.class); + context.record(measureMap); + } @Test public void testSerializeDefault() throws Exception { diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java index 3eb5f933c7..4e9f6e2e18 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java @@ -13,12 +13,18 @@ package io.opencensus.stats; -import com.google.common.base.Function; -import com.google.common.base.Predicates; +import static com.google.common.truth.Truth.assertThat; + import com.google.common.collect.Iterables; -import com.google.common.truth.Truth; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.stats.AggregationData.CountData; +import io.opencensus.stats.AggregationData.HistogramData; +import io.opencensus.stats.AggregationData.MeanData; +import io.opencensus.stats.AggregationData.RangeData; +import io.opencensus.stats.AggregationData.StdDevData; +import io.opencensus.stats.AggregationData.SumData; import java.util.ArrayList; -import java.util.Collection; import java.util.List; /** Stats test utilities. */ @@ -53,108 +59,112 @@ private static StatsContextImpl createContext( } /** - * Creates a {@code DistributionAggregate} by adding the given values to a new {@link - * MutableDistribution} that has {@code BucketBoundaries}. + * Creates a list of {@link AggregationData}s by adding the given sequence of values, based on the + * definition of the given {@link Aggregation}s. * - * @param tags the {@code DistributionAggregate}'s tags. - * @param bucketBoundaries the bucket boundaries. - * @param values the values to add to the distribution. - * @return the new {@code DistributionAggregate} + * @param aggregations the {@code Aggregation}s to apply the values to. + * @param values the values to add to the {@code MutableAggregation}s. + * @return the new {@code AggregationData}s. */ - static DistributionAggregate createDistributionAggregate( - List tags, BucketBoundaries bucketBoundaries, List values) { - MutableDistribution mdist = MutableDistribution.create(bucketBoundaries); - for (double value : values) { - mdist.add(value); + static List createAggregationData( + List aggregations, double... values) { + List aggregationDataList = new ArrayList(aggregations.size()); + for (Aggregation aggregation : aggregations) { + MutableAggregation mAggregation = MutableViewData.createMutableAggregation(aggregation); + for (double value : values) { + mAggregation.add(value); + } + aggregationDataList.add(MutableViewData.createAggregationData(mAggregation)); } - MutableDistribution.Range range = mdist.getRange(); - return DistributionAggregate.create( - mdist.getCount(), - mdist.getMean(), - mdist.getSum(), - DistributionAggregate.Range.create(range.getMin(), range.getMax()), - tags, - mdist.getBucketCounts()); + return aggregationDataList; } /** - * Creates a {@code DistributionAggregate} by adding the given values to a new {@link - * MutableDistribution} that does not have {@code BucketBoundaries}. + * Compare the {@code AggregationData} with expected values based on its underlying type. The + * expected values are all optional (nullable). * - * @param tags the {@code DistributionAggregate}'s tags. - * @param values the values to add to the distribution. - * @return the new {@code DistributionAggregate} + * @param aggregate the {@code AggregationData} to be verified. + * @param sum the expected sum value, if aggregation is a {@code SumData}. + * @param count the expected count value, if aggregation is a {@code CountData}. + * @param bucketCounts the expected bucket counts, if aggregation is a {@code HistogramData}. + * @param min the expected min value, if aggregation is a {@code RangeData}. + * @param max the expected max value, if aggregation is a {@code RangeData}. + * @param mean the expected mean value, if aggregation is a {@code MeanData}. + * @param stdDev the expected standard deviation, if aggregation is a {@code StdDevData}. + * @param tolerance the tolerance used for {@code double} comparison. */ - static DistributionAggregate createDistributionAggregate( - List tags, List values) { - MutableDistribution mdist = MutableDistribution.create(); - for (double value : values) { - mdist.add(value); - } - MutableDistribution.Range range = mdist.getRange(); - return DistributionAggregate.create( - mdist.getCount(), - mdist.getMean(), - mdist.getSum(), - DistributionAggregate.Range.create(range.getMin(), range.getMax()), - tags); + static void assertAggregationDataEquals( + AggregationData aggregate, final Double sum, final Long count, final List bucketCounts, + final Double min, final Double max, final Double mean, final Double stdDev, + final double tolerance) { + aggregate.match( + new Function() { + @Override + public Void apply(SumData arg) { + assertThat(arg.getSum()).isWithin(tolerance).of(sum); + return null; + } + }, + new Function() { + @Override + public Void apply(CountData arg) { + assertThat(arg.getCount()).isEqualTo(count); + return null; + } + }, + new Function() { + @Override + public Void apply(HistogramData arg) { + assertThat(removeTrailingZeros(arg.getBucketCounts())).isEqualTo( + removeTrailingZeros(bucketCounts)); + return null; + } + }, + new Function() { + @Override + public Void apply(RangeData arg) { + if (max == Double.NEGATIVE_INFINITY && min == Double.POSITIVE_INFINITY) { + assertThat(arg.getMax()).isNegativeInfinity(); + assertThat(arg.getMin()).isPositiveInfinity(); + } else { + assertThat(arg.getMax()).isWithin(tolerance).of(max); + assertThat(arg.getMin()).isWithin(tolerance).of(min); + } + return null; + } + }, + new Function() { + @Override + public Void apply(MeanData arg) { + assertThat(arg.getMean()).isWithin(tolerance).of(mean); + return null; + } + }, + new Function() { + @Override + public Void apply(StdDevData arg) { + assertThat(arg.getStdDev()).isWithin(tolerance).of(stdDev); + return null; + } + }, + Functions.throwIllegalArgumentException()); } /** - * Asserts that the two sets of {@code DistributionAggregate}s are equivalent, with a given - * tolerance. The tolerance is used when comparing the mean and sum of values. The order of the - * {@code DistributionAggregate}s has no effect. The expected parameter is last, because it is - * likely to be a larger expression. + * Remove trailing zeros and return a boxed list of {@code Long}. * - * @param tolerance the tolerance used for {@code double} comparison. - * @param actual the actual test result. - * @param expected the expected value. - * @throws AssertionError if the {@code DistributionAggregate}s don't match. + * @param longs the input array of primitive type long. + * @return a list of boxed object Long, with trailing zeros removed. */ - static void assertDistributionAggregatesEquivalent( - double tolerance, - Collection actual, - Collection expected) { - Function> getTagsFunction = - new Function>() { - @Override - public List apply(DistributionAggregate agg) { - return agg.getTags(); - } - }; - Iterable> expectedTags = Iterables.transform(expected, getTagsFunction); - Iterable> actualTags = Iterables.transform(actual, getTagsFunction); - Truth.assertThat(actualTags).containsExactlyElementsIn(expectedTags); - for (DistributionAggregate expectedAgg : expected) { - DistributionAggregate actualAgg = - Iterables.find( - actual, - Predicates.compose(Predicates.equalTo(expectedAgg.getTags()), getTagsFunction)); - assertDistributionAggregateValuesEquivalent( - "DistributionAggregate tags=" + expectedAgg.getTags(), - tolerance, - expectedAgg, - actualAgg); + static List removeTrailingZeros(long... longs) { + if (longs == null) { + return null; } - } - - private static void assertDistributionAggregateValuesEquivalent( - String msg, double tolerance, DistributionAggregate agg1, DistributionAggregate agg2) { - Truth.assertWithMessage(msg + " count").that(agg1.getCount()).isEqualTo(agg2.getCount()); - Truth.assertWithMessage(msg + " mean") - .that(agg1.getMean()) - .isWithin(tolerance) - .of(agg2.getMean()); - Truth.assertWithMessage(msg + " sum").that(agg1.getSum()).isWithin(tolerance).of(agg2.getSum()); - Truth.assertWithMessage(msg + " range").that(agg1.getRange()).isEqualTo(agg2.getRange()); - - if (agg1.getBucketCounts() == null && agg2.getBucketCounts() == null) { - return; - } else { - Truth.assertWithMessage(msg + " bucket counts") - .that(removeTrailingZeros(agg1.getBucketCounts())) - .isEqualTo(removeTrailingZeros(agg2.getBucketCounts())); + List boxed = new ArrayList(longs.length); + for (long l : longs) { + boxed.add(l); // Boxing. Could use Arrays.stream().boxed().collect after Java 8. } + return removeTrailingZeros(boxed); } private static List removeTrailingZeros(List longs) { diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index 46b2490766..a2e5732fe0 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -17,7 +17,6 @@ import io.opencensus.stats.Measure.MeasureDouble; import io.opencensus.testing.common.TestClock; import java.util.Arrays; -import java.util.Collection; import org.junit.Ignore; import org.junit.Rule; import org.junit.rules.ExpectedException; @@ -459,11 +458,4 @@ public class ViewManagerImplTest { // StatsTestUtil.createDistributionAggregate( // Arrays.asList(Tag.create(KEY, VALUE)), Arrays.asList(1.1)))); // } - - // TODO(sebright) Consider making this helper method work with larger ranges of double values and - // moving it to StatsTestUtil. - private static void assertDistributionAggregatesEquivalent( - Collection actual, Collection expected) { - StatsTestUtil.assertDistributionAggregatesEquivalent(1e-6, actual, expected); - } } From 0333b0f77e7354c7eaa518b22588bbf2f67b4d27 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 9 Aug 2017 15:55:20 -0700 Subject: [PATCH 0366/1581] Add TODO for deciding how to handle keys with the same name but different types. --- core/src/main/java/io/opencensus/tags/TagContextBuilder.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/java/io/opencensus/tags/TagContextBuilder.java b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java index 251651b37d..2a490ef177 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextBuilder.java +++ b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java @@ -19,6 +19,8 @@ import javax.annotation.concurrent.Immutable; /** Builder for the {@link TagContext} class. */ +// TODO(sebright): Decide what to do when 'set' is called with a key that has the same name as an +// existing key, but a different type. We currently keep both keys. public abstract class TagContextBuilder { private static final TagContextBuilder NOOP_TAG_CONTEXT_BUILDER = new NoopTagContextBuilder(); From bf7b834e2d544b36ca8225cd997daced393dd240 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 10 Aug 2017 13:22:01 -0700 Subject: [PATCH 0367/1581] Revert "Temporarily remove methods for working with the current context." This reverts commit 23845cb05e2a8453b60eb971a9cb59d888a92e92. --- .../io/opencensus/tags/TagContextBuilder.java | 13 +++++++ .../java/io/opencensus/tags/TagContexts.java | 36 ++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/io/opencensus/tags/TagContextBuilder.java b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java index 2a490ef177..259f8ab62a 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextBuilder.java +++ b/core/src/main/java/io/opencensus/tags/TagContextBuilder.java @@ -13,6 +13,7 @@ package io.opencensus.tags; +import io.opencensus.common.Scope; import io.opencensus.tags.TagKey.TagKeyBoolean; import io.opencensus.tags.TagKey.TagKeyLong; import io.opencensus.tags.TagKey.TagKeyString; @@ -66,6 +67,18 @@ public abstract class TagContextBuilder { */ public abstract TagContext build(); + /** + * Enters the scope of code where the {@link TagContext} created from this builder is in the + * current context and returns an object that represents that scope. The scope is exited when the + * returned object is closed. + * + * @return an object that defines a scope where the {@code TagContext} created from this builder + * is set to the current context. + */ + public final Scope buildScoped() { + return CurrentTagContextUtils.withTagContext(build()); + } + /** * Returns a {@code TagContextBuilder} that ignores all calls to {@link #set}. * diff --git a/core/src/main/java/io/opencensus/tags/TagContexts.java b/core/src/main/java/io/opencensus/tags/TagContexts.java index c72175647c..077c628b60 100644 --- a/core/src/main/java/io/opencensus/tags/TagContexts.java +++ b/core/src/main/java/io/opencensus/tags/TagContexts.java @@ -13,10 +13,11 @@ package io.opencensus.tags; +import io.opencensus.common.Scope; import javax.annotation.concurrent.Immutable; /** - * Object for creating new {@link TagContext}s. + * Object for creating new {@link TagContext}s and {@code TagContext}s based on the current context. * *

This class returns {@link TagContextBuilder builders} that can be used to create the * implementation-dependent {@link TagContext}s. @@ -31,6 +32,17 @@ public abstract class TagContexts { */ public abstract TagContext empty(); + /** + * Returns the current {@code TagContext}. + * + * @return the current {@code TagContext}. + */ + // TODO(sebright): Should we let the implementation override this method? + public final TagContext getCurrentTagContext() { + TagContext tags = CurrentTagContextUtils.getCurrentTagContext(); + return tags == null ? empty() : tags; + } + /** * Returns a new empty {@code Builder}. * @@ -47,6 +59,28 @@ public TagContextBuilder emptyBuilder() { */ public abstract TagContextBuilder toBuilder(TagContext tags); + /** + * Returns a new builder created from the current {@code TagContext}. + * + * @return a new builder created from the current {@code TagContext}. + */ + public final TagContextBuilder currentBuilder() { + return toBuilder(getCurrentTagContext()); + } + + /** + * Enters the scope of code where the given {@code TagContext} is in the current context and + * returns an object that represents that scope. The scope is exited when the returned object is + * closed. + * + * @param tags the {@code TagContext} to be set to the current context. + * @return an object that defines a scope where the given {@code TagContext} is set to the current + * context. + */ + public final Scope withTagContext(TagContext tags) { + return CurrentTagContextUtils.withTagContext(tags); + } + /** * Returns a {@code TagContexts} that only produces {@link TagContext}s with no tags. * From 3a8f7ff1202694e976bff006a3d84d028ea06ef7 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 10 Aug 2017 17:58:19 -0700 Subject: [PATCH 0368/1581] Add tests for public methods that interact with the current TagContext. --- .../tags/ScopedTagContextsTest.java | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 core/src/test/java/io/opencensus/tags/ScopedTagContextsTest.java diff --git a/core/src/test/java/io/opencensus/tags/ScopedTagContextsTest.java b/core/src/test/java/io/opencensus/tags/ScopedTagContextsTest.java new file mode 100644 index 0000000000..6b277cf818 --- /dev/null +++ b/core/src/test/java/io/opencensus/tags/ScopedTagContextsTest.java @@ -0,0 +1,192 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import io.opencensus.common.Scope; +import io.opencensus.tags.Tag.TagString; +import io.opencensus.tags.TagKey.TagKeyBoolean; +import io.opencensus.tags.TagKey.TagKeyLong; +import io.opencensus.tags.TagKey.TagKeyString; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Unit tests for the methods in {@link TagContexts} and {@link TagContextBuilder} that interact + * with the current {@link TagContext}. + */ +@RunWith(JUnit4.class) +public class ScopedTagContextsTest { + private static final TagKeyString KEY_1 = TagKeyString.create("key 1"); + private static final TagKeyString KEY_2 = TagKeyString.create("key 2"); + + private static final TagValueString VALUE_1 = TagValueString.create("value 1"); + private static final TagValueString VALUE_2 = TagValueString.create("value 2"); + + private final TagContext emptyTagContext = new SimpleTagContext(); + + private final TagContexts tagContexts = + new TagContexts() { + @Override + public TagContextBuilder toBuilder(TagContext tags) { + return new SimpleTagContextBuilder(((SimpleTagContext) tags).tags); + } + + @Override + public TagContext empty() { + return emptyTagContext; + } + }; + + @Test + public void defaultTagContext() { + assertThat(tagContexts.getCurrentTagContext()).isSameAs(emptyTagContext); + } + + @Test + public void withTagContext() { + assertThat(tagContexts.getCurrentTagContext()).isSameAs(emptyTagContext); + TagContext scopedTags = new SimpleTagContext(TagString.create(KEY_1, VALUE_1)); + Scope scope = tagContexts.withTagContext(scopedTags); + try { + assertThat(tagContexts.getCurrentTagContext()).isSameAs(scopedTags); + } finally { + scope.close(); + } + assertThat(tagContexts.getCurrentTagContext()).isSameAs(emptyTagContext); + } + + @Test + public void createBuilderFromCurrentTags() { + TagContext scopedTags = new SimpleTagContext(TagString.create(KEY_1, VALUE_1)); + Scope scope = tagContexts.withTagContext(scopedTags); + try { + TagContext newTags = tagContexts.currentBuilder().set(KEY_2, VALUE_2).build(); + assertThat(asList(newTags)) + .containsExactly(TagString.create(KEY_1, VALUE_1), TagString.create(KEY_2, VALUE_2)); + assertThat(tagContexts.getCurrentTagContext()).isSameAs(scopedTags); + } finally { + scope.close(); + } + } + + @Test + public void setCurrentTagsWithBuilder() { + assertThat(tagContexts.getCurrentTagContext()).isSameAs(emptyTagContext); + Scope scope = tagContexts.emptyBuilder().set(KEY_1, VALUE_1).buildScoped(); + try { + assertThat(asList(tagContexts.getCurrentTagContext())) + .containsExactly(TagString.create(KEY_1, VALUE_1)); + } finally { + scope.close(); + } + assertThat(tagContexts.getCurrentTagContext()).isSameAs(emptyTagContext); + } + + @Test + public void addToCurrentTagsWithBuilder() { + TagContext scopedTags = new SimpleTagContext(TagString.create(KEY_1, VALUE_1)); + Scope scope1 = tagContexts.withTagContext(scopedTags); + try { + Scope scope2 = tagContexts.currentBuilder().set(KEY_2, VALUE_2).buildScoped(); + try { + assertThat(asList(tagContexts.getCurrentTagContext())) + .containsExactly(TagString.create(KEY_1, VALUE_1), TagString.create(KEY_2, VALUE_2)); + } finally { + scope2.close(); + } + assertThat(tagContexts.getCurrentTagContext()).isSameAs(scopedTags); + } finally { + scope1.close(); + } + } + + private static List asList(TagContext tags) { + return Lists.newArrayList(tags.unsafeGetIterator()); + } + + private static final class SimpleTagContextBuilder extends TagContextBuilder { + private final Map tagMap; + + SimpleTagContextBuilder(Set tags) { + Map tagMap = Maps.newHashMap(); + for (TagString tag : tags) { + tagMap.put(tag.getKey(), tag.getValue()); + } + this.tagMap = Maps.newHashMap(tagMap); + } + + @Override + public TagContextBuilder set(TagKeyString key, TagValueString value) { + tagMap.put(key, value); + return this; + } + + @Override + public TagContextBuilder set(TagKeyLong key, long value) { + throw new UnsupportedOperationException(); + } + + @Override + public TagContextBuilder set(TagKeyBoolean key, boolean value) { + throw new UnsupportedOperationException(); + } + + @Override + public TagContextBuilder clear(TagKey key) { + throw new UnsupportedOperationException(); + } + + @Override + public TagContext build() { + Set tags = new HashSet(); + for (Entry entry : tagMap.entrySet()) { + tags.add(TagString.create(entry.getKey(), entry.getValue())); + } + return new SimpleTagContext(tags); + } + } + + private static final class SimpleTagContext extends TagContext { + private final Set tags; + + public SimpleTagContext(TagString... tags) { + this(Arrays.asList(tags)); + } + + public SimpleTagContext(Collection tags) { + this.tags = Collections.unmodifiableSet(new HashSet(tags)); + } + + @Override + public Iterator unsafeGetIterator() { + return Iterators.transform( + tags.iterator(), com.google.common.base.Functions.identity()); + } + } +} From ee50410435e6e000a76239a8cfd091aed4ab1cc5 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Thu, 10 Aug 2017 18:45:48 -0700 Subject: [PATCH 0369/1581] Rename TagContextFactoryImplTest to TagContextsImplTest. The new name matches the class under test. --- ...{TagContextFactoryImplTest.java => TagContextsImplTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename core_impl/src/test/java/io/opencensus/impl/tags/{TagContextFactoryImplTest.java => TagContextsImplTest.java} (98%) diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextsImplTest.java similarity index 98% rename from core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java rename to core_impl/src/test/java/io/opencensus/impl/tags/TagContextsImplTest.java index 6347a740b6..607e1e8eed 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextFactoryImplTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextsImplTest.java @@ -38,7 +38,7 @@ /** Tests for {@link TagContextsImpl}. */ @RunWith(JUnit4.class) -public class TagContextFactoryImplTest { +public class TagContextsImplTest { private final TagContexts tagContexts = new TagContextsImpl(); private static final TagKeyString KS = TagKeyString.create("ks"); From e126423d44e7f6fc9c581189e906ffbc9b689d72 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 11 Aug 2017 03:46:14 +0200 Subject: [PATCH 0370/1581] Use the ext libraries property when referring to the Byte Buddy dependency. --- contrib/agent/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index e275ebdcf3..4759d87be9 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -98,7 +98,7 @@ shadowJar { // Include only the following dependencies (excluding transitive dependencies). dependencies { - include(dependency('net.bytebuddy:byte-buddy')) + include(dependency(libraries.byte_buddy)) include(dependency(libraries.guava)) } From 54db9df1e45449c461fa618b96771476d157ae59 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 11 Aug 2017 11:50:10 +0200 Subject: [PATCH 0371/1581] Move everything related to integration tests to its own section in the build script. --- contrib/agent/build.gradle | 54 ++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index e275ebdcf3..2ba31583d6 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -30,27 +30,8 @@ def agentBootstrapClasses = agentBootstrapPackageDir + '**' // classloader). def agentRepackaged = "${agentPackage}.deps" -// The setup for integration testing is mostly based on -// https://www.petrikainulainen.net/programming/gradle/getting-started-with-gradle-integration-testing/. -sourceSets { - integrationTest { - java { - compileClasspath += main.output + test.output - runtimeClasspath += main.output + test.output - srcDir file('src/integration-test/java') - } - resources.srcDir file('src/integration-test/resources') - } -} - -configurations { - integrationTestCompile.extendsFrom testCompile - integrationTestRuntime.extendsFrom testRuntime -} - dependencies { compileOnly libraries.grpc_context - integrationTestCompile libraries.grpc_context compile libraries.findbugs_annotations compile libraries.guava compile libraries.byte_buddy @@ -58,12 +39,6 @@ dependencies { signature 'org.codehaus.mojo.signature:java16:+@signature' } -// Disable findbugs for integration tests, too. -findbugsIntegrationTest.enabled = false - -// Disable checkstyle for integration tests if not java8. -checkstyleIntegrationTest.enabled = JavaVersion.current().isJava8Compatible() - jar { manifest { // Set the required manifest attributes for the Java agent, cf. @@ -148,6 +123,35 @@ jar.finalizedBy shadowJar // TODO(stschmidt): Proguard-shrink the agent JAR. +// Integration tests. The setup is mostly based on +// https://www.petrikainulainen.net/programming/gradle/getting-started-with-gradle-integration-testing/. + +sourceSets { + integrationTest { + java { + compileClasspath += main.output + test.output + runtimeClasspath += main.output + test.output + srcDir file('src/integration-test/java') + } + resources.srcDir file('src/integration-test/resources') + } +} + +configurations { + integrationTestCompile.extendsFrom testCompile + integrationTestRuntime.extendsFrom testRuntime +} + +dependencies { + integrationTestCompile libraries.grpc_context +} + +// Disable checkstyle for integration tests if not java8. +checkstyleIntegrationTest.enabled = JavaVersion.current().isJava8Compatible() + +// Disable findbugs for integration tests, too. +findbugsIntegrationTest.enabled = false + // Run integration tests with the agent enabled. task integrationTest(type: Test) { testClassesDirs = sourceSets.integrationTest.output.classesDirs From d2ce9ffb61d9857f2ae3a54c1ef91c7da492f231 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 11 Aug 2017 12:35:34 +0200 Subject: [PATCH 0372/1581] Apply gradle plugin io.morethan.jmhreport for visualizing JMH results. --- contrib/agent/build.gradle | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index e275ebdcf3..0b7525a87a 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -1,7 +1,8 @@ plugins { id 'com.github.johnrengelman.shadow' version '2.0.1' id 'me.tatarka.retrolambda' version '3.6.0' - id "me.champeau.gradle.jmh" version "0.4.4" + id 'me.champeau.gradle.jmh' version "0.4.4" + id 'io.morethan.jmhreport' version '0.5.0' } description = 'OpenCensus Agent' @@ -194,4 +195,12 @@ jmh { iterations = 10 fork = 1 failOnError = true + resultFormat = 'JSON' } + +jmhReport { + jmhResultPath = project.file("${project.buildDir}/reports/jmh/results.json") + jmhReportOutput = project.file("${project.buildDir}/reports/jmh") +} + +tasks.jmh.finalizedBy tasks.jmhReport From 9d7e45a9a5e1f1efde20a370eb50b2a6b1a2f095 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 11 Aug 2017 16:17:48 +0200 Subject: [PATCH 0373/1581] Prefer single quotes. --- contrib/agent/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 33d19d8912..bcf8734a98 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -1,7 +1,7 @@ plugins { id 'com.github.johnrengelman.shadow' version '2.0.1' id 'me.tatarka.retrolambda' version '3.6.0' - id 'me.champeau.gradle.jmh' version "0.4.4" + id 'me.champeau.gradle.jmh' version '0.4.4' id 'io.morethan.jmhreport' version '0.5.0' } From bf93de81d79c90dd2403d8197a65cf61a98307a0 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 11 Aug 2017 16:52:46 +0200 Subject: [PATCH 0374/1581] Fix grammar in doc. --- contrib/agent/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 33d19d8912..903c5f9735 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -26,8 +26,8 @@ def agentBootstrapPackage = "${agentPackage}.bootstrap" def agentBootstrapPackageDir = agentBootstrapPackage.replace('.', '/') + '/' def agentBootstrapClasses = agentBootstrapPackageDir + '**' -// The package to which which we relocate all third party packages. This avoids any conflicts of -// the agent's classes with the app's classes, which are loaded by the same classloader (the system +// The package to which we relocate all third party packages. This avoids any conflicts of the +// agent's classes with the app's classes, which are loaded by the same classloader (the system // classloader). def agentRepackaged = "${agentPackage}.deps" From 5c714878aa653e90bf1fe6701a40eb9af392aaea Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 11 Aug 2017 17:42:56 +0200 Subject: [PATCH 0375/1581] Introduce a simplistic plug-in mechanism. --- build.gradle | 1 + contrib/agent/build.gradle | 2 ++ .../ExecutorInstrumentationTest.java | 2 +- .../ExecutorInstrumentationBenchmark.java | 2 +- .../opencensus/contrib/agent/AgentMain.java | 33 +++---------------- .../ContextStrategyImpl.java | 2 +- .../ExecutorInstrumentation.java | 25 +++++++++++--- .../agent/instrumentation/Instrumenter.java | 31 +++++++++++++++++ 8 files changed, 63 insertions(+), 35 deletions(-) rename contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/{ => instrumentation}/ExecutorInstrumentationTest.java (99%) rename contrib/agent/src/jmh/java/io/opencensus/contrib/agent/{ => instrumentation}/ExecutorInstrumentationBenchmark.java (98%) rename contrib/agent/src/main/java/io/opencensus/contrib/agent/{ => instrumentation}/ContextStrategyImpl.java (94%) rename contrib/agent/src/main/java/io/opencensus/contrib/agent/{ => instrumentation}/ExecutorInstrumentation.java (80%) create mode 100644 contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/Instrumenter.java diff --git a/build.gradle b/build.gradle index 6b9f1dda98..dac0061d37 100644 --- a/build.gradle +++ b/build.gradle @@ -105,6 +105,7 @@ subprojects { libraries = [ auto_value : "com.google.auto.value:auto-value:${autoValueVersion}", + auto_service : 'com.google.auto.service:auto-service:1.0-rc3', byte_buddy : 'net.bytebuddy:byte-buddy:1.7.1', disruptor : 'com.lmax:disruptor:3.3.6', errorprone : 'com.google.errorprone:error_prone_annotations:2.0.11', diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 55c7a96b25..8159c85600 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -32,6 +32,7 @@ def agentBootstrapClasses = agentBootstrapPackageDir + '**' def agentRepackaged = "${agentPackage}.deps" dependencies { + compileOnly libraries.auto_service compileOnly libraries.grpc_context compile libraries.findbugs_annotations compile libraries.guava @@ -113,6 +114,7 @@ shadowJar { // ... except for the expected entries. [ agentPackageDir, 'META-INF/MANIFEST.MF', + 'META-INF/services/io.opencensus.contrib.agent.instrumentation.Instrumenter' ].any { entry.isDirectory() ? it.startsWith(entry.name) : it == entry.name } // Also, should not have the bootstrap classes. assert !entry.name.startsWith(agentBootstrapPackageDir) diff --git a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentationTest.java similarity index 99% rename from contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java rename to contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentationTest.java index c94b4b5a40..d0193ceac8 100644 --- a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ExecutorInstrumentationTest.java +++ b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentationTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.contrib.agent; +package io.opencensus.contrib.agent.instrumentation; import static com.google.common.truth.Truth.assertThat; diff --git a/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentationBenchmark.java similarity index 98% rename from contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java rename to contrib/agent/src/jmh/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentationBenchmark.java index ee6b714581..99c07cdf18 100644 --- a/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/ExecutorInstrumentationBenchmark.java +++ b/contrib/agent/src/jmh/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentationBenchmark.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.contrib.agent; +package io.opencensus.contrib.agent.instrumentation; import com.google.common.util.concurrent.MoreExecutors; import io.grpc.Context; diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java index c3450868e5..9f81e75e91 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/AgentMain.java @@ -19,7 +19,9 @@ import io.opencensus.contrib.agent.bootstrap.ContextManager; import io.opencensus.contrib.agent.bootstrap.ContextStrategy; +import io.opencensus.contrib.agent.instrumentation.Instrumenter; import java.lang.instrument.Instrumentation; +import java.util.ServiceLoader; import java.util.jar.JarFile; import java.util.logging.Logger; import net.bytebuddy.agent.builder.AgentBuilder; @@ -74,8 +76,9 @@ public static void premain(String agentArgs, Instrumentation instrumentation) th .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) .with(new AgentBuilderListener()) .ignore(none()); - agentBuilder = LazyLoaded.addContextPropagation(agentBuilder); - // TODO: Add more instrumentation, potentially introducing a plugin mechanism. + for (Instrumenter instrumenter : ServiceLoader.load(Instrumenter.class)) { + agentBuilder = instrumenter.instrument(agentBuilder); + } agentBuilder.installOn(instrumentation); logger.info("Initialized."); @@ -86,30 +89,4 @@ private static void checkLoadedByBootstrapClassloader(Class clazz) { "%s must be loaded by the bootstrap classloader", clazz); } - - private static class LazyLoaded { - - /** - * Adds automatic context propagation. - * - * @param agentBuilder an {@link AgentBuilder} object to which the additional instrumentation is - * added - * @return an {@link AgentBuilder} object having the additional instrumentation - */ - private static AgentBuilder addContextPropagation(AgentBuilder agentBuilder) { - // TODO(stschmidt): Gracefully handle the case of missing io.grpc.Context at runtime. - - // Initialize the ContextManager with the concrete ContextStrategy. - ContextManager.setContextStrategy(new ContextStrategyImpl()); - - // Add automatic context propagation to Executor#execute. - agentBuilder = agentBuilder - .type(ExecutorInstrumentation.createMatcher()) - .transform(ExecutorInstrumentation.createTransformer()); - - // TODO(stschmidt): Add automatic context propagation to Thread#start. - - return agentBuilder; - } - } } diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ContextStrategyImpl.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java similarity index 94% rename from contrib/agent/src/main/java/io/opencensus/contrib/agent/ContextStrategyImpl.java rename to contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java index 3edafeac80..616d3d430a 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ContextStrategyImpl.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.contrib.agent; +package io.opencensus.contrib.agent.instrumentation; import io.grpc.Context; import io.opencensus.contrib.agent.bootstrap.ContextStrategy; diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentation.java similarity index 80% rename from contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java rename to contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentation.java index a6d09e301e..ccdd6e6347 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ExecutorInstrumentation.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentation.java @@ -11,8 +11,9 @@ * limitations under the License. */ -package io.opencensus.contrib.agent; +package io.opencensus.contrib.agent.instrumentation; +import static com.google.common.base.Preconditions.checkNotNull; import static net.bytebuddy.matcher.ElementMatchers.isAbstract; import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf; import static net.bytebuddy.matcher.ElementMatchers.nameEndsWith; @@ -20,6 +21,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.not; +import com.google.auto.service.AutoService; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.opencensus.contrib.agent.bootstrap.ContextManager; import java.util.concurrent.Executor; @@ -35,7 +37,22 @@ * {@link Runnable}, just like the Microsoft .Net Framework propagates the System.Threading.ExecutionContext. */ -final class ExecutorInstrumentation { +@AutoService(Instrumenter.class) +public final class ExecutorInstrumentation implements Instrumenter { + + @Override + public AgentBuilder instrument(AgentBuilder agentBuilder) { + checkNotNull(agentBuilder, "agentBuilder"); + + // TODO(stschmidt): Gracefully handle the case of missing io.grpc.Context at runtime. + + // Initialize the ContextManager with the concrete ContextStrategy. + ContextManager.setContextStrategy(new ContextStrategyImpl()); + + return agentBuilder + .type(createMatcher()) + .transform(createTransformer()); + } private static class Transformer implements AgentBuilder.Transformer { @@ -46,7 +63,7 @@ public DynamicType.Builder transform(DynamicType.Builder builder, } } - static ElementMatcher.Junction createMatcher() { + private static ElementMatcher.Junction createMatcher() { // This matcher matches implementations of Executor, but excludes CurrentContextExecutor and // FixedContextExecutor from io.grpc.Context, which already propagate the context. // TODO(stschmidt): As the executor implementation itself (e.g. ThreadPoolExecutor) is @@ -60,7 +77,7 @@ static ElementMatcher.Junction createMatcher() { .or(nameEndsWith("FixedContextExecutor"))))); } - static AgentBuilder.Transformer createTransformer() { + private static AgentBuilder.Transformer createTransformer() { return new Transformer(); } diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/Instrumenter.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/Instrumenter.java new file mode 100644 index 0000000000..fab933dab9 --- /dev/null +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/Instrumenter.java @@ -0,0 +1,31 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent.instrumentation; + +import net.bytebuddy.agent.builder.AgentBuilder; + +/** + * Interface for plug-ins that add bytecode instrumentation. + */ +public interface Instrumenter { + + /** + * Adds bytecode instrumentation to the given {@link AgentBuilder}. + * + * @param agentBuilder an {@link AgentBuilder} object to which the additional instrumentation is + * added + * @return an {@link AgentBuilder} object having the additional instrumentation + */ + AgentBuilder instrument(AgentBuilder agentBuilder); +} From fe82160db75f96327d0060d69d8b86f87aaac85a Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 11 Aug 2017 18:50:37 +0300 Subject: [PATCH 0376/1581] Update README to extract links and add maven release badge. (#504) --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a49cd7d400..0e28e24fbc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,14 @@ OpenCensus - A stats collection and distributed tracing framework ================================================================= -[![Build Status](https://travis-ci.org/census-instrumentation/opencensus-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/opencensus-java) [![Build status](https://ci.appveyor.com/api/projects/status/hxthmpkxar4jq4be/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/opencensus-java/branch/master) +[![Build Status][travis-image]][travis-url] [![Build status][appveyor-image]][appveyor-url] [![Maven Central][maven-image]][maven-url] OpenCensus provides a framework to define and collect stats against metrics and to break those stats down across user-defined dimensions. The library is in alpha stage and the API is subject to change. + +[travis-image]: https://travis-ci.org/census-instrumentation/opencensus-java.svg?branch=master +[travis-url]: https://travis-ci.org/census-instrumentation/opencensus-java +[appveyor-image]: https://ci.appveyor.com/api/projects/status/hxthmpkxar4jq4be/branch/master?svg=true +[appveyor-url]: https://ci.appveyor.com/project/instrumentationjavateam/opencensus-java/branch/master +[maven-image]: https://maven-badges.herokuapp.com/maven-central/io.opencensus/opencensus-api/badge.svg +[maven-url]: https://maven-badges.herokuapp.com/maven-central/io.opencensus/opencensus-api \ No newline at end of file From 199be03c07ab5b57869a19a51aee67ce645efd3a Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 11 Aug 2017 19:00:06 +0300 Subject: [PATCH 0377/1581] Stop using context ClassLoader in Provider (#502) --- .../java/io/opencensus/internal/Provider.java | 26 ------------------- .../java/io/opencensus/trace/Tracing.java | 2 +- .../io/opencensus/internal/ProviderTest.java | 12 ++++----- .../main/java/io/opencensus/stats/Stats.java | 2 +- .../main/java/io/opencensus/tags/Tags.java | 2 +- 5 files changed, 9 insertions(+), 35 deletions(-) diff --git a/api/src/main/java/io/opencensus/internal/Provider.java b/api/src/main/java/io/opencensus/internal/Provider.java index 05e36d092d..43cd40f675 100644 --- a/api/src/main/java/io/opencensus/internal/Provider.java +++ b/api/src/main/java/io/opencensus/internal/Provider.java @@ -42,30 +42,4 @@ public static T createInstance(Class rawClass, Class superclass) { "Provider " + rawClass.getName() + " could not be instantiated.", e); } } - - /** - * Get the correct {@link ClassLoader} that must be used when loading using reflection. - * - * @return The correct {@code ClassLoader} that must be used when loading using reflection. - */ - public static ClassLoader getCorrectClassLoader(Class superClass) { - if (isAndroid()) { - // When android:sharedUserId or android:process is used, Android will setup a dummy - // ClassLoader for the thread context (http://stackoverflow.com/questions/13407006), - // instead of letting users to manually set context class loader, we choose the - // correct class loader here. - return superClass.getClassLoader(); - } - return Thread.currentThread().getContextClassLoader(); - } - - private static boolean isAndroid() { - try { - Class.forName("android.app.Application", /*initialize=*/ false, null); - return true; - } catch (Exception e) { - // If Application isn't loaded, it might as well not be Android. - return false; - } - } } diff --git a/api/src/main/java/io/opencensus/trace/Tracing.java b/api/src/main/java/io/opencensus/trace/Tracing.java index 869fae4848..70b0a70eda 100644 --- a/api/src/main/java/io/opencensus/trace/Tracing.java +++ b/api/src/main/java/io/opencensus/trace/Tracing.java @@ -26,7 +26,7 @@ public final class Tracing { private static final Logger logger = Logger.getLogger(Tracing.class.getName()); private static final TraceComponent traceComponent = - loadTraceComponent(Provider.getCorrectClassLoader(TraceComponent.class)); + loadTraceComponent(TraceComponent.class.getClassLoader()); /** * Returns the global {@link Tracer}. diff --git a/api/src/test/java/io/opencensus/internal/ProviderTest.java b/api/src/test/java/io/opencensus/internal/ProviderTest.java index 3ca13b725d..ed6e8a024a 100644 --- a/api/src/test/java/io/opencensus/internal/ProviderTest.java +++ b/api/src/test/java/io/opencensus/internal/ProviderTest.java @@ -49,7 +49,7 @@ public void createInstance_ThrowsErrorWhenClassIsPrivate() throws ClassNotFoundE Class.forName( "io.opencensus.internal.ProviderTest$PrivateClass", true, - Provider.getCorrectClassLoader(ProviderTest.class)), + ProviderTest.class.getClassLoader()), PrivateClass.class); } @@ -60,7 +60,7 @@ public void createInstance_ThrowsErrorWhenClassHasPrivateConstructor() Class.forName( "io.opencensus.internal.ProviderTest$PrivateConstructorClass", true, - Provider.getCorrectClassLoader(ProviderTest.class)), + ProviderTest.class.getClassLoader()), PrivateConstructorClass.class); } @@ -71,7 +71,7 @@ public void createInstance_ThrowsErrorWhenClassDoesNotHaveDefaultConstructor() Class.forName( "io.opencensus.internal.ProviderTest$NoDefaultConstructorClass", true, - Provider.getCorrectClassLoader(ProviderTest.class)), + ProviderTest.class.getClassLoader()), NoDefaultConstructorClass.class); } @@ -81,7 +81,7 @@ public void createInstance_ThrowsErrorWhenClassIsNotASubclass() throws ClassNotF Class.forName( "io.opencensus.internal.ProviderTest$GoodClass", true, - Provider.getCorrectClassLoader(ProviderTest.class)), + ProviderTest.class.getClassLoader()), MyInterface.class); } @@ -92,7 +92,7 @@ public void createInstance_GoodClass() throws ClassNotFoundException { Class.forName( "io.opencensus.internal.ProviderTest$GoodClass", true, - Provider.getCorrectClassLoader(ProviderTest.class)), + ProviderTest.class.getClassLoader()), GoodClass.class)) .isNotNull(); } @@ -104,7 +104,7 @@ public void createInstance_GoodSubclass() throws ClassNotFoundException { Class.forName( "io.opencensus.internal.ProviderTest$MyInterfaceImpl", true, - Provider.getCorrectClassLoader(ProviderTest.class)), + ProviderTest.class.getClassLoader()), MyInterface.class)) .isNotNull(); } diff --git a/core/src/main/java/io/opencensus/stats/Stats.java b/core/src/main/java/io/opencensus/stats/Stats.java index d245a6d8c9..3221db96f6 100644 --- a/core/src/main/java/io/opencensus/stats/Stats.java +++ b/core/src/main/java/io/opencensus/stats/Stats.java @@ -24,7 +24,7 @@ public final class Stats { private static final Logger logger = Logger.getLogger(Stats.class.getName()); private static final StatsComponent statsComponent = - loadStatsComponent(Provider.getCorrectClassLoader(StatsComponent.class)); + loadStatsComponent(StatsComponent.class.getClassLoader()); /** Returns the default {@link StatsContextFactory}. */ @Nullable diff --git a/core/src/main/java/io/opencensus/tags/Tags.java b/core/src/main/java/io/opencensus/tags/Tags.java index df1f01885a..4f68c1fd2e 100644 --- a/core/src/main/java/io/opencensus/tags/Tags.java +++ b/core/src/main/java/io/opencensus/tags/Tags.java @@ -23,7 +23,7 @@ public final class Tags { private static final Logger logger = Logger.getLogger(Tags.class.getName()); private static final TagsComponent tagsComponent = - loadTagsComponent(Provider.getCorrectClassLoader(TagsComponent.class)); + loadTagsComponent(TagsComponent.class.getClassLoader()); private Tags() {} From 870a06c440b59f8e64d5eb9b5ddddb79dd0299d1 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Fri, 11 Aug 2017 10:53:02 -0700 Subject: [PATCH 0378/1581] Add TODOs on whether we want to change StdDev. (#507) --- core/src/main/java/io/opencensus/stats/Aggregation.java | 2 ++ .../src/main/java/io/opencensus/stats/MutableAggregation.java | 1 + 2 files changed, 3 insertions(+) diff --git a/core/src/main/java/io/opencensus/stats/Aggregation.java b/core/src/main/java/io/opencensus/stats/Aggregation.java index e6540e6504..4d36aee7b1 100644 --- a/core/src/main/java/io/opencensus/stats/Aggregation.java +++ b/core/src/main/java/io/opencensus/stats/Aggregation.java @@ -212,6 +212,8 @@ public final T match( /** Calculate standard deviation on aggregated {@code MeasureValue}s. */ @Immutable @AutoValue + // TODO(songya): StackDriver uses sumOfSquaredDeviation instead of standard deviation, do we want + // to change this aggregation to sumOfSquaredDeviation instead? public abstract static class StdDev extends Aggregation { StdDev() { diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableAggregation.java b/core_impl/src/main/java/io/opencensus/stats/MutableAggregation.java index b044683d87..538a262dcd 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableAggregation.java +++ b/core_impl/src/main/java/io/opencensus/stats/MutableAggregation.java @@ -335,6 +335,7 @@ void add(double value) { * * @return the aggregated standard deviations. */ + // TODO(songya): decide if we want to return sumOfSquaredDeviations directly. double getStdDev() { return count == 0 ? 0 : Math.sqrt(sumOfSquaredDeviations / count); } From a6e1c7de4891e54d23a00d873a44e00bbf80820d Mon Sep 17 00:00:00 2001 From: Yang Song Date: Fri, 11 Aug 2017 14:02:08 -0700 Subject: [PATCH 0379/1581] Update ViewManagerImplTest. (#493) --- .../io/opencensus/stats/StatsContextTest.java | 13 +- .../io/opencensus/stats/StatsTestUtil.java | 162 ++-- .../opencensus/stats/ViewManagerImplTest.java | 810 +++++++++--------- 3 files changed, 511 insertions(+), 474 deletions(-) diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index a972071ccf..d6f2c586e2 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -139,12 +139,13 @@ public void testRecordDouble() { afterViewData.getAggregationMap().entrySet()) { assertThat(entry.getKey()).containsExactly(TagValue.create("myMethod")); assertThat(entry.getValue()).hasSize(3); - // TODO(songya): update this using assertAggregationDataListEquals() - for (AggregationData aggregate : entry.getValue()) { - StatsTestUtil.assertAggregationDataEquals(aggregate, 5.1, 1L, - StatsTestUtil.removeTrailingZeros(0, 0, 0, 0, 0, 0, 1), null, null, null, null, - TOLERANCE); - } + StatsTestUtil.assertAggregationDataListEquals( + Arrays.asList( + AggregationData.SumData.create(5.1), + AggregationData.CountData.create(1), + AggregationData.HistogramData.create(0, 0, 0, 0, 0, 0, 1)), + entry.getValue(), + TOLERANCE); } } diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java index 4e9f6e2e18..ef6bb656c3 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java @@ -26,6 +26,7 @@ import io.opencensus.stats.AggregationData.SumData; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** Stats test utilities. */ final class StatsTestUtil { @@ -80,91 +81,102 @@ static List createAggregationData( } /** - * Compare the {@code AggregationData} with expected values based on its underlying type. The - * expected values are all optional (nullable). + * Compare the actual and expected AggregationMap within the given tolerance. * - * @param aggregate the {@code AggregationData} to be verified. - * @param sum the expected sum value, if aggregation is a {@code SumData}. - * @param count the expected count value, if aggregation is a {@code CountData}. - * @param bucketCounts the expected bucket counts, if aggregation is a {@code HistogramData}. - * @param min the expected min value, if aggregation is a {@code RangeData}. - * @param max the expected max value, if aggregation is a {@code RangeData}. - * @param mean the expected mean value, if aggregation is a {@code MeanData}. - * @param stdDev the expected standard deviation, if aggregation is a {@code StdDevData}. + * @param expected the expected map. + * @param actual the actual mapping from {@code List} to + * {@code List}. * @param tolerance the tolerance used for {@code double} comparison. */ - static void assertAggregationDataEquals( - AggregationData aggregate, final Double sum, final Long count, final List bucketCounts, - final Double min, final Double max, final Double mean, final Double stdDev, - final double tolerance) { - aggregate.match( - new Function() { - @Override - public Void apply(SumData arg) { - assertThat(arg.getSum()).isWithin(tolerance).of(sum); - return null; - } - }, - new Function() { - @Override - public Void apply(CountData arg) { - assertThat(arg.getCount()).isEqualTo(count); - return null; - } - }, - new Function() { - @Override - public Void apply(HistogramData arg) { - assertThat(removeTrailingZeros(arg.getBucketCounts())).isEqualTo( - removeTrailingZeros(bucketCounts)); - return null; - } - }, - new Function() { - @Override - public Void apply(RangeData arg) { - if (max == Double.NEGATIVE_INFINITY && min == Double.POSITIVE_INFINITY) { - assertThat(arg.getMax()).isNegativeInfinity(); - assertThat(arg.getMin()).isPositiveInfinity(); - } else { - assertThat(arg.getMax()).isWithin(tolerance).of(max); - assertThat(arg.getMin()).isWithin(tolerance).of(min); - } - return null; - } - }, - new Function() { - @Override - public Void apply(MeanData arg) { - assertThat(arg.getMean()).isWithin(tolerance).of(mean); - return null; - } - }, - new Function() { - @Override - public Void apply(StdDevData arg) { - assertThat(arg.getStdDev()).isWithin(tolerance).of(stdDev); - return null; - } - }, - Functions.throwIllegalArgumentException()); + static void assertAggregationMapEquals( + Map, List> actual, + Map, List> expected, + double tolerance) { + assertThat(actual.keySet()).containsExactlyElementsIn(expected.keySet()); + for (List tagValues : actual.keySet()) { + assertAggregationDataListEquals(expected.get(tagValues), actual.get(tagValues), tolerance); + } } /** - * Remove trailing zeros and return a boxed list of {@code Long}. + * Compare the expected and actual list of {@code AggregationData} within the given tolerance. * - * @param longs the input array of primitive type long. - * @return a list of boxed object Long, with trailing zeros removed. + * @param expectedValue the expected list of {@code AggregationData}. + * @param actualValue the actual list of {@code AggregationData}. + * @param tolerance the tolerance used for {@code double} comparison. */ - static List removeTrailingZeros(long... longs) { - if (longs == null) { - return null; + static void assertAggregationDataListEquals( + List expectedValue, List actualValue, + final double tolerance) { + assertThat(expectedValue.size()).isEqualTo(actualValue.size()); + for (int i = 0; i < expectedValue.size(); i++) { + final AggregationData actual = actualValue.get(i); + AggregationData expected = expectedValue.get(i); + expected.match( + new Function() { + @Override + public Void apply(SumData arg) { + assertThat(actual).isInstanceOf(SumData.class); + assertThat(((SumData) actual).getSum()).isWithin(tolerance).of(arg.getSum()); + return null; + } + }, + new Function() { + @Override + public Void apply(CountData arg) { + assertThat(actual).isInstanceOf(CountData.class); + assertThat(((CountData) actual).getCount()).isEqualTo(arg.getCount()); + return null; + } + }, + new Function() { + @Override + public Void apply(HistogramData arg) { + assertThat(actual).isInstanceOf(HistogramData.class); + assertThat(removeTrailingZeros(((HistogramData) actual).getBucketCounts())) + .isEqualTo(removeTrailingZeros(arg.getBucketCounts())); + return null; + } + }, + new Function() { + @Override + public Void apply(RangeData arg) { + assertThat(actual).isInstanceOf(RangeData.class); + assertRangeDataEquals((RangeData) actual, arg, tolerance); + return null; + } + }, + new Function() { + @Override + public Void apply(MeanData arg) { + assertThat(actual).isInstanceOf(MeanData.class); + assertThat(((MeanData) actual).getMean()).isWithin(tolerance).of(arg.getMean()); + return null; + } + }, + new Function() { + @Override + public Void apply(StdDevData arg) { + assertThat(actual).isInstanceOf(StdDevData.class); + assertThat(((StdDevData) actual).getStdDev()).isWithin(tolerance).of(arg.getStdDev()); + return null; + } + }, + Functions.throwIllegalArgumentException()); } - List boxed = new ArrayList(longs.length); - for (long l : longs) { - boxed.add(l); // Boxing. Could use Arrays.stream().boxed().collect after Java 8. + } + + // Compare the expected and actual RangeData within the given tolerance. + private static void assertRangeDataEquals( + RangeData actual, RangeData expected, double tolerance) { + if (expected.getMax() == Double.NEGATIVE_INFINITY + && expected.getMin() == Double.POSITIVE_INFINITY) { + assertThat(actual.getMax()).isNegativeInfinity(); + assertThat(actual.getMin()).isPositiveInfinity(); + } else { + assertThat(actual.getMax()).isWithin(tolerance).of(expected.getMax()); + assertThat(actual.getMin()).isWithin(tolerance).of(expected.getMin()); } - return removeTrailingZeros(boxed); } private static List removeTrailingZeros(List longs) { diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index a2e5732fe0..54fdb7062e 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -13,20 +13,35 @@ package io.opencensus.stats; +import static com.google.common.truth.Truth.assertThat; +import static io.opencensus.stats.StatsTestUtil.createContext; + +import com.google.common.collect.ImmutableMap; +import io.opencensus.common.Duration; +import io.opencensus.common.Timestamp; import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.stats.Aggregation.Count; +import io.opencensus.stats.Aggregation.Histogram; +import io.opencensus.stats.Aggregation.Mean; +import io.opencensus.stats.Aggregation.Range; +import io.opencensus.stats.Aggregation.StdDev; +import io.opencensus.stats.Aggregation.Sum; import io.opencensus.stats.Measure.MeasureDouble; +import io.opencensus.stats.View.Window.Cumulative; +import io.opencensus.stats.View.Window.Interval; +import io.opencensus.stats.ViewData.WindowData.CumulativeData; import io.opencensus.testing.common.TestClock; import java.util.Arrays; -import org.junit.Ignore; +import java.util.Collections; +import java.util.List; import org.junit.Rule; +import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** Tests for {@link ViewManagerImpl}. */ -@Ignore @RunWith(JUnit4.class) -// TODO(songya): re-enable the tests once implementation is done. public class ViewManagerImplTest { @Rule @@ -45,7 +60,6 @@ public class ViewManagerImplTest { private static final String MEASURE_DESCRIPTION = "measure description"; - private static final MeasureDouble MEASURE = Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); @@ -54,13 +68,20 @@ public class ViewManagerImplTest { private static final String VIEW_DESCRIPTION = "view description"; + private static final Cumulative CUMULATIVE = Cumulative.create(); + + private static final double EPSILON = 1e-7; + private static final BucketBoundaries BUCKET_BOUNDARIES = BucketBoundaries.create( Arrays.asList( 0.0, 0.2, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0)); - private static final DistributionAggregation DISTRIBUTION_AGGREGATION_DESCRIPTOR = - DistributionAggregation.create(BUCKET_BOUNDARIES.getBoundaries()); + private static final List AGGREGATIONS = + Collections.unmodifiableList(Arrays.asList( + Sum.create(), Count.create(), Range.create(), + Histogram.create(BUCKET_BOUNDARIES), Mean.create(), + StdDev.create())); private final TestClock clock = TestClock.create(); @@ -71,391 +92,394 @@ public class ViewManagerImplTest { private final ViewManagerImpl viewManager = statsComponent.getViewManager(); private final StatsRecorder statsRecorder = statsComponent.getStatsRecorder(); -// private static DistributionView createDistributionView() { -// return createDistributionView( -// VIEW_NAME, MEASURE, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); -// } -// -// private static DistributionView createDistributionView( -// View.Name name, -// Measure measure, -// DistributionAggregation distributionAggregation, -// List keys) { -// return DistributionView.create(name, VIEW_DESCRIPTION, measure, distributionAggregation, keys); -// } -// -// @Test -// public void testRegisterAndGetView() { -// DistributionView view = createDistributionView(); -// viewManager.registerView(view); -// assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view); -// } -// -// @Test -// public void preventRegisteringIntervalView() { -// View intervalView = -// IntervalView.create( -// VIEW_NAME, -// VIEW_DESCRIPTION, -// MEASURE, -// IntervalAggregation.create(Arrays.asList(Duration.fromMillis(1000))), -// Arrays.asList(KEY)); -// thrown.expect(UnsupportedOperationException.class); -// viewManager.registerView(intervalView); -// } -// -// @Test -// public void allowRegisteringSameViewTwice() { -// DistributionView view = createDistributionView(); -// viewManager.registerView(view); -// viewManager.registerView(view); -// assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view); -// } -// -// @Test -// public void preventRegisteringDifferentViewWithSameName() { -// View view1 = -// DistributionView.create( -// VIEW_NAME, -// "View description.", -// MEASURE, -// DISTRIBUTION_AGGREGATION_DESCRIPTOR, -// Arrays.asList(KEY)); -// viewManager.registerView(view1); -// View view2 = -// DistributionView.create( -// VIEW_NAME, -// "This is a different description.", -// MEASURE, -// DISTRIBUTION_AGGREGATION_DESCRIPTOR, -// Arrays.asList(KEY)); -// try { -// thrown.expect(IllegalArgumentException.class); -// thrown.expectMessage("A different view with the same name is already registered"); -// viewManager.registerView(view2); -// } finally { -// assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view1); -// } -// } -// -// @Test -// public void disallowGettingNonexistentViewData() { -// thrown.expect(IllegalArgumentException.class); -// viewManager.getView(VIEW_NAME); -// } -// -// @Test -// public void testRecord() { -// DistributionView view = -// createDistributionView( -// VIEW_NAME, -// MEASURE, -// DISTRIBUTION_AGGREGATION_DESCRIPTOR, -// Arrays.asList(KEY)); -// clock.setTime(Timestamp.create(1, 2)); -// viewManager.registerView(view); -// StatsContextImpl tags = createContext(factory, KEY, VALUE); -// for (double val : Arrays.asList(10.0, 20.0, 30.0, 40.0)) { -// statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, val).build()); -// } -// clock.setTime(Timestamp.create(3, 4)); -// DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); -// assertThat(viewData.getView()).isEqualTo(view); -// assertThat(viewData.getStart()).isEqualTo(Timestamp.create(1, 2)); -// assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(3, 4)); -// assertDistributionAggregatesEquivalent( -// viewData.getDistributionAggregates(), -// Arrays.asList( -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList(Tag.create(KEY, VALUE)), -// BUCKET_BOUNDARIES, -// Arrays.asList(10.0, 20.0, 30.0, 40.0)))); -// } -// -// @Test -// public void getViewDoesNotClearStats() { -// DistributionView view = -// createDistributionView( -// VIEW_NAME, -// MEASURE, -// DISTRIBUTION_AGGREGATION_DESCRIPTOR, -// Arrays.asList(KEY)); -// clock.setTime(Timestamp.create(10, 0)); -// viewManager.registerView(view); -// StatsContextImpl tags = createContext(factory, KEY, VALUE); -// statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.1).build()); -// clock.setTime(Timestamp.create(11, 0)); -// DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); -// assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(10, 0)); -// assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(11, 0)); -// assertDistributionAggregatesEquivalent( -// viewData1.getDistributionAggregates(), -// Arrays.asList( -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(0.1)))); -// statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.2).build()); -// clock.setTime(Timestamp.create(12, 0)); -// DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME); -// -// // The second view should have the same start time as the first view, and it should include both -// // recorded values: -// assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(10, 0)); -// assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(12, 0)); -// assertDistributionAggregatesEquivalent( -// viewData2.getDistributionAggregates(), -// Arrays.asList( -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList(Tag.create(KEY, VALUE)), -// BUCKET_BOUNDARIES, -// Arrays.asList(0.1, 0.2)))); -// } -// -// @Test -// public void testRecordMultipleTagValues() { -// viewManager.registerView( -// createDistributionView( -// VIEW_NAME, -// MEASURE, -// DISTRIBUTION_AGGREGATION_DESCRIPTOR, -// Arrays.asList(KEY))); -// statsRecorder.record( -// createContext(factory, KEY, VALUE), -// MeasureMap.builder().set(MEASURE, 10.0).build()); -// statsRecorder.record( -// createContext(factory, KEY, VALUE_2), -// MeasureMap.builder().set(MEASURE, 30.0).build()); -// statsRecorder.record( -// createContext(factory, KEY, VALUE_2), -// MeasureMap.builder().set(MEASURE, 50.0).build()); -// DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); -// assertDistributionAggregatesEquivalent( -// viewData.getDistributionAggregates(), -// Arrays.asList( -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(10.0)), -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList(Tag.create(KEY, VALUE_2)), -// BUCKET_BOUNDARIES, -// Arrays.asList(30.0, 50.0)))); -// } -// -// // This test checks that StatsRecorder.record(...) does not throw an exception when no views are -// // registered. -// @Test -// public void allowRecordingWithoutRegisteringMatchingViewData() { -// statsRecorder.record( -// createContext(factory, KEY, VALUE), -// MeasureMap.builder().set(MEASURE, 10).build()); -// } -// -// @Test -// public void testRecordWithEmptyStatsContext() { -// viewManager.registerView( -// createDistributionView( -// VIEW_NAME, -// MEASURE, -// DISTRIBUTION_AGGREGATION_DESCRIPTOR, -// Arrays.asList(KEY))); -// // DEFAULT doesn't have tags, but the view has tag key "KEY". -// statsRecorder.record(factory.getDefault(), -// MeasureMap.builder().set(MEASURE, 10.0).build()); -// DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); -// assertDistributionAggregatesEquivalent( -// viewData.getDistributionAggregates(), -// Arrays.asList( -// StatsTestUtil.createDistributionAggregate( -// // Tag is missing for associated measureValues, should use default tag value -// // "unknown/not set" -// Arrays.asList(Tag.create(KEY, MutableViewData.UNKNOWN_TAG_VALUE)), -// BUCKET_BOUNDARIES, -// // Should record stats with default tag value: "KEY" : "unknown/not set". -// Arrays.asList(10.0)))); -// } -// -// @Test -// public void testRecordWithNonExistentMeasurement() { -// viewManager.registerView( -// createDistributionView( -// VIEW_NAME, -// Measure.MeasureDouble.create(MEASURE_NAME, "measure", MEASURE_UNIT), -// DISTRIBUTION_AGGREGATION_DESCRIPTOR, -// Arrays.asList(KEY))); -// MeasureDouble measure2 = -// Measure.MeasureDouble.create(MEASURE_NAME_2, "measure", MEASURE_UNIT); -// statsRecorder.record(createContext(factory, KEY, VALUE), -// MeasureMap.builder().set(measure2, 10.0).build()); -// DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); -// assertThat(view.getDistributionAggregates()).isEmpty(); -// } -// -// @Test -// public void testRecordWithTagsThatDoNotMatchViewData() { -// viewManager.registerView( -// createDistributionView( -// VIEW_NAME, -// MEASURE, -// DISTRIBUTION_AGGREGATION_DESCRIPTOR, -// Arrays.asList(KEY))); -// statsRecorder.record( -// createContext(factory, TagKey.create("wrong key"), VALUE), -// MeasureMap.builder().set(MEASURE, 10.0).build()); -// statsRecorder.record( -// createContext(factory, TagKey.create("another wrong key"), VALUE), -// MeasureMap.builder().set(MEASURE, 50.0).build()); -// DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); -// assertDistributionAggregatesEquivalent( -// view.getDistributionAggregates(), -// Arrays.asList( -// StatsTestUtil.createDistributionAggregate( -// // Won't record the unregistered tag key, will use default tag instead: -// // "KEY" : "unknown/not set". -// Arrays.asList(Tag.create(KEY, MutableViewData.UNKNOWN_TAG_VALUE)), -// BUCKET_BOUNDARIES, -// // Should record stats with default tag value: "KEY" : "unknown/not set". -// Arrays.asList(10.0, 50.0)))); -// } -// -// @Test -// public void testViewDataWithMultipleTagKeys() { -// TagKey key1 = TagKey.create("Key-1"); -// TagKey key2 = TagKey.create("Key-2"); -// viewManager.registerView( -// createDistributionView( -// VIEW_NAME, -// MEASURE, -// DISTRIBUTION_AGGREGATION_DESCRIPTOR, -// Arrays.asList(key1, key2))); -// statsRecorder.record( -// createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), -// MeasureMap.builder().set(MEASURE, 1.1).build()); -// statsRecorder.record( -// createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v20")), -// MeasureMap.builder().set(MEASURE, 2.2).build()); -// statsRecorder.record( -// createContext(factory, key1, TagValue.create("v2"), key2, TagValue.create("v10")), -// MeasureMap.builder().set(MEASURE, 3.3).build()); -// statsRecorder.record( -// createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), -// MeasureMap.builder().set(MEASURE, 4.4).build()); -// DistributionViewData view = (DistributionViewData) viewManager.getView(VIEW_NAME); -// assertDistributionAggregatesEquivalent( -// view.getDistributionAggregates(), -// Arrays.asList( -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList( -// Tag.create(key1, TagValue.create("v1")), -// Tag.create(key2, TagValue.create("v10"))), -// BUCKET_BOUNDARIES, -// Arrays.asList(1.1, 4.4)), -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList( -// Tag.create(key1, TagValue.create("v1")), -// Tag.create(key2, TagValue.create("v20"))), -// BUCKET_BOUNDARIES, -// Arrays.asList(2.2)), -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList( -// Tag.create(key1, TagValue.create("v2")), -// Tag.create(key2, TagValue.create("v10"))), -// BUCKET_BOUNDARIES, -// Arrays.asList(3.3)))); -// } -// -// @Test -// public void testMultipleViewDatasSameMeasure() { -// View view1 = -// createDistributionView( -// VIEW_NAME, -// MEASURE, -// DISTRIBUTION_AGGREGATION_DESCRIPTOR, -// Arrays.asList(KEY)); -// View view2 = -// createDistributionView( -// VIEW_NAME_2, -// MEASURE, -// DISTRIBUTION_AGGREGATION_DESCRIPTOR, -// Arrays.asList(KEY)); -// clock.setTime(Timestamp.create(1, 1)); -// viewManager.registerView(view1); -// clock.setTime(Timestamp.create(2, 2)); -// viewManager.registerView(view2); -// statsRecorder.record( -// createContext(factory, KEY, VALUE), -// MeasureMap.builder().set(MEASURE, 5.0).build()); -// List expectedAggs = -// Arrays.asList( -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(5.0))); -// clock.setTime(Timestamp.create(3, 3)); -// DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); -// clock.setTime(Timestamp.create(4, 4)); -// DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME_2); -// assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(1, 1)); -// assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(3, 3)); -// assertDistributionAggregatesEquivalent(viewData1.getDistributionAggregates(), expectedAggs); -// assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(2, 2)); -// assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(4, 4)); -// assertDistributionAggregatesEquivalent(viewData2.getDistributionAggregates(), expectedAggs); -// } -// -// @Test -// public void testMultipleViewsDifferentMeasures() { -// MeasureDouble measure1 = -// Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); -// MeasureDouble measure2 = -// Measure.MeasureDouble.create(MEASURE_NAME_2, MEASURE_DESCRIPTION, MEASURE_UNIT); -// View view1 = -// createDistributionView( -// VIEW_NAME, measure1, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); -// View view2 = -// createDistributionView( -// VIEW_NAME_2, measure2, DISTRIBUTION_AGGREGATION_DESCRIPTOR, Arrays.asList(KEY)); -// clock.setTime(Timestamp.create(1, 0)); -// viewManager.registerView(view1); -// clock.setTime(Timestamp.create(2, 0)); -// viewManager.registerView(view2); -// statsRecorder.record( -// createContext(factory, KEY, VALUE), -// MeasureMap.builder().set(measure1, 1.1).set(measure2, 2.2).build()); -// clock.setTime(Timestamp.create(3, 0)); -// DistributionViewData viewData1 = (DistributionViewData) viewManager.getView(VIEW_NAME); -// clock.setTime(Timestamp.create(4, 0)); -// DistributionViewData viewData2 = (DistributionViewData) viewManager.getView(VIEW_NAME_2); -// assertThat(viewData1.getStart()).isEqualTo(Timestamp.create(1, 0)); -// assertThat(viewData1.getEnd()).isEqualTo(Timestamp.create(3, 0)); -// assertDistributionAggregatesEquivalent( -// viewData1.getDistributionAggregates(), -// Arrays.asList( -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(1.1)))); -// assertThat(viewData2.getStart()).isEqualTo(Timestamp.create(2, 0)); -// assertThat(viewData2.getEnd()).isEqualTo(Timestamp.create(4, 0)); -// assertDistributionAggregatesEquivalent( -// viewData2.getDistributionAggregates(), -// Arrays.asList( -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList(Tag.create(KEY, VALUE)), BUCKET_BOUNDARIES, Arrays.asList(2.2)))); -// } -// -// @Test -// public void testGetDistributionViewDataWithoutBucketBoundaries() { -// View view = -// createDistributionView( -// VIEW_NAME, MEASURE, DistributionAggregation.create(), -// Arrays.asList(KEY)); -// clock.setTime(Timestamp.create(1, 0)); -// viewManager.registerView(view); -// statsRecorder.record( -// createContext(factory, KEY, VALUE), -// MeasureMap.builder().set(MEASURE, 1.1).build()); -// clock.setTime(Timestamp.create(3, 0)); -// DistributionViewData viewData = (DistributionViewData) viewManager.getView(VIEW_NAME); -// assertThat(viewData.getStart()).isEqualTo(Timestamp.create(1, 0)); -// assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(3, 0)); -// assertDistributionAggregatesEquivalent( -// viewData.getDistributionAggregates(), -// Arrays.asList( -// StatsTestUtil.createDistributionAggregate( -// Arrays.asList(Tag.create(KEY, VALUE)), Arrays.asList(1.1)))); -// } + private static View createCumulativeView() { + return createCumulativeView( + VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(KEY)); + } + + private static View createCumulativeView( + View.Name name, + Measure measure, + List aggregations, + List keys) { + return View.create( + name, VIEW_DESCRIPTION, measure, aggregations, keys, CUMULATIVE); + } + + @Test + public void testRegisterAndGetCumulativeView() { + View view = createCumulativeView(); + viewManager.registerView(view); + assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view); + } + + @Test + public void preventRegisteringIntervalView() { + View intervalView = + View.create( + VIEW_NAME, + VIEW_DESCRIPTION, + MEASURE, + AGGREGATIONS, + Arrays.asList(KEY), + Interval.create(Duration.create(60, 0))); + thrown.expect(UnsupportedOperationException.class); + viewManager.registerView(intervalView); + } + + @Test + public void allowRegisteringSameViewTwice() { + View view = createCumulativeView(); + viewManager.registerView(view); + viewManager.registerView(view); + assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view); + } + + @Test + public void preventRegisteringDifferentViewWithSameName() { + View view1 = + View.create( + VIEW_NAME, + "View description.", + MEASURE, + AGGREGATIONS, + Arrays.asList(KEY), + CUMULATIVE); + viewManager.registerView(view1); + View view2 = + View.create( + VIEW_NAME, + "This is a different description.", + MEASURE, + AGGREGATIONS, + Arrays.asList(KEY), + CUMULATIVE); + try { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("A different view with the same name is already registered"); + viewManager.registerView(view2); + } finally { + assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view1); + } + } + + @Test + public void disallowGettingNonexistentViewData() { + thrown.expect(IllegalArgumentException.class); + viewManager.getView(VIEW_NAME); + } + + @Test + public void testRecord() { + View view = + createCumulativeView( + VIEW_NAME, + MEASURE, + AGGREGATIONS, + Arrays.asList(KEY)); + clock.setTime(Timestamp.create(1, 2)); + viewManager.registerView(view); + StatsContextImpl tags = createContext(factory, KEY, VALUE); + double[] values = {10.0, 20.0, 30.0, 40.0}; + for (double val : values) { + statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, val).build()); + } + clock.setTime(Timestamp.create(3, 4)); + ViewData viewData = viewManager.getView(VIEW_NAME); + assertThat(viewData.getView()).isEqualTo(view); + assertThat(viewData.getWindowData()).isEqualTo( + CumulativeData.create(Timestamp.create(1, 2), Timestamp.create(3, 4))); + StatsTestUtil.assertAggregationMapEquals( + viewData.getAggregationMap(), + ImmutableMap.of( + Arrays.asList(VALUE), + StatsTestUtil.createAggregationData(AGGREGATIONS, values)), + EPSILON); + } + + @Test + public void getViewDoesNotClearStats() { + View view = + createCumulativeView( + VIEW_NAME, + MEASURE, + AGGREGATIONS, + Arrays.asList(KEY)); + clock.setTime(Timestamp.create(10, 0)); + viewManager.registerView(view); + StatsContextImpl tags = createContext(factory, KEY, VALUE); + statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.1).build()); + clock.setTime(Timestamp.create(11, 0)); + ViewData viewData1 = viewManager.getView(VIEW_NAME); + assertThat(viewData1.getWindowData()).isEqualTo( + CumulativeData.create(Timestamp.create(10, 0), Timestamp.create(11, 0))); + StatsTestUtil.assertAggregationMapEquals( + viewData1.getAggregationMap(), + ImmutableMap.of( + Arrays.asList(VALUE), + StatsTestUtil.createAggregationData(AGGREGATIONS, 0.1)), + EPSILON); + + statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.2).build()); + clock.setTime(Timestamp.create(12, 0)); + ViewData viewData2 = viewManager.getView(VIEW_NAME); + + // The second view should have the same start time as the first view, and it should include both + // recorded values: + assertThat(viewData2.getWindowData()).isEqualTo( + CumulativeData.create(Timestamp.create(10, 0), Timestamp.create(12, 0))); + StatsTestUtil.assertAggregationMapEquals( + viewData2.getAggregationMap(), + ImmutableMap.of( + Arrays.asList(VALUE), + StatsTestUtil.createAggregationData(AGGREGATIONS, 0.1, 0.2)), + EPSILON); + } + + @Test + public void testRecordMultipleTagValues() { + viewManager.registerView( + createCumulativeView( + VIEW_NAME, + MEASURE, + AGGREGATIONS, + Arrays.asList(KEY))); + statsRecorder.record( + createContext(factory, KEY, VALUE), + MeasureMap.builder().set(MEASURE, 10.0).build()); + statsRecorder.record( + createContext(factory, KEY, VALUE_2), + MeasureMap.builder().set(MEASURE, 30.0).build()); + statsRecorder.record( + createContext(factory, KEY, VALUE_2), + MeasureMap.builder().set(MEASURE, 50.0).build()); + ViewData viewData = viewManager.getView(VIEW_NAME); + StatsTestUtil.assertAggregationMapEquals( + viewData.getAggregationMap(), + ImmutableMap.of( + Arrays.asList(VALUE), + StatsTestUtil.createAggregationData(AGGREGATIONS, 10.0), + Arrays.asList(VALUE_2), + StatsTestUtil.createAggregationData(AGGREGATIONS, 30.0, 50.0)), + EPSILON); + } + + // This test checks that StatsRecorder.record(...) does not throw an exception when no views are + // registered. + @Test + public void allowRecordingWithoutRegisteringMatchingViewData() { + statsRecorder.record( + createContext(factory, KEY, VALUE), + MeasureMap.builder().set(MEASURE, 10).build()); + } + + @Test + public void testRecordWithEmptyStatsContext() { + viewManager.registerView( + createCumulativeView( + VIEW_NAME, + MEASURE, + AGGREGATIONS, + Arrays.asList(KEY))); + // DEFAULT doesn't have tags, but the view has tag key "KEY". + statsRecorder.record(factory.getDefault(), + MeasureMap.builder().set(MEASURE, 10.0).build()); + ViewData viewData = viewManager.getView(VIEW_NAME); + StatsTestUtil.assertAggregationMapEquals( + viewData.getAggregationMap(), + ImmutableMap.of( + // Tag is missing for associated measureValues, should use default tag value + // "unknown/not set". + Arrays.asList(MutableViewData.UNKNOWN_TAG_VALUE), + // Should record stats with default tag value: "KEY" : "unknown/not set". + StatsTestUtil.createAggregationData(AGGREGATIONS, 10.0)), + EPSILON); + } + + @Test + public void testRecordWithNonExistentMeasurement() { + viewManager.registerView( + createCumulativeView( + VIEW_NAME, + Measure.MeasureDouble.create(MEASURE_NAME, "measure", MEASURE_UNIT), + AGGREGATIONS, + Arrays.asList(KEY))); + MeasureDouble measure2 = + Measure.MeasureDouble.create(MEASURE_NAME_2, "measure", MEASURE_UNIT); + statsRecorder.record(createContext(factory, KEY, VALUE), + MeasureMap.builder().set(measure2, 10.0).build()); + ViewData view = viewManager.getView(VIEW_NAME); + assertThat(view.getAggregationMap()).isEmpty(); + } + + @Test + public void testRecordWithTagsThatDoNotMatchViewData() { + viewManager.registerView( + createCumulativeView( + VIEW_NAME, + MEASURE, + AGGREGATIONS, + Arrays.asList(KEY))); + statsRecorder.record( + createContext(factory, TagKey.create("wrong key"), VALUE), + MeasureMap.builder().set(MEASURE, 10.0).build()); + statsRecorder.record( + createContext(factory, TagKey.create("another wrong key"), VALUE), + MeasureMap.builder().set(MEASURE, 50.0).build()); + ViewData viewData = viewManager.getView(VIEW_NAME); + StatsTestUtil.assertAggregationMapEquals( + viewData.getAggregationMap(), + ImmutableMap.of( + // Won't record the unregistered tag key, for missing registered keys will use default + // tag value : "unknown/not set". + Arrays.asList(MutableViewData.UNKNOWN_TAG_VALUE), + // Should record stats with default tag value: "KEY" : "unknown/not set". + StatsTestUtil.createAggregationData(AGGREGATIONS, 10.0, 50.0)), + EPSILON); + } + + @Test + public void testViewDataWithMultipleTagKeys() { + TagKey key1 = TagKey.create("Key-1"); + TagKey key2 = TagKey.create("Key-2"); + viewManager.registerView( + createCumulativeView( + VIEW_NAME, + MEASURE, + AGGREGATIONS, + Arrays.asList(key1, key2))); + statsRecorder.record( + createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), + MeasureMap.builder().set(MEASURE, 1.1).build()); + statsRecorder.record( + createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v20")), + MeasureMap.builder().set(MEASURE, 2.2).build()); + statsRecorder.record( + createContext(factory, key1, TagValue.create("v2"), key2, TagValue.create("v10")), + MeasureMap.builder().set(MEASURE, 3.3).build()); + statsRecorder.record( + createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), + MeasureMap.builder().set(MEASURE, 4.4).build()); + ViewData viewData = viewManager.getView(VIEW_NAME); + StatsTestUtil.assertAggregationMapEquals( + viewData.getAggregationMap(), + ImmutableMap.of( + Arrays.asList(TagValue.create("v1"), TagValue.create("v10")), + StatsTestUtil.createAggregationData(AGGREGATIONS, 1.1, 4.4), + Arrays.asList(TagValue.create("v1"), TagValue.create("v20")), + StatsTestUtil.createAggregationData(AGGREGATIONS, 2.2), + Arrays.asList(TagValue.create("v2"), TagValue.create("v10")), + StatsTestUtil.createAggregationData(AGGREGATIONS, 3.3)), + EPSILON); + } + + @Test + public void testMultipleViewSameMeasure() { + View view1 = + createCumulativeView( + VIEW_NAME, + MEASURE, + AGGREGATIONS, + Arrays.asList(KEY)); + View view2 = + createCumulativeView( + VIEW_NAME_2, + MEASURE, + AGGREGATIONS, + Arrays.asList(KEY)); + clock.setTime(Timestamp.create(1, 1)); + viewManager.registerView(view1); + clock.setTime(Timestamp.create(2, 2)); + viewManager.registerView(view2); + statsRecorder.record( + createContext(factory, KEY, VALUE), + MeasureMap.builder().set(MEASURE, 5.0).build()); + clock.setTime(Timestamp.create(3, 3)); + ViewData viewData1 = viewManager.getView(VIEW_NAME); + clock.setTime(Timestamp.create(4, 4)); + ViewData viewData2 = viewManager.getView(VIEW_NAME_2); + assertThat(viewData1.getWindowData()).isEqualTo( + CumulativeData.create(Timestamp.create(1, 1), Timestamp.create(3, 3))); + StatsTestUtil.assertAggregationMapEquals( + viewData1.getAggregationMap(), + ImmutableMap.of( + Arrays.asList(VALUE), + StatsTestUtil.createAggregationData(AGGREGATIONS, 5.0)), + EPSILON); + assertThat(viewData2.getWindowData()).isEqualTo( + CumulativeData.create(Timestamp.create(2, 2), Timestamp.create(4, 4))); + StatsTestUtil.assertAggregationMapEquals( + viewData2.getAggregationMap(), + ImmutableMap.of( + Arrays.asList(VALUE), + StatsTestUtil.createAggregationData(AGGREGATIONS, 5.0)), + EPSILON); + } + + @Test + public void testMultipleViewsDifferentMeasures() { + MeasureDouble measure1 = + Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); + MeasureDouble measure2 = + Measure.MeasureDouble.create(MEASURE_NAME_2, MEASURE_DESCRIPTION, MEASURE_UNIT); + View view1 = + createCumulativeView( + VIEW_NAME, measure1, AGGREGATIONS, Arrays.asList(KEY)); + View view2 = + createCumulativeView( + VIEW_NAME_2, measure2, AGGREGATIONS, Arrays.asList(KEY)); + clock.setTime(Timestamp.create(1, 0)); + viewManager.registerView(view1); + clock.setTime(Timestamp.create(2, 0)); + viewManager.registerView(view2); + statsRecorder.record( + createContext(factory, KEY, VALUE), + MeasureMap.builder().set(measure1, 1.1).set(measure2, 2.2).build()); + clock.setTime(Timestamp.create(3, 0)); + ViewData viewData1 = viewManager.getView(VIEW_NAME); + clock.setTime(Timestamp.create(4, 0)); + ViewData viewData2 = viewManager.getView(VIEW_NAME_2); + assertThat(viewData1.getWindowData()).isEqualTo( + CumulativeData.create(Timestamp.create(1, 0), Timestamp.create(3, 0))); + StatsTestUtil.assertAggregationMapEquals( + viewData1.getAggregationMap(), + ImmutableMap.of( + Arrays.asList(VALUE), + StatsTestUtil.createAggregationData(AGGREGATIONS, 1.1)), + EPSILON); + assertThat(viewData2.getWindowData()).isEqualTo( + CumulativeData.create(Timestamp.create(2, 0), Timestamp.create(4, 0))); + StatsTestUtil.assertAggregationMapEquals( + viewData2.getAggregationMap(), + ImmutableMap.of( + Arrays.asList(VALUE), + StatsTestUtil.createAggregationData(AGGREGATIONS, 2.2)), + EPSILON); + } + + @Test + public void testGetCumulativeViewDataWithoutBucketBoundaries() { + List aggregationsNoHistogram = Arrays.asList( + Sum.create(), Count.create(), Mean.create(), Range.create(), StdDev.create()); + View view = + createCumulativeView( + VIEW_NAME, MEASURE, + aggregationsNoHistogram, + Arrays.asList(KEY)); + clock.setTime(Timestamp.create(1, 0)); + viewManager.registerView(view); + statsRecorder.record( + createContext(factory, KEY, VALUE), + MeasureMap.builder().set(MEASURE, 1.1).build()); + clock.setTime(Timestamp.create(3, 0)); + ViewData viewData = viewManager.getView(VIEW_NAME); + assertThat(viewData.getWindowData()).isEqualTo( + CumulativeData.create(Timestamp.create(1, 0), Timestamp.create(3, 0))); + StatsTestUtil.assertAggregationMapEquals( + viewData.getAggregationMap(), + ImmutableMap.of( + Arrays.asList(VALUE), + StatsTestUtil.createAggregationData(aggregationsNoHistogram, 1.1)), + EPSILON); + } } From c06ffca52c8a662bf277997bf6c6af78880c6c7f Mon Sep 17 00:00:00 2001 From: songy23 Date: Thu, 13 Jul 2017 17:09:58 -0700 Subject: [PATCH 0380/1581] Remove outdated data structures. --- .../io/opencensus/stats/Distribution.java | 179 -------------- .../stats/DistributionAggregate.java | 181 -------------- .../stats/DistributionAggregation.java | 77 ------ .../opencensus/stats/IntervalAggregate.java | 103 -------- .../opencensus/stats/IntervalAggregation.java | 86 ------- .../opencensus/stats/MutableDistribution.java | 233 ------------------ .../stats/DistributionAggregateTest.java | 91 ------- .../stats/DistributionAggregationTest.java | 59 ----- .../io/opencensus/stats/DistributionTest.java | 86 ------- .../stats/IntervalAggregateTest.java | 65 ----- .../stats/IntervalAggregationTest.java | 77 ------ .../stats/MutableDistributionTest.java | 154 ------------ 12 files changed, 1391 deletions(-) delete mode 100644 core/src/main/java/io/opencensus/stats/Distribution.java delete mode 100644 core/src/main/java/io/opencensus/stats/DistributionAggregate.java delete mode 100644 core/src/main/java/io/opencensus/stats/DistributionAggregation.java delete mode 100644 core/src/main/java/io/opencensus/stats/IntervalAggregate.java delete mode 100644 core/src/main/java/io/opencensus/stats/IntervalAggregation.java delete mode 100644 core/src/main/java/io/opencensus/stats/MutableDistribution.java delete mode 100644 core/src/test/java/io/opencensus/stats/DistributionAggregateTest.java delete mode 100644 core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java delete mode 100644 core/src/test/java/io/opencensus/stats/DistributionTest.java delete mode 100644 core/src/test/java/io/opencensus/stats/IntervalAggregateTest.java delete mode 100644 core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java delete mode 100644 core/src/test/java/io/opencensus/stats/MutableDistributionTest.java diff --git a/core/src/main/java/io/opencensus/stats/Distribution.java b/core/src/main/java/io/opencensus/stats/Distribution.java deleted file mode 100644 index a2806727e9..0000000000 --- a/core/src/main/java/io/opencensus/stats/Distribution.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import com.google.auto.value.AutoValue; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * A distribution contains summary statistics for a population of values and, optionally, a - * histogram representing the distribution of those values across a specified set of histogram - * buckets. - * - *

The bucket boundaries for that histogram are described by {@link BucketBoundaries}, which - * defines {@code BucketBoundaries.getBoundaries().size() + 1 (= N)} buckets. The boundaries for - * bucket index i are: - * - *

    - *
  • [-infinity, bounds[i]) for i == 0 - *
  • [bounds[i-1], bounds[i]) for 0 < i < N-1 - *
  • [bounds[i-1], +infinity) for i == N-1 - *
- * - *

i.e. an underflow bucket (number 0), zero or more finite buckets (1 through N - 2, and an - * overflow bucket (N - 1), with inclusive lower bounds and exclusive upper bounds. - * - *

Note: If N = 1, there are no finite buckets and the single bucket is both the overflow and - * underflow bucket. - * - *

Although not forbidden, it is generally a bad idea to include non-finite values (infinities or - * NaNs) in the population of values, as this will render derived values (e.g. {@code mean}) - * meaningless. - */ - -@Immutable -@AutoValue -abstract class Distribution { - - Distribution() {} - - /** - * Constructs a {@link Distribution} with the same contents as a {@link MutableDistribution}. - * - * @param distribution the {@code MutableDistribution} to be copied. - * @return a {@code Distribution} with the same contents as the given {@link MutableDistribution}. - */ - static Distribution create(MutableDistribution distribution) { - long[] counts = distribution.getInternalBucketCountsArray(); - List bucketCounts = counts != null ? longArrayToImmutableList(counts) : null; - return new AutoValue_Distribution( - distribution.getCount(), - distribution.getSum(), - distribution.getSumOfSquaredDeviations(), - Range.create(distribution.getRange()), - distribution.getBucketBoundaries(), - bucketCounts); - } - - private static List longArrayToImmutableList(long[] array) { - List boxedBucketCounts = new ArrayList(array.length); - for (long bucketCount : array) { - boxedBucketCounts.add(bucketCount); - } - return Collections.unmodifiableList(boxedBucketCounts); - } - - /** - * The number of values in the population. Must be non-negative. - * - * @return The number of values in the population. - */ - abstract long getCount(); - - /** - * The arithmetic mean of the values in the population. If {@link #getCount()} is zero then this - * value will be NaN. - * - * @return The arithmetic mean of all values in the population. - */ - final double getMean() { - return getSum() / getCount(); - } - - /** - * The sum of the values in the population. If {@link #getCount()} is zero then this value will - * also be zero. - * - * @return The sum of values in the population. - */ - abstract double getSum(); - - /** - * The sum of squared deviations from the mean for values in the population. For values x_i this - * is Sum[i=1..n]((x_i - mean)^2) - * - *

If {@link #getCount()} is zero then this value will also be zero. - * - * @return The sum of squared deviations from the mean for values in the population. - */ - abstract double getSumOfSquaredDeviations(); - - /** - * The range of the population values. If {@link #getCount()} is zero then the returned range - * will contain the "impossible" range [+Inf, -Inf]. - * - * @return The {code Range} representing the range of population values. - */ - abstract Range getRange(); - - /** - * The optional histogram bucket boundaries used by this {@code MutableDistribution}. - * - * @return The bucket boundaries, or {@code null} if there is no histogram. - */ - @Nullable - abstract BucketBoundaries getBucketBoundaries(); - - /** - * A Distribution may optionally contain a histogram of the values in the population. The - * histogram is given in {@link #getBucketCounts()} as counts of values that fall into one of a - * sequence of non-overlapping buckets, described by {@link BucketBoundaries}. The sum of the - * values in {@link #getBucketCounts()} must equal the value in {@link #getCount()}. - * - *

Bucket counts are given in order under the numbering scheme described above (the underflow - * bucket has number 0; the finite buckets, if any, have numbers 1 through N-2; the overflow - * bucket has number N-1). - * - *

The size of {@link #getBucketCounts()} must be no greater than N as defined in {@link - * BucketBoundaries}. - * - *

Any suffix of trailing buckets containing only zero may be omitted. - * - *

{@link #getBucketCounts()} will return null iff the associated {@link BucketBoundaries} is - * null. - * - * @return The count of population values in each histogram bucket. - */ - @Nullable - abstract List getBucketCounts(); - - /** Describes a range of population values. */ - @Immutable - @AutoValue - abstract static class Range { - - /** Constructs a {@code Range} from a {@link MutableDistribution.Range}. */ - static Range create(MutableDistribution.Range range) { - return new AutoValue_Distribution_Range(range.getMin(), range.getMax()); - } - - /** - * The minimum of the population values. - * - * @return The minimum of the population values. - */ - abstract double getMin(); - - /** - * The maximum of the population values. - * - * @return The maximum of the population values. - */ - abstract double getMax(); - } -} diff --git a/core/src/main/java/io/opencensus/stats/DistributionAggregate.java b/core/src/main/java/io/opencensus/stats/DistributionAggregate.java deleted file mode 100644 index a2eabb0430..0000000000 --- a/core/src/main/java/io/opencensus/stats/DistributionAggregate.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import com.google.auto.value.AutoValue; -import com.google.common.base.Preconditions; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -// TODO(aveitch) The below class should be changed to use a Distribution as a private member. -/** - * An aggregation of data based on distributions. - * - *

A distribution contains summary statistics for a population of values and, optionally, a - * histogram representing the distribution of those values across a specified set of histogram - * buckets, as defined in {@link DistributionAggregation#getBucketBoundaries()}. - * - *

Although not forbidden, it is generally a bad idea to include non-finite values (infinities or - * NaNs) in the population of values, as this will render the {@code mean} meaningless. - */ -@Immutable -@AutoValue -public abstract class DistributionAggregate { - /** - * Constructs a {@code DistributionAggregate} without bucket counts. - * - * @param count the number of values in the population. It must be non-negative. - * @param mean the arithmetic mean of the values. If {@code count} is zero then this value must - * also be zero. - * @param sum the sum of the values. If {@code count} is zero then this value must also be zero. - * @param range the range of the values. - * @param tags the {@code Tag}s associated with the {@code DistributionAggregate}. - * @return a {@code DistributionAggregate} without bucket counts. - */ - public static DistributionAggregate create( - long count, double mean, double sum, Range range, List tags) { - return createInternal(count, mean, sum, range, tags, null); - } - - /** - * Constructs a {@code DistributionAggregate} with bucket counts. - * - * @param count the number of values in the population. It must be non-negative. - * @param mean the arithmetic mean of the values. If {@code count} is zero then this value must - * also be zero. - * @param sum the sum of the values. If {@code count} is zero then this value must also be zero. - * @param range the range of the values. - * @param tags the {@code Tag}s associated with the {@code DistributionAggregate}. - * @param bucketCounts the bucket counts for the histogram associated with the {@code - * DistributionAggregate}. - * @return a {@code DistributionAggregate} with bucket counts. - */ - public static DistributionAggregate create( - long count, double mean, double sum, Range range, List tags, List bucketCounts) { - return createInternal( - count, - mean, - sum, - range, - tags, - Collections.unmodifiableList(new ArrayList(bucketCounts))); - } - - private static DistributionAggregate createInternal( - long count, double mean, double sum, Range range, List tags, List bucketCounts) { - Preconditions.checkArgument(count >= 0, "Count must be non-negative."); - if (count == 0) { - Preconditions.checkArgument(mean == 0, "Mean must be 0 when the count is 0."); - Preconditions.checkArgument(sum == 0, "Sum must be 0 when the count is 0."); - } - return new AutoValue_DistributionAggregate(count, mean, sum, range, tags, bucketCounts); - } - - /** - * Returns the number of values in the population. - * - * @return the number of values in the population. - */ - public abstract long getCount(); - - /** - * Returns the arithmetic mean of the values in the population. - * - * @return the arithmetic mean of the values in the population. - */ - public abstract double getMean(); - - /** - * Returns the sum of the values in the population. - * - * @return the sum of the values in the population. - */ - public abstract double getSum(); - - /** - * Returns the range of the population values. If {@link #getCount()} is zero then the returned - * range is implementation-dependent. - * - * @return the range of the population values. - */ - public abstract Range getRange(); - - /** - * Returns the {@code Tag}s associated with this {@code DistributionAggregate}. - * - * @return the {@code Tag}s associated with this {@code DistributionAggregate}. - */ - public abstract List getTags(); - - /** - * Returns the bucket counts, or {@code null} if this {@code DistributionAggregate}'s associated - * {@link DistributionAggregation} has no buckets. - * - *

A Distribution may contain a histogram of the values in the population. The histogram is - * given in {@link #getBucketCounts()} as counts of values that fall into one of a sequence of - * non-overlapping buckets, described by {@link - * DistributionAggregation#getBucketBoundaries()}. The sum of the values in {@link - * #getBucketCounts()} must equal the value in {@link #getCount()}. - * - *

Bucket counts are given in order under the numbering scheme described in the link above (the - * underflow bucket has number 0; the finite buckets, if any, have numbers 1 through N-2; the - * overflow bucket has number N-1). - * - *

The size of {@link #getBucketCounts()} must be no greater than N as defined in {@link - * DistributionAggregation#getBucketBoundaries()}. - * - *

Any suffix of trailing buckets containing only zero may be omitted. - * - *

{@link #getBucketCounts()} will return null iff the associated {@link - * DistributionAggregation#getBucketBoundaries()} returns null. - * - * @return the bucket counts, or {@code null} if this {@code DistributionAggregate}'s associated - * {@link DistributionAggregation} has no buckets. - */ - @Nullable - public abstract List getBucketCounts(); - - /** The range of a population's values. */ - @Immutable - @AutoValue - public abstract static class Range { - /** - * Returns a {@code Range} with the given bounds. - * - * @param min the minimum of the population values. - * @param max the maximum of the population values. - * @return a {@code Range} with the given bounds. - */ - public static Range create(double min, double max) { - return new AutoValue_DistributionAggregate_Range(min, max); - } - - /** - * Returns the minimum of the population values. - * - * @return the minimum of the population values. - */ - public abstract double getMin(); - - /** - * Returns the maximum of the population values. - * - * @return the maximum of the population values. - */ - public abstract double getMax(); - } -} diff --git a/core/src/main/java/io/opencensus/stats/DistributionAggregation.java b/core/src/main/java/io/opencensus/stats/DistributionAggregation.java deleted file mode 100644 index 120fc27cc1..0000000000 --- a/core/src/main/java/io/opencensus/stats/DistributionAggregation.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import com.google.auto.value.AutoValue; -import java.util.List; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * Describes data aggregations based on distributions. - * - *

A distribution aggregation may optionally contain a histogram of the values in the - * population. The bucket boundaries for that histogram are described by - * {@link BucketBoundaries}, which defines {@code BucketBoundaries.getBoundaries.size() + 1 (= N)} - * buckets. The boundaries for bucket index i are: - *

    - *
  • [-infinity, bounds[i]) for i == 0 - *
  • [bounds[i-1], bounds[i]) for 0 < i < N-1 - *
  • [bounds[i-1], +infinity) for i == N-1 - *
- * i.e. an underflow bucket (number 0), zero or more finite buckets (1 through N - 2, and an - * overflow bucket (N - 1), with inclusive lower bounds and exclusive upper bounds. - * - *

Note: If N = 1, there are no finite buckets and the single bucket is both the overflow - * and underflow bucket. - */ -@Immutable -@AutoValue -public abstract class DistributionAggregation { - /** - * Constructs a new {@link DistributionAggregation} with the optional - * histogram bucket boundaries. - */ - public static DistributionAggregation create(List bucketBoundaries) { - return createInternal(BucketBoundaries.create(bucketBoundaries)); - } - - /** - * Constructs a new {@link DistributionAggregation} without the optional - * histogram bucket boundaries. - */ - public static DistributionAggregation create() { - return createInternal(null); - } - - private static DistributionAggregation createInternal( - @Nullable BucketBoundaries bucketBoundaries) { - return new AutoValue_DistributionAggregation(bucketBoundaries); - } - - /** - * The optional histogram bucket boundaries for a distribution. - * - *

Note: The returned list is unmodifiable, attempts to update it will throw an - * UnsupportedOperationException. - */ - @Nullable - public List getBucketBoundaries() { - BucketBoundaries bucketBoundaries = getBucketBoundariesObject(); - return bucketBoundaries == null ? null : bucketBoundaries.getBoundaries(); - } - - @Nullable - abstract BucketBoundaries getBucketBoundariesObject(); -} diff --git a/core/src/main/java/io/opencensus/stats/IntervalAggregate.java b/core/src/main/java/io/opencensus/stats/IntervalAggregate.java deleted file mode 100644 index b8d2549cbc..0000000000 --- a/core/src/main/java/io/opencensus/stats/IntervalAggregate.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import io.opencensus.common.Duration; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Contains summary stats over various time intervals. - */ -public final class IntervalAggregate { - /** - * Constructs new {@link IntervalAggregate}. - * TODO(dpo): Determine what we should do it intervals is empty. - */ - public static final IntervalAggregate create(List tags, List intervals) { - return new IntervalAggregate(tags, intervals); - } - - /** - * {@link Tag}s associated with this aggregation. - * - *

Note: The returned list is unmodifiable, attempts to update it will throw an - * UnsupportedOperationException. - */ - public final List getTags() { - return tags; - } - - /** - * Sequence of intervals for this aggregation. - */ - public List getIntervals() { - return intervals; - } - - private final List tags; - private final List intervals; - - private IntervalAggregate(List tags, List intervals) { - this.tags = tags; - this.intervals = Collections.unmodifiableList(new ArrayList(intervals)); - } - - /** - * Summary statistic over a single time interval. - */ - public static final class Interval { - /** - * Constructs a new {@link Interval}. - * - *

Note: {@code intervalSize} must be positive otherwise behavior is unspecified. - */ - public static Interval create(Duration intervalSize, double count, double sum) { - return new Interval(intervalSize, count, sum); - } - - /** - * The interval duration. - */ - public Duration getIntervalSize() { - return intervalSize; - } - - /** - * The number of measurements in this interval. - */ - public double getCount() { - return count; - } - - /** - * The cumulative sum of measurements in this interval. - */ - public double getSum() { - return sum; - } - - private final Duration intervalSize; - private final double count; - private final double sum; - - private Interval(Duration intervalSize, double count, double sum) { - this.intervalSize = intervalSize; - this.count = count; - this.sum = sum; - } - } -} diff --git a/core/src/main/java/io/opencensus/stats/IntervalAggregation.java b/core/src/main/java/io/opencensus/stats/IntervalAggregation.java deleted file mode 100644 index 0562969b3c..0000000000 --- a/core/src/main/java/io/opencensus/stats/IntervalAggregation.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import io.opencensus.common.Duration; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Describes data aggregations based on time intervals. - */ -public final class IntervalAggregation { - /** - * Constructs a new {@link IntervalAggregation}. - * - *

The given {@code numSubIntervals} must be in the range [2, 20], see - * {@link #getNumSubIntervals()} for more details. - * - *

The given {@code intervalSizes} must have at least one entry. - */ - public static IntervalAggregation create( - int numSubIntervals, List intervalSizes) { - if (numSubIntervals < 2 || numSubIntervals > 20) { - throw new IllegalArgumentException( - "The number of subintervals must be in the range [2, 20]."); - } - if (intervalSizes.isEmpty()) { - throw new IllegalArgumentException("There must be at least one interval size."); - } - return new IntervalAggregation( - numSubIntervals, - Collections.unmodifiableList(new ArrayList(intervalSizes))); - } - - /** - * Constructs a new {@link IntervalAggregation} with the number of sub intervals set - * to the default value of 5. - */ - public static IntervalAggregation create(List intervalSizes) { - return create(5, intervalSizes); - } - - /** - * The number of sub intervals. - * - *

The number of internal sub-intervals to use when collecting stats for each interval. The - * max error in interval measurements will be approximately 1/getNumSubIntervals() - * (although in practice, this will only be approached in the presence of very large and bursty - * workload changes), and underlying memory usage will be roughly proportional to the value of - * this field. Must be in the range [2, 20]. A value of 5 will be used if this is unspecified. - */ - public int getNumSubIntervals() { - return numSubIntervals; - } - - /** - * The time intervals to record for the aggregation. - * - *

Note: The returned list is unmodifiable, attempts to update it will throw an - * UnsupportedOperationException. - */ - public List getIntervalSizes() { - return intervalSizes; - } - - private final int numSubIntervals; - private final List intervalSizes; - - private IntervalAggregation(int numSubIntervals, List intervalSizes) { - this.numSubIntervals = numSubIntervals; - this.intervalSizes = intervalSizes; - } -} diff --git a/core/src/main/java/io/opencensus/stats/MutableDistribution.java b/core/src/main/java/io/opencensus/stats/MutableDistribution.java deleted file mode 100644 index 4cf93c4d0b..0000000000 --- a/core/src/main/java/io/opencensus/stats/MutableDistribution.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import javax.annotation.Nullable; - -/** Mutable version of {@link Distribution}. */ -final class MutableDistribution { - private long count = 0; // The number of values in the population. - private double sum = 0.0; // The sum of the values in the population. - private double mean = 0.0; // The mean of the values in the population - private double sumOfSquaredDeviations = 0.0; // The sum of squares of deviation from mean - private Range range = Range.create(); // Range of values in the population. - - @Nullable - private final BucketBoundaries bucketBoundaries; // Histogram boundaries; null means no histogram - - @Nullable private final long[] bucketCounts; // Counts for each histogram bucket - - /** - * Constructs a new, empty {@link MutableDistribution}. - * - * @return a new, empty {@code MutableDistribution}. - */ - static final MutableDistribution create() { - return new MutableDistribution(null); - } - - /** - * Constructs a new {@link MutableDistribution} with specified {@code bucketBoundaryList}. - * - * @param bucketBoundaries the boundaries for the buckets in the underlying {@code - * MutableDistribution}. - * @return a new, empty {@code MutableDistribution} with the specified boundaries. - */ - static final MutableDistribution create(BucketBoundaries bucketBoundaries) { - checkNotNull(bucketBoundaries, "bucketBoundaries Object should not be null."); - return new MutableDistribution(bucketBoundaries); - } - - // Returns true if the distribution has histogram buckets. - // TODO(sebright): Decide whether to expose this method. - private boolean hasBuckets() { - return (bucketBoundaries != null); - } - - // Construct a new MutableDistribution with optional bucket boundaries. - private MutableDistribution(@Nullable BucketBoundaries bucketBoundaries) { - this.bucketBoundaries = bucketBoundaries; - bucketCounts = - bucketBoundaries == null ? null : new long[bucketBoundaries.getBoundaries().size() + 1]; - } - - /** - * Returns the number of values in the population. Must be non-negative. - * - * @return The number of values in the population. - */ - long getCount() { - return count; - } - - /** - * The arithmetic mean of the values in the population. If {@link #getCount()} is zero then this - * value will be NaN. - * - * @return The arithmetic mean of all values in the population. - */ - double getMean() { - return (count == 0) ? Double.NaN : mean; - } - - /** - * The sum of the values in the population. If {@link #getCount()} is zero then this value will - * also be zero. - * - * @return The sum of values in the population. - */ - double getSum() { - return sum; - } - - /** - * The sum of squared deviations from the mean for values in the population. For values x_i this - * is Sum[i=1..n]((x_i - mean)^2) - * - *

If {@link #getCount()} is zero then this value will also be zero. - * - *

Computed using Welfords method (see - * https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance, or Knuth, "The Art of - * Computer Programming", Vol. 2, page 323, 3rd edition) - * - * @return The sum of squared deviations from the mean for values in the population. - */ - double getSumOfSquaredDeviations() { - return sumOfSquaredDeviations; - } - - /** - * The range of the population values. If {@link #getCount()} is zero then this returned range is - * implementation-dependent. - * - * @return The {code Range} representing the range of population values. - */ - Range getRange() { - return range; - } - - /** - * The optional histogram bucket boundaries used by this {@code MutableDistribution}. - * - * @return The bucket boundaries, or {@code null} if there is no histogram. - */ - @Nullable - BucketBoundaries getBucketBoundaries() { - return bucketBoundaries; - } - - /** - * The bucket counts of the optional histogram. - * - * @see Distribution#getBucketCounts() - * @return The count of population values in each histogram bucket, or {@code null} if there is no - * histogram. - */ - @Nullable - List getBucketCounts() { - if (hasBuckets()) { - List boxedBucketCounts = new ArrayList(bucketCounts.length); - for (long bucketCount : bucketCounts) { - boxedBucketCounts.add(bucketCount); - } - return boxedBucketCounts; - } - return null; - } - - @Nullable - long[] getInternalBucketCountsArray() { - return hasBuckets() ? Arrays.copyOf(bucketCounts, bucketCounts.length) : null; - } - - // Increment the appropriate bucket count. hasBuckets() MUST be true. - private void putIntoBucket(double value) { - for (int i = 0; i < bucketBoundaries.getBoundaries().size(); i++) { - if (value < bucketBoundaries.getBoundaries().get(i)) { - bucketCounts[i]++; - return; - } - } - bucketCounts[bucketCounts.length - 1]++; - } - - /** - * Put a new value into the distribution. - * - * @param value new value to be added to population - */ - void add(double value) { - count++; - sum += value; - double deltaFromMean = value - mean; - mean += deltaFromMean / count; - double deltaFromMean2 = value - mean; - sumOfSquaredDeviations += deltaFromMean * deltaFromMean2; - range.add(value); - if (hasBuckets()) { - putIntoBucket(value); - } - } - - /** Mutable version of {@code Distribution.Range}. */ - static final class Range { - // Initial "impossible" values, that will get reset as soon as first value is added. - private double min = Double.POSITIVE_INFINITY; - private double max = Double.NEGATIVE_INFINITY; - - /** Construct a new, empty {@code Range}. */ - static final Range create() { - return new Range(); - } - - /** - * The minimum of the population values. - * - * @return The minimum of the population values. - */ - double getMin() { - return min; - } - - /** - * The maximum of the population values. - * - * @return The maximum of the population values. - */ - double getMax() { - return max; - } - - /** - * Put a new value into the Range. Sets min and max values if appropriate. - * - * @param value the new value - */ - void add(double value) { - if (value < min) { - min = value; - } - if (value > max) { - max = value; - } - } - - private Range() {} - } -} diff --git a/core/src/test/java/io/opencensus/stats/DistributionAggregateTest.java b/core/src/test/java/io/opencensus/stats/DistributionAggregateTest.java deleted file mode 100644 index 5ace8204f3..0000000000 --- a/core/src/test/java/io/opencensus/stats/DistributionAggregateTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.testing.EqualsTester; -import io.opencensus.stats.DistributionAggregate.Range; -import java.util.Arrays; -import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests for class {@link DistributionAggregate}. - */ -@RunWith(JUnit4.class) -public final class DistributionAggregateTest { - - @Test - public void testDistributionAggregateWithOutBuckets() { - DistributionAggregate aggr = DistributionAggregate.create(10, 5.0, 30.0, - Range.create(1.0, 5.0), TAGS); - - assertThat(aggr.getCount()).isEqualTo(10); - assertThat(aggr.getMean()).isEqualTo(5.0); - assertThat(aggr.getSum()).isEqualTo(30.0); - assertThat(aggr.getRange().getMin()).isEqualTo(1.0); - assertThat(aggr.getRange().getMax()).isEqualTo(5.0); - assertThat(aggr.getTags()).hasSize(TAGS.size()); - for (int i = 0; i < aggr.getTags().size(); i++) { - assertThat(aggr.getTags().get(i)).isEqualTo(TAGS.get(i)); - } - assertThat(aggr.getBucketCounts()).isNull(); - } - - @Test - public void testDistributionAggregateWithBuckets() { - List buckets = Arrays.asList(2L, 2L, 2L, 2L, 2L); - DistributionAggregate aggr = DistributionAggregate.create(10, 5.0, 30.0, - Range.create(1.0, 5.0), TAGS, buckets); - - assertThat(aggr.getCount()).isEqualTo(10); - assertThat(aggr.getMean()).isEqualTo(5.0); - assertThat(aggr.getSum()).isEqualTo(30.0); - assertThat(aggr.getRange().getMin()).isEqualTo(1.0); - assertThat(aggr.getRange().getMax()).isEqualTo(5.0); - assertThat(aggr.getBucketCounts()).isNotNull(); - assertThat(aggr.getBucketCounts()).hasSize(buckets.size()); - assertThat(aggr.getTags()).hasSize(TAGS.size()); - for (int i = 0; i < aggr.getTags().size(); i++) { - assertThat(aggr.getTags().get(i)).isEqualTo(TAGS.get(i)); - } - for (int i = 0; i < aggr.getBucketCounts().size(); i++) { - assertThat(aggr.getBucketCounts().get(i)).isEqualTo(buckets.get(i)); - } - } - - @Test - public void testDistributionAggregateEquals() { - List buckets = Arrays.asList(1L, 2L, 3L); - new EqualsTester() - .addEqualityGroup( - DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS), - DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS)) - .addEqualityGroup( - DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS, buckets), - DistributionAggregate.create(10, 5.0, 30.0, Range.create(1.0, 5.0), TAGS, buckets)) - .testEquals(); - } - - private static final TagKey K1 = TagKey.create("k1"); - private static final TagKey K2 = TagKey.create("k2"); - - private static final TagValue V1 = TagValue.create("v1"); - private static final TagValue V2 = TagValue.create("v2"); - - private static final List TAGS = Arrays.asList(Tag.create(K1, V1), Tag.create(K2, V2)); -} diff --git a/core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java b/core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java deleted file mode 100644 index 8d9ac23eed..0000000000 --- a/core/src/test/java/io/opencensus/stats/DistributionAggregationTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.testing.EqualsTester; -import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests for {@link DistributionAggregation} - */ -@RunWith(JUnit4.class) -public final class DistributionAggregationTest { - @Test - public void testDistributionAggregationEmpty() { - DistributionAggregation d = DistributionAggregation.create(); - assertThat(d.getBucketBoundaries()).isNull(); - } - - @Test - public void testDistributionAggregation() { - Double[] buckets = new Double[] { 0.1, 2.2, 33.3 }; - DistributionAggregation d = - DistributionAggregation.create(Arrays.asList(buckets)); - assertThat(d.getBucketBoundaries()).isNotNull(); - assertThat(d.getBucketBoundaries()).hasSize(buckets.length); - for (int i = 0; i < buckets.length; i++) { - assertThat(d.getBucketBoundaries().get(i)) - .isWithin(0.00000001).of(buckets[i]); - } - } - - @Test - public void testDistributionAggregationEquals() { - new EqualsTester() - .addEqualityGroup( - DistributionAggregation.create(Arrays.asList(1.0, 2.0, 5.0)), - DistributionAggregation.create(Arrays.asList(1.0, 2.0, 5.0))) - .addEqualityGroup( - DistributionAggregation.create(), - DistributionAggregation.create()) - .testEquals(); - } -} diff --git a/core/src/test/java/io/opencensus/stats/DistributionTest.java b/core/src/test/java/io/opencensus/stats/DistributionTest.java deleted file mode 100644 index f6c2ccb0da..0000000000 --- a/core/src/test/java/io/opencensus/stats/DistributionTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.testing.EqualsTester; -import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link io.opencensus.stats.Distribution}. */ -@RunWith(JUnit4.class) -public class DistributionTest { - private static final double TOLERANCE = 1e-6; - - @Test - public void testDistributionWithoutBoundaries() { - MutableDistribution mDistribution = MutableDistribution.create(); - mDistribution.add(1.0); - mDistribution.add(2.0); - Distribution distribution = Distribution.create(mDistribution); - assertThat(distribution.getBucketBoundaries()).isNull(); - assertThat(distribution.getBucketCounts()).isNull(); - assertThat(distribution.getCount()).isEqualTo(2L); - assertThat(distribution.getMean()).isWithin(TOLERANCE).of(1.5); - assertThat(distribution.getSum()).isWithin(TOLERANCE).of(3.0); - assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(1.0); - assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(2.0); - } - - @Test - public void testDistributionWithBoundaries() { - BucketBoundaries boundaries = BucketBoundaries.create(Arrays.asList(-10.0, 10.0)); - MutableDistribution mDistribution = MutableDistribution.create(boundaries); - mDistribution.add(2.0); - mDistribution.add(100.0); - mDistribution.add(-6); - Distribution distribution = Distribution.create(mDistribution); - assertThat(distribution.getBucketBoundaries()).isEqualTo(boundaries); - assertThat(distribution.getBucketCounts()).containsExactly(0L, 2L, 1L).inOrder(); - assertThat(distribution.getCount()).isEqualTo(3L); - assertThat(distribution.getMean()).isWithin(TOLERANCE).of(32.0); - assertThat(distribution.getSum()).isWithin(TOLERANCE).of(96.0); - assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(-6.0); - assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(100.0); - } - - @Test(expected = NullPointerException.class) - public void disallowCreatingDistributionFromNull() { - Distribution.create(null); - } - - @Test(expected = NullPointerException.class) - public void disallowCreatingRangeFromNull() { - Distribution.Range.create(null); - } - - @Test - public void testDistributionEquals() { - BucketBoundaries boundaries = BucketBoundaries.create(Arrays.asList(-10.0, 10.0)); - MutableDistribution mDistribution = MutableDistribution.create(boundaries); - mDistribution.add(1); - mDistribution.add(-1); - Distribution distribution1 = Distribution.create(mDistribution); - Distribution distribution2 = Distribution.create(mDistribution); - mDistribution.add(0); - Distribution distribution3 = Distribution.create(mDistribution); - new EqualsTester() - .addEqualityGroup(distribution1, distribution2) - .addEqualityGroup(distribution3) - .testEquals(); - } -} diff --git a/core/src/test/java/io/opencensus/stats/IntervalAggregateTest.java b/core/src/test/java/io/opencensus/stats/IntervalAggregateTest.java deleted file mode 100644 index 9d0210eb17..0000000000 --- a/core/src/test/java/io/opencensus/stats/IntervalAggregateTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import io.opencensus.common.Duration; -import io.opencensus.stats.IntervalAggregate.Interval; -import java.util.Arrays; -import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests for class {@link IntervalAggregate}. - */ -@RunWith(JUnit4.class) -public final class IntervalAggregateTest { - @Test - public void testIntervalAggregate() { - List intervals = Arrays.asList( - Interval.create(Duration.fromMillis(10), 100.0, 1000.0), - Interval.create(Duration.fromMillis(11), 101.0, 1001.0)); - IntervalAggregate aggr = IntervalAggregate.create(TAGS, intervals); - - assertThat(aggr.getTags()).hasSize(TAGS.size()); - for (int i = 0; i < aggr.getTags().size(); i++) { - assertThat(aggr.getTags().get(i)).isEqualTo(TAGS.get(i)); - } - assertThat(aggr.getIntervals()).hasSize(intervals.size()); - for (int i = 0; i < aggr.getIntervals().size(); i++) { - assertThat(aggr.getIntervals().get(i)).isEqualTo(intervals.get(i)); - } - } - - @Test - public void testInterval() { - Duration duration = Duration.fromMillis(10); - Interval interval = Interval.create(duration, 100.0, 1000.0); - - assertThat(interval.getIntervalSize()).isEqualTo(duration); - assertThat(interval.getCount()).isWithin(0.00000001).of(100.0); - assertThat(interval.getSum()).isWithin(0.00000001).of(1000.0); - } - - private static final TagKey K1 = TagKey.create("k1"); - private static final TagKey K2 = TagKey.create("k2"); - - private static final TagValue V1 = TagValue.create("v1"); - private static final TagValue V2 = TagValue.create("v2"); - - private static final List TAGS = Arrays.asList(Tag.create(K1, V1), Tag.create(K2, V2)); -} diff --git a/core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java b/core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java deleted file mode 100644 index 0c7029ed8e..0000000000 --- a/core/src/test/java/io/opencensus/stats/IntervalAggregationTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import io.opencensus.common.Duration; -import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests for {@link IntervalAggregation} - */ -@RunWith(JUnit4.class) -public final class IntervalAggregationTest { - @Test - public void testIntervalAggregation() { - Duration[] intervals = - new Duration[] { Duration.fromMillis(1), Duration.fromMillis(22), Duration.fromMillis(333)}; - IntervalAggregation intervalAggregation = - IntervalAggregation.create(12, Arrays.asList(intervals)); - assertThat(intervalAggregation.getNumSubIntervals()).isEqualTo(12); - assertThat(intervalAggregation.getIntervalSizes()).isNotNull(); - assertThat(intervalAggregation.getIntervalSizes()).hasSize(intervals.length); - for (int i = 0; i < intervals.length; i++) { - assertThat(intervalAggregation.getIntervalSizes().get(i)).isEqualTo(intervals[i]); - } - } - - @Test - public void testIntervalAggregationWithDefaultNumSubIntervals() { - assertThat( - IntervalAggregation.create( - Arrays.asList(Duration.fromMillis(1))).getNumSubIntervals()) - .isEqualTo(5); - } - - @Test - public void testIntervalAggregationNumSubIntervalsRange() { - assertThat( - IntervalAggregation.create( - 2, Arrays.asList(Duration.fromMillis(1))).getNumSubIntervals()) - .isEqualTo(2); - assertThat( - IntervalAggregation.create( - 20, Arrays.asList(Duration.fromMillis(1))).getNumSubIntervals()) - .isEqualTo(20); - } - - @Test(expected = IllegalArgumentException.class) - public void testIntervalAggregationLowNumSubIntervals() { - IntervalAggregation.create(1, Arrays.asList(Duration.fromMillis(1))); - } - - @Test(expected = IllegalArgumentException.class) - public void testIntervalAggregationHighNumSubIntervals() { - IntervalAggregation.create(21, Arrays.asList(Duration.fromMillis(1))); - } - - @Test(expected = IllegalArgumentException.class) - public void testIntervalAggregationEmptyIntervalSizes() { - IntervalAggregation.create(Arrays.asList(new Duration[] { })); - } -} diff --git a/core/src/test/java/io/opencensus/stats/MutableDistributionTest.java b/core/src/test/java/io/opencensus/stats/MutableDistributionTest.java deleted file mode 100644 index 029de76db0..0000000000 --- a/core/src/test/java/io/opencensus/stats/MutableDistributionTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import java.util.Arrays; -import java.util.List; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link io.opencensus.stats.MutableDistribution}. */ -@RunWith(JUnit4.class) -public class MutableDistributionTest { - private static final double TOLERANCE = 1e-5; - - @Rule public final ExpectedException thrown = ExpectedException.none(); - - @Test - public void testEmptyDistribution() { - MutableDistribution empty = MutableDistribution.create(); - assertThat(empty.getCount()).isEqualTo(0); - assertThat(empty.getSum()).isWithin(TOLERANCE).of(0.0); - assertThat(empty.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(0.0); - assertThat(empty.getMean()).isNaN(); - assertThat(empty.getRange().getMin()).isPositiveInfinity(); - assertThat(empty.getRange().getMax()).isNegativeInfinity(); - assertThat(empty.getBucketCounts()).isNull(); - } - - @Test - public void testEmptyDistributionWithBuckets() { - List buckets = Arrays.asList(0.0, 1.0, 2.0); - MutableDistribution empty = MutableDistribution.create(BucketBoundaries.create(buckets)); - assertThat(empty.getCount()).isEqualTo(0); - assertThat(empty.getSum()).isWithin(TOLERANCE).of(0.0); - assertThat(empty.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(0.0); - assertThat(empty.getMean()).isNaN(); - assertThat(empty.getBucketCounts()).hasSize(4); - for (Long element : empty.getBucketCounts()) { - assertThat(element).isEqualTo(0); - } - } - - @Test - public void testNullBoundaries() throws Exception { - thrown.expect(NullPointerException.class); - MutableDistribution.create(null); - } - - @Test - public void testUnsortedBoundaries() throws Exception { - List buckets = Arrays.asList(0.0, 1.0, 1.0); - thrown.expect(IllegalArgumentException.class); - MutableDistribution.create(BucketBoundaries.create(buckets)); - } - - @Test - public void testNoBoundaries() { - List buckets = Arrays.asList(); - MutableDistribution noBoundaries = MutableDistribution.create(BucketBoundaries.create(buckets)); - assertThat(noBoundaries.getBucketCounts()).hasSize(1); - assertThat(noBoundaries.getBucketCounts().get(0)).isEqualTo(0); - } - - @Test - public void testDistribution() { - MutableDistribution distribution = MutableDistribution.create(); - distribution.add(1.0); - assertThat(distribution.getCount()).isEqualTo(1); - assertThat(distribution.getSum()).isWithin(TOLERANCE).of(1.0); - assertThat(distribution.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(0.0); - assertThat(distribution.getMean()).isWithin(TOLERANCE).of(1.0); - assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(1.0); - assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(1.0); - distribution.add(1.0); - assertThat(distribution.getCount()).isEqualTo(2); - assertThat(distribution.getSum()).isWithin(TOLERANCE).of(2.0); - assertThat(distribution.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(0.0); - assertThat(distribution.getMean()).isWithin(TOLERANCE).of(1.0); - assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(1.0); - assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(1.0); - distribution.add(7.0); - assertThat(distribution.getCount()).isEqualTo(3); - assertThat(distribution.getSum()).isWithin(TOLERANCE).of(9.0); - assertThat(distribution.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(24.0); - assertThat(distribution.getMean()).isWithin(TOLERANCE).of(3.0); - assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(1.0); - assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(7.0); - distribution.add(-4.6); - assertThat(distribution.getCount()).isEqualTo(4); - assertThat(distribution.getSum()).isWithin(TOLERANCE).of(4.4); - assertThat(distribution.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(67.32); - assertThat(distribution.getMean()).isWithin(TOLERANCE).of(1.1); - assertThat(distribution.getRange().getMin()).isWithin(TOLERANCE).of(-4.6); - assertThat(distribution.getRange().getMax()).isWithin(TOLERANCE).of(7.0); - assertThat(distribution.getBucketCounts()).isNull(); - } - - @Test - public void testDistributionWithOneBoundary() { - List buckets = Arrays.asList(5.0); - MutableDistribution distribution = MutableDistribution.create(BucketBoundaries.create(buckets)); - assertThat(distribution.getBucketCounts()).hasSize(2); - for (Long element : distribution.getBucketCounts()) { - assertThat(element).isEqualTo(0); - } - distribution.add(1.4); - distribution.add(5.0); - distribution.add(-17.0); - distribution.add(123.45); - assertThat(distribution.getCount()).isEqualTo(4); - assertThat(distribution.getBucketCounts().get(0)).isEqualTo(2); - assertThat(distribution.getBucketCounts().get(1)).isEqualTo(2); - } - - @Test - public void testDistributionWithBoundaries() { - List buckets = Arrays.asList(-1.0, 2.0, 5.0, 20.0); - MutableDistribution distribution = MutableDistribution.create(BucketBoundaries.create(buckets)); - assertThat(distribution.getBucketCounts()).hasSize(5); - for (Long element : distribution.getBucketCounts()) { - assertThat(element).isEqualTo(0); - } - distribution.add(-50.0); - distribution.add(-20.0); - distribution.add(4.0); - distribution.add(4.0); - distribution.add(4.999999); - distribution.add(5.0); - distribution.add(5.000001); - distribution.add(123.45); - assertThat(distribution.getCount()).isEqualTo(8); - assertThat(distribution.getBucketCounts().get(0)).isEqualTo(2); - assertThat(distribution.getBucketCounts().get(1)).isEqualTo(0); - assertThat(distribution.getBucketCounts().get(2)).isEqualTo(3); - assertThat(distribution.getBucketCounts().get(3)).isEqualTo(2); - assertThat(distribution.getBucketCounts().get(4)).isEqualTo(1); - } -} From 9ee885d93a4b40f03a83353bba1a03c7e6cfa4a3 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 11 Aug 2017 14:49:49 -0700 Subject: [PATCH 0381/1581] Enable checkstyle for tests in stats package. --- build.gradle | 5 --- .../io/opencensus/stats/MeasureMapTest.java | 2 +- .../java/io/opencensus/stats/MeasureTest.java | 4 +- .../stats/RpcViewConstantsTest.java | 8 ++-- .../java/io/opencensus/stats/StatsTest.java | 12 +++--- .../java/io/opencensus/stats/TagKeyTest.java | 4 +- .../java/io/opencensus/stats/TagTest.java | 4 +- .../io/opencensus/stats/TagValueTest.java | 4 +- .../io/opencensus/stats/ViewDataTest.java | 43 ++++++++++++------- .../java/io/opencensus/stats/ViewTest.java | 2 +- .../stats/StatsContextFactoryTest.java | 2 +- .../io/opencensus/stats/StatsContextTest.java | 16 +++---- .../io/opencensus/stats/StatsTestUtil.java | 6 +-- .../opencensus/stats/ViewManagerImplTest.java | 8 ++-- 14 files changed, 58 insertions(+), 62 deletions(-) diff --git a/build.gradle b/build.gradle index 6b9f1dda98..98cbc78b6b 100644 --- a/build.gradle +++ b/build.gradle @@ -165,11 +165,6 @@ subprojects { configProperties["rootDir"] = rootDir } - checkstyleTest { - // TODO(sebright): Fix style errors in stats tests. - excludes = ["io/opencensus/stats/**"] - } - // Disable checkstyle if no java8. checkstyleMain.enabled = JavaVersion.current().isJava8Compatible() checkstyleTest.enabled = JavaVersion.current().isJava8Compatible() diff --git a/core/src/test/java/io/opencensus/stats/MeasureMapTest.java b/core/src/test/java/io/opencensus/stats/MeasureMapTest.java index 0dcfc5ecfa..68ec7a3704 100644 --- a/core/src/test/java/io/opencensus/stats/MeasureMapTest.java +++ b/core/src/test/java/io/opencensus/stats/MeasureMapTest.java @@ -23,7 +23,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link MeasureMap} */ +/** Tests for {@link MeasureMap}. */ @RunWith(JUnit4.class) public class MeasureMapTest { diff --git a/core/src/test/java/io/opencensus/stats/MeasureTest.java b/core/src/test/java/io/opencensus/stats/MeasureTest.java index e3b35608d4..738d83c25f 100644 --- a/core/src/test/java/io/opencensus/stats/MeasureTest.java +++ b/core/src/test/java/io/opencensus/stats/MeasureTest.java @@ -23,9 +23,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link Measure} - */ +/** Tests for {@link Measure}. */ @RunWith(JUnit4.class) public final class MeasureTest { diff --git a/core/src/test/java/io/opencensus/stats/RpcViewConstantsTest.java b/core/src/test/java/io/opencensus/stats/RpcViewConstantsTest.java index ab5fc3deec..2702320e2d 100644 --- a/core/src/test/java/io/opencensus/stats/RpcViewConstantsTest.java +++ b/core/src/test/java/io/opencensus/stats/RpcViewConstantsTest.java @@ -13,6 +13,8 @@ package io.opencensus.stats; +import static com.google.common.truth.Truth.assertThat; + import io.opencensus.common.Duration; import io.opencensus.stats.Aggregation.Count; import io.opencensus.stats.Aggregation.Histogram; @@ -23,11 +25,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import static com.google.common.truth.Truth.assertThat; - -/** - * Test for {@link RpcViewConstants}. - */ +/** Test for {@link RpcViewConstants}. */ @RunWith(JUnit4.class) public final class RpcViewConstantsTest { diff --git a/core/src/test/java/io/opencensus/stats/StatsTest.java b/core/src/test/java/io/opencensus/stats/StatsTest.java index 423df07ef0..8db2ac395e 100644 --- a/core/src/test/java/io/opencensus/stats/StatsTest.java +++ b/core/src/test/java/io/opencensus/stats/StatsTest.java @@ -44,12 +44,12 @@ public Class loadClass(String name) { public void loadStatsManager_IgnoresMissingClasses() { assertThat( Stats.loadStatsComponent( - new ClassLoader() { - @Override - public Class loadClass(String name) throws ClassNotFoundException { - throw new ClassNotFoundException(); - } - }) + new ClassLoader() { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + throw new ClassNotFoundException(); + } + }) .getClass() .getName()) .isEqualTo("io.opencensus.stats.StatsComponent$NoopStatsComponent"); diff --git a/core/src/test/java/io/opencensus/stats/TagKeyTest.java b/core/src/test/java/io/opencensus/stats/TagKeyTest.java index e412b53c77..2398a3c7af 100644 --- a/core/src/test/java/io/opencensus/stats/TagKeyTest.java +++ b/core/src/test/java/io/opencensus/stats/TagKeyTest.java @@ -22,9 +22,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link TagKey} - */ +/** Tests for {@link TagKey}. */ @RunWith(JUnit4.class) public final class TagKeyTest { @Test diff --git a/core/src/test/java/io/opencensus/stats/TagTest.java b/core/src/test/java/io/opencensus/stats/TagTest.java index 4ab7a201b8..05135b15ce 100644 --- a/core/src/test/java/io/opencensus/stats/TagTest.java +++ b/core/src/test/java/io/opencensus/stats/TagTest.java @@ -20,9 +20,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link Tag} - */ +/** Tests for {@link Tag}. */ @RunWith(JUnit4.class) public final class TagTest { @Test diff --git a/core/src/test/java/io/opencensus/stats/TagValueTest.java b/core/src/test/java/io/opencensus/stats/TagValueTest.java index d69a18d69c..e53bda139f 100644 --- a/core/src/test/java/io/opencensus/stats/TagValueTest.java +++ b/core/src/test/java/io/opencensus/stats/TagValueTest.java @@ -22,9 +22,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link TagValue} - */ +/** Tests for {@link TagValue}. */ @RunWith(JUnit4.class) public final class TagValueTest { @Test diff --git a/core/src/test/java/io/opencensus/stats/ViewDataTest.java b/core/src/test/java/io/opencensus/stats/ViewDataTest.java index 42db54c1a7..19ef3ef2a6 100644 --- a/core/src/test/java/io/opencensus/stats/ViewDataTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewDataTest.java @@ -83,38 +83,38 @@ public void testIntervalViewData() { @Test public void testViewDataEquals() { - View dView = + View cumulativeView = View.create(name, description, measure, AGGREGATIONS, tagKeys, CUMULATIVE); - View iView = + View intervalView = View.create(name, description, measure, AGGREGATIONS, tagKeys, INTERVAL_HOUR); new EqualsTester() .addEqualityGroup( ViewData.create( - dView, ENTRIES, + cumulativeView, ENTRIES, CumulativeData.create( Timestamp.fromMillis(1000), Timestamp.fromMillis(2000))), ViewData.create( - dView, + cumulativeView, ENTRIES, CumulativeData.create( Timestamp.fromMillis(1000), Timestamp.fromMillis(2000)))) .addEqualityGroup( ViewData.create( - dView, + cumulativeView, ENTRIES, CumulativeData.create( Timestamp.fromMillis(1000), Timestamp.fromMillis(3000)))) .addEqualityGroup( ViewData.create( - iView, ENTRIES, + intervalView, ENTRIES, IntervalData.create(Timestamp.fromMillis(2000))), ViewData.create( - iView, ENTRIES, + intervalView, ENTRIES, IntervalData.create(Timestamp.fromMillis(2000)))) .addEqualityGroup( ViewData.create( - iView, Collections., List>emptyMap(), + intervalView, Collections., List>emptyMap(), IntervalData.create(Timestamp.fromMillis(2000)))) .testEquals(); } @@ -205,14 +205,25 @@ public void preventStartTimeLaterThanEndTime() { private static final List AGGREGATIONS = Collections.unmodifiableList(Arrays.asList( Sum.create(), Count.create(), Range.create(), Histogram.create(BUCKET_BOUNDARIES), Mean.create(), StdDev.create())); - - private static final ImmutableMap, List> ENTRIES = ImmutableMap.of( - Arrays.asList(V1, V2), - Arrays.asList(SumData.create(0), CountData.create(1), HistogramData.create(1, 0, 0, 0, 0), - RangeData.create(0, 0), MeanData.create(0), StdDevData.create(0)), - Arrays.asList(V10, V20), - Arrays.asList(SumData.create(50), CountData.create(2), HistogramData.create(0, 0, 2, 0, 0), - RangeData.create(25, 25), MeanData.create(25), StdDevData.create(0))); + + private static final ImmutableMap, List> ENTRIES = + ImmutableMap.of( + Arrays.asList(V1, V2), + Arrays.asList( + SumData.create(0), + CountData.create(1), + HistogramData.create(1, 0, 0, 0, 0), + RangeData.create(0, 0), + MeanData.create(0), + StdDevData.create(0)), + Arrays.asList(V10, V20), + Arrays.asList( + SumData.create(50), + CountData.create(2), + HistogramData.create(0, 0, 2, 0, 0), + RangeData.create(25, 25), + MeanData.create(25), + StdDevData.create(0))); // name private final View.Name name = View.Name.create("test-view"); diff --git a/core/src/test/java/io/opencensus/stats/ViewTest.java b/core/src/test/java/io/opencensus/stats/ViewTest.java index 0ead370dd2..0255c4918e 100644 --- a/core/src/test/java/io/opencensus/stats/ViewTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewTest.java @@ -27,7 +27,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link View} */ +/** Tests for {@link View}. */ @RunWith(JUnit4.class) public final class ViewTest { @Test diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java index f900412a29..df06e2a212 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java @@ -88,7 +88,6 @@ public void testDeserializeValueTypeString() throws Exception { @Test public void testDeserializeMultipleString() throws Exception { sampleTags.put(TagKey.create("Key2"), TagValue.create("String2")); - StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byteArrayOutputStream.write(StatsSerializer.VERSION_ID); @@ -99,6 +98,7 @@ public void testDeserializeMultipleString() throws Exception { StatsContext actual = testDeserialize( new ByteArrayInputStream(byteArrayOutputStream.toByteArray())); + StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); assertThat(actual).isEqualTo(expected); } diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java index d6f2c586e2..a81857d571 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java @@ -186,6 +186,14 @@ public void testRoundtripSerialization() throws Exception { testRoundtripSerialization(defaultStatsContext.with(K_EMPTY, V_EMPTY)); } + private void testRoundtripSerialization(StatsContext expected) throws Exception { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + expected.serialize(output); + ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); + StatsContext actual = factory.deserialize(input); + assertThat(actual).isEqualTo(expected); + } + // Tests for Object overrides. @Test @@ -238,14 +246,6 @@ private void testSerialize(Tag... tags) throws IOException { assertThat(possibleOutputs).contains(actual.toString()); } - private void testRoundtripSerialization(StatsContext expected) throws Exception { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - expected.serialize(output); - ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); - StatsContext actual = factory.deserialize(input); - assertThat(actual).isEqualTo(expected); - } - private static final void encodeString(String input, ByteArrayOutputStream byteArrayOutputStream) throws IOException { VarInt.putVarInt(input.length(), byteArrayOutputStream); diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java index ef6bb656c3..1567d8c6fc 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java @@ -71,11 +71,11 @@ static List createAggregationData( List aggregations, double... values) { List aggregationDataList = new ArrayList(aggregations.size()); for (Aggregation aggregation : aggregations) { - MutableAggregation mAggregation = MutableViewData.createMutableAggregation(aggregation); + MutableAggregation mutableAggregation = MutableViewData.createMutableAggregation(aggregation); for (double value : values) { - mAggregation.add(value); + mutableAggregation.add(value); } - aggregationDataList.add(MutableViewData.createAggregationData(mAggregation)); + aggregationDataList.add(MutableViewData.createAggregationData(mutableAggregation)); } return aggregationDataList; } diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index 54fdb7062e..8688cd99e2 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -375,13 +375,13 @@ public void testViewDataWithMultipleTagKeys() { @Test public void testMultipleViewSameMeasure() { - View view1 = + final View view1 = createCumulativeView( VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(KEY)); - View view2 = + final View view2 = createCumulativeView( VIEW_NAME_2, MEASURE, @@ -422,10 +422,10 @@ public void testMultipleViewsDifferentMeasures() { Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); MeasureDouble measure2 = Measure.MeasureDouble.create(MEASURE_NAME_2, MEASURE_DESCRIPTION, MEASURE_UNIT); - View view1 = + final View view1 = createCumulativeView( VIEW_NAME, measure1, AGGREGATIONS, Arrays.asList(KEY)); - View view2 = + final View view2 = createCumulativeView( VIEW_NAME_2, measure2, AGGREGATIONS, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); From dce343a9daa908b2bd53d630be91670e731e65d1 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Sun, 13 Aug 2017 00:08:51 +0200 Subject: [PATCH 0382/1581] Let JMH benchmarks depend on successful integration tests. --- contrib/agent/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/agent/build.gradle b/contrib/agent/build.gradle index 55c7a96b25..2b7ff53599 100644 --- a/contrib/agent/build.gradle +++ b/contrib/agent/build.gradle @@ -193,6 +193,7 @@ task agentJar(type: Copy) { } jmhJar.dependsOn agentJar +jmhJar.dependsOn integrationTest jmh { jmhVersion = '1.19' From d088c0e2acb6eb6a03f1e103517fff725022ca7c Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 14 Aug 2017 11:08:56 -0700 Subject: [PATCH 0383/1581] Clean links to travis/appveyor in agent readme and add maven release status (#513) --- contrib/agent/README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/contrib/agent/README.md b/contrib/agent/README.md index 90abb8cf66..ed0824ac7b 100644 --- a/contrib/agent/README.md +++ b/contrib/agent/README.md @@ -1,6 +1,6 @@ # OpenCensus Agent for Java -[![Build Status](https://travis-ci.org/census-instrumentation/opencensus-java.svg?branch=master)](https://travis-ci.org/census-instrumentation/opencensus-java) [![Build status](https://ci.appveyor.com/api/projects/status/hxthmpkxar4jq4be/branch/master?svg=true)](https://ci.appveyor.com/project/instrumentationjavateam/opencensus-java/branch/master) +[![Build Status][travis-image]][travis-url] [![Build status][appveyor-image]][appveyor-url] [![Maven Central][maven-image]][maven-url] The *OpenCensus Agent for Java* collects and sends latency data about your Java process to OpenCensus backends such as Zipkin, Stackdriver Trace, etc. for analysis and visualization. @@ -48,3 +48,10 @@ the following example: ```shell java -javaagent:path/to/opencensus-agent.jar ... ``` + +[travis-image]: https://travis-ci.org/census-instrumentation/opencensus-java.svg?branch=master +[travis-url]: https://travis-ci.org/census-instrumentation/opencensus-java +[appveyor-image]: https://ci.appveyor.com/api/projects/status/hxthmpkxar4jq4be/branch/master?svg=true +[appveyor-url]: https://ci.appveyor.com/project/instrumentationjavateam/opencensus-java/branch/master +[maven-image]: https://maven-badges.herokuapp.com/maven-central/io.opencensus/opencensus-agent/badge.svg +[maven-url]: https://maven-badges.herokuapp.com/maven-central/io.opencensus/opencensus-agent \ No newline at end of file From 0318bc5a0ba6742273551068b3cdd900364be37e Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 14 Aug 2017 11:28:40 -0700 Subject: [PATCH 0384/1581] Refactor tag validation code. This commit splits tag validation into separate methods for handling tag keys and values, since keys and values may need different restrictions on their input Strings. There should be no change in behavior. --- .../io/opencensus/internal/StringUtil.java | 13 ++++--------- .../main/java/io/opencensus/tags/TagKey.java | 18 ++++++++++++++---- .../io/opencensus/tags/TagValueString.java | 14 ++++++++++++-- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/api/src/main/java/io/opencensus/internal/StringUtil.java b/api/src/main/java/io/opencensus/internal/StringUtil.java index 48992ebd80..2d17cb34f9 100644 --- a/api/src/main/java/io/opencensus/internal/StringUtil.java +++ b/api/src/main/java/io/opencensus/internal/StringUtil.java @@ -44,17 +44,12 @@ public static String sanitize(String str) { } /** - * Determines whether the {@code String} is a valid tag key, tag value, or metric name. + * Determines whether the {@code String} contains only printable characters. * - * @param string the {@code String} to be validated. - * @return whether the {@code String} is valid. - * @see #sanitize(String) + * @param str the {@code String} to be validated. + * @return whether the {@code String} contains only printable characters. */ - public static boolean isValid(String string) { - return string.length() <= MAX_LENGTH && isPrintableString(string); - } - - private static boolean isPrintableString(String str) { + public static boolean isPrintableString(String str) { for (int i = 0; i < str.length(); i++) { if (!isPrintableChar(str.charAt(i))) { return false; diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index 94359a03a9..aadfcc85d2 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -37,7 +37,7 @@ @Immutable public abstract class TagKey { /** The maximum length for a tag key name. The value is {@value #MAX_LENGTH}. */ - public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; + public static final int MAX_LENGTH = 255; TagKey() {} @@ -113,6 +113,16 @@ public abstract T match( Function booleanFunction, Function defaultFunction); + /** + * Determines whether the given {@code String} is a valid tag key. + * + * @param name the tag key name to be validated. + * @return whether the name is valid. + */ + private static boolean isValid(String name) { + return name.length() <= MAX_LENGTH && StringUtil.isPrintableString(name); + } + /** A {@code TagKey} for values of type {@code String}. */ @Immutable @AutoValue @@ -133,7 +143,7 @@ public abstract static class TagKeyString extends TagKey { * @throws IllegalArgumentException if the name is not valid. */ public static TagKeyString create(String name) { - checkArgument(StringUtil.isValid(name)); + checkArgument(isValid(name)); return new AutoValue_TagKey_TagKeyString(name); } @@ -173,7 +183,7 @@ public abstract static class TagKeyLong extends TagKey { */ // TODO(sebright): Make this public once we support types other than String. static TagKeyLong create(String name) { - checkArgument(StringUtil.isValid(name)); + checkArgument(isValid(name)); return new AutoValue_TagKey_TagKeyLong(name); } @@ -213,7 +223,7 @@ public abstract static class TagKeyBoolean extends TagKey { */ // TODO(sebright): Make this public once we support types other than String. static TagKeyBoolean create(String name) { - checkArgument(StringUtil.isValid(name)); + checkArgument(isValid(name)); return new AutoValue_TagKey_TagKeyBoolean(name); } diff --git a/core/src/main/java/io/opencensus/tags/TagValueString.java b/core/src/main/java/io/opencensus/tags/TagValueString.java index 4c032f8f12..316755866f 100644 --- a/core/src/main/java/io/opencensus/tags/TagValueString.java +++ b/core/src/main/java/io/opencensus/tags/TagValueString.java @@ -29,7 +29,7 @@ @AutoValue public abstract class TagValueString { /** The maximum length for a {@code String} tag value. The value is {@value #MAX_LENGTH}. */ - public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; + public static final int MAX_LENGTH = 255; TagValueString() {} @@ -46,7 +46,7 @@ public abstract class TagValueString { * @throws IllegalArgumentException if the {@code String} is not valid. */ public static TagValueString create(String value) { - Preconditions.checkArgument(StringUtil.isValid(value)); + Preconditions.checkArgument(isValid(value)); return new AutoValue_TagValueString(value); } @@ -56,4 +56,14 @@ public static TagValueString create(String value) { * @return the tag value as a {@code String}. */ public abstract String asString(); + + /** + * Determines whether the given {@code String} is a valid tag value. + * + * @param name the tag value to be validated. + * @return whether the value is valid. + */ + private static boolean isValid(String name) { + return name.length() <= MAX_LENGTH && StringUtil.isPrintableString(name); + } } From 6a60437adee7df1851530d799c5d7e9e768eec48 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 14 Aug 2017 20:06:44 -0700 Subject: [PATCH 0385/1581] Replace original tag classes with classes in the tags package. I removed all of the original tag classes and tests. There are still a few things that need to be done after this commit: - The tags package doesn't have a class to represent a tag value yet, so I used Object instead of TagValue in the ViewData API. - There are no methods for manipulating the current TagContext yet, since #498 hasn't been merged. I couldn't update StatsRunner, so I temporarily commented most of it out. - We need to add a StatsRecorder.record method that uses the current context. --- .../stats/CurrentStatsContextUtils.java | 80 ----- .../opencensus/stats/RpcMeasureConstants.java | 7 +- .../main/java/io/opencensus/stats/Stats.java | 6 - .../io/opencensus/stats/StatsComponent.java | 14 +- .../io/opencensus/stats/StatsContext.java | 82 ------ .../opencensus/stats/StatsContextFactory.java | 104 ------- .../io/opencensus/stats/StatsRecorder.java | 5 +- .../main/java/io/opencensus/stats/Tag.java | 43 --- .../main/java/io/opencensus/stats/TagKey.java | 52 ---- .../java/io/opencensus/stats/TagValue.java | 52 ---- .../main/java/io/opencensus/stats/View.java | 3 +- .../java/io/opencensus/stats/ViewData.java | 17 +- .../stats/CurrentStatsContextUtilsTest.java | 78 ----- .../opencensus/stats/StatsRecorderTest.java | 27 +- .../java/io/opencensus/stats/StatsTest.java | 1 - .../java/io/opencensus/stats/TagKeyTest.java | 58 ---- .../java/io/opencensus/stats/TagTest.java | 55 ---- .../io/opencensus/stats/TagValueTest.java | 58 ---- .../io/opencensus/stats/ViewDataTest.java | 20 +- .../java/io/opencensus/stats/ViewTest.java | 16 +- .../opencensus/impl/tags/TagContextImpl.java | 4 +- .../opencensus/impl/tags/TagContextsImpl.java | 3 +- .../io/opencensus/stats/MeasureToViewMap.java | 11 +- .../io/opencensus/stats/MutableViewData.java | 72 ++++- .../stats/StatsComponentImplBase.java | 7 - .../stats/StatsContextFactoryImpl.java | 48 --- .../io/opencensus/stats/StatsContextImpl.java | 92 ------ .../io/opencensus/stats/StatsManager.java | 7 +- .../opencensus/stats/StatsRecorderImpl.java | 7 +- .../io/opencensus/stats/StatsSerializer.java | 155 ---------- .../stats/MeasureToViewMapTest.java | 4 +- .../opencensus/stats/MutableViewDataTest.java | 19 +- .../stats/StatsContextFactoryTest.java | 273 ------------------ .../io/opencensus/stats/StatsContextTest.java | 254 ---------------- .../io/opencensus/stats/StatsTestUtil.java | 32 +- .../opencensus/stats/ViewManagerImplTest.java | 235 +++++++-------- .../java/io/opencensus/stats/StatsTest.java | 5 - .../java/io/opencensus/stats/StatsTest.java | 5 - .../examples/stats/StatsRunner.java | 79 +++-- 39 files changed, 283 insertions(+), 1807 deletions(-) delete mode 100644 core/src/main/java/io/opencensus/stats/CurrentStatsContextUtils.java delete mode 100644 core/src/main/java/io/opencensus/stats/StatsContext.java delete mode 100644 core/src/main/java/io/opencensus/stats/StatsContextFactory.java delete mode 100644 core/src/main/java/io/opencensus/stats/Tag.java delete mode 100644 core/src/main/java/io/opencensus/stats/TagKey.java delete mode 100644 core/src/main/java/io/opencensus/stats/TagValue.java delete mode 100644 core/src/test/java/io/opencensus/stats/CurrentStatsContextUtilsTest.java delete mode 100644 core/src/test/java/io/opencensus/stats/TagKeyTest.java delete mode 100644 core/src/test/java/io/opencensus/stats/TagTest.java delete mode 100644 core/src/test/java/io/opencensus/stats/TagValueTest.java delete mode 100644 core_impl/src/main/java/io/opencensus/stats/StatsContextFactoryImpl.java delete mode 100644 core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java delete mode 100644 core_impl/src/main/java/io/opencensus/stats/StatsSerializer.java delete mode 100644 core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java delete mode 100644 core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java diff --git a/core/src/main/java/io/opencensus/stats/CurrentStatsContextUtils.java b/core/src/main/java/io/opencensus/stats/CurrentStatsContextUtils.java deleted file mode 100644 index 2db58c950f..0000000000 --- a/core/src/main/java/io/opencensus/stats/CurrentStatsContextUtils.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import io.grpc.Context; -import io.opencensus.common.Scope; - -/** - * Util methods/functionality to interact with the {@link io.grpc.Context}. - */ -final class CurrentStatsContextUtils { - - // Static class. - private CurrentStatsContextUtils() { - } - - /** - * The {@link io.grpc.Context.Key} used to interact with the {@code StatsContext} contained in the - * {@link io.grpc.Context}. - */ - public static final Context.Key STATS_CONTEXT_KEY = - Context.key("opencensus-stats-context-key"); - - /** - * Returns The {@link StatsContext} from the current context. - * - * @return The {@code StatsContext} from the current context. - */ - static StatsContext getCurrentStatsContext() { - return STATS_CONTEXT_KEY.get(Context.current()); - } - - /** - * Enters the scope of code where the given {@link StatsContext} is in the current context, and - * returns an object that represents that scope. The scope is exited when the returned object - * is closed. - * - *

Supports try-with-resource idiom. - * - * @param statsContext The {@code StatsContext} to be set to the current context. - * @return An object that defines a scope where the given {@code StatsContext} is set to the - * current context. - */ - static Scope withStatsContext(StatsContext statsContext) { - return new WithStatsContext(statsContext, STATS_CONTEXT_KEY); - } - - // Supports try-with-resources idiom. - private static final class WithStatsContext implements Scope { - - private final Context origContext; - - /** - * Constructs a new {@link WithStatsContext}. - * - * @param statsContext is the {@code StatsContext} to be added to the current {@code Context}. - * @param contextKey is the {@code Context.Key} used to set/get {@code StatsContext} from the - * {@code Context}. - */ - private WithStatsContext(StatsContext statsContext, Context.Key contextKey) { - origContext = Context.current().withValue(contextKey, statsContext).attach(); - } - - @Override - public void close() { - Context.current().detach(origContext); - } - } -} diff --git a/core/src/main/java/io/opencensus/stats/RpcMeasureConstants.java b/core/src/main/java/io/opencensus/stats/RpcMeasureConstants.java index 32e0259fff..33eb0d08fe 100644 --- a/core/src/main/java/io/opencensus/stats/RpcMeasureConstants.java +++ b/core/src/main/java/io/opencensus/stats/RpcMeasureConstants.java @@ -15,6 +15,7 @@ import io.opencensus.stats.Measure.MeasureDouble; import io.opencensus.stats.Measure.MeasureLong; +import io.opencensus.tags.TagKey.TagKeyString; /** * Constants for collecting rpc stats. @@ -22,9 +23,9 @@ public final class RpcMeasureConstants { // Rpc tag keys. - public static final TagKey RPC_STATUS = TagKey.create("canonical_status"); - public static final TagKey RPC_CLIENT_METHOD = TagKey.create("method"); - public static final TagKey RPC_SERVER_METHOD = TagKey.create("method"); + public static final TagKeyString RPC_STATUS = TagKeyString.create("canonical_status"); + public static final TagKeyString RPC_CLIENT_METHOD = TagKeyString.create("method"); + public static final TagKeyString RPC_SERVER_METHOD = TagKeyString.create("method"); // Constants used to define the following Measures. private static final String BYTE = "By"; diff --git a/core/src/main/java/io/opencensus/stats/Stats.java b/core/src/main/java/io/opencensus/stats/Stats.java index 3221db96f6..f8cbce0958 100644 --- a/core/src/main/java/io/opencensus/stats/Stats.java +++ b/core/src/main/java/io/opencensus/stats/Stats.java @@ -26,12 +26,6 @@ public final class Stats { private static final StatsComponent statsComponent = loadStatsComponent(StatsComponent.class.getClassLoader()); - /** Returns the default {@link StatsContextFactory}. */ - @Nullable - public static StatsContextFactory getStatsContextFactory() { - return statsComponent == null ? null : statsComponent.getStatsContextFactory(); - } - /** Returns the default {@link StatsRecorder}. */ @Nullable public static StatsRecorder getStatsRecorder() { diff --git a/core/src/main/java/io/opencensus/stats/StatsComponent.java b/core/src/main/java/io/opencensus/stats/StatsComponent.java index 4ea13c2353..489dda6a7a 100644 --- a/core/src/main/java/io/opencensus/stats/StatsComponent.java +++ b/core/src/main/java/io/opencensus/stats/StatsComponent.java @@ -17,8 +17,7 @@ import javax.annotation.concurrent.Immutable; /** - * Class that holds the implementations for {@link ViewManager}, {@link StatsRecorder}, and {@link - * StatsContextFactory}. + * Class that holds the implementations for {@link ViewManager} and {@link StatsRecorder}. * *

All objects returned by methods on {@code StatsComponent} are cacheable. */ @@ -32,11 +31,6 @@ public abstract class StatsComponent { /** Returns the default {@link StatsRecorder}. */ public abstract StatsRecorder getStatsRecorder(); - /** Returns the default {@link StatsContextFactory}. */ - // TODO(sebright): Remove this method once StatsContext is replaced by TagContext. - @Nullable - abstract StatsContextFactory getStatsContextFactory(); - /** * Returns a {@code StatsComponent} that has a no-op implementation for the {@link StatsRecorder}. * @@ -60,11 +54,5 @@ public ViewManager getViewManager() { public StatsRecorder getStatsRecorder() { return StatsRecorder.getNoopStatsRecorder(); } - - @Override - @Nullable - StatsContextFactory getStatsContextFactory() { - return null; - } } } diff --git a/core/src/main/java/io/opencensus/stats/StatsContext.java b/core/src/main/java/io/opencensus/stats/StatsContext.java deleted file mode 100644 index b29675390b..0000000000 --- a/core/src/main/java/io/opencensus/stats/StatsContext.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import java.io.IOException; -import java.io.OutputStream; -import javax.annotation.concurrent.Immutable; - -/** - * An immutable context for stats operations. - */ -@Immutable -public abstract class StatsContext { - /** - * Returns a builder based on this {@link StatsContext}. - */ - public abstract Builder builder(); - - /** Shorthand for builder().set(k1, v1).build() */ - public final StatsContext with(TagKey k1, TagValue v1) { - return builder().set(k1, v1).build(); - } - - /** Shorthand for builder().set(k1, v1).set(k2, v2).build() */ - public final StatsContext with(TagKey k1, TagValue v1, TagKey k2, TagValue v2) { - return builder().set(k1, v1).set(k2, v2).build(); - } - - /** Shorthand for builder().set(k1, v1).set(k2, v2).set(k3, v3).build() */ - public final StatsContext with( - TagKey k1, TagValue v1, TagKey k2, TagValue v2, TagKey k3, TagValue v3) { - return builder().set(k1, v1).set(k2, v2).set(k3, v3).build(); - } - - /** - * Records the given measurements against this {@link StatsContext}. - * - * @param measurements the measurements to record against the saved {@link StatsContext} - * @return this - */ - public abstract StatsContext record(MeasureMap measurements); - - /** - * Serializes the {@link StatsContext} into the on-the-wire representation. - * - *

The inverse of {@link StatsContextFactory#deserialize(java.io.InputStream)} and should be - * based on the {@link StatsContext} protobuf representation. - * - * @param output the {@link OutputStream} to add the serialized form of this {@link StatsContext}. - */ - public abstract void serialize(OutputStream output) throws IOException; - - /** - * Builder for {@link StatsContext}. - */ - public abstract static class Builder { - /** - * Associates the given tag key with the given tag value. - * - * @param key the key - * @param value the value to be associated with {@code key} - * @return {@code this} - */ - public abstract Builder set(TagKey key, TagValue value); - - /** - * Builds a {@link StatsContext} from the specified keys and values. - */ - public abstract StatsContext build(); - } -} diff --git a/core/src/main/java/io/opencensus/stats/StatsContextFactory.java b/core/src/main/java/io/opencensus/stats/StatsContextFactory.java deleted file mode 100644 index 9abe675da9..0000000000 --- a/core/src/main/java/io/opencensus/stats/StatsContextFactory.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.base.Preconditions.checkNotNull; - -import io.opencensus.common.Scope; -import java.io.IOException; -import java.io.InputStream; - -/** - * Factory class for {@link StatsContext}. - */ -public abstract class StatsContextFactory { - - /** - * Creates a {@link StatsContext} from the given on-the-wire encoded representation. - * - *

Should be the inverse of {@link StatsContext#serialize(java.io.OutputStream)}. The - * serialized representation should be based on the {@link StatsContext} binary representation. - * - * @param input on-the-wire representation of a {@link StatsContext} - * @return a {@link StatsContext} deserialized from {@code input} - */ - public abstract StatsContext deserialize(InputStream input) throws IOException; - - /** - * Returns the default {@link StatsContext}. - */ - public abstract StatsContext getDefault(); - - /** - * Get current StatsContext from current gRPC Context. - * - * @return the current {@code StatsContext} from {@code io.grpc.Context}, or the default - * {@code StatsContext} if there's no {@code StatsContext} associated with current - * {@code io.grpc.Context}. - */ - public final StatsContext getCurrentStatsContext() { - StatsContext statsContext = CurrentStatsContextUtils.getCurrentStatsContext(); - return statsContext != null ? statsContext : getDefault(); - } - - /** - * Enters the scope of code where the given {@link StatsContext} is in the current Context, and - * returns an object that represents that scope. The scope is exited when the returned object is - * closed. - * - *

Supports try-with-resource idiom. - * - *

Example of usage: - * - *

{@code
-   * private final StatsContextFactory statsCtxFactory =
-   *     checkNotNull(Stats.getStatsContextFactory(), "statsCtxFactory");
-   * void doWork() {
-   *   // Construct a new StatsContext with required tags to be set into current context.
-   *   StatsContext statsCtx = statsCtxFactory.getCurrentStatsContext().with(tagKey, tagValue);
-   *   try (Scope scopedStatsCtx = statsCtxFactory.withStatsContext(statsCtx)) {
-   *     doSomeOtherWork();  // Here "scopedStatsCtx" is the current StatsContext.
-   *   }
-   * }
-   * }
- * - *

Prior to Java SE 7, you can use a finally block to ensure that a resource is closed - * regardless of whether the try statement completes normally or abruptly. - * - *

Example of usage prior to Java SE7: - * - *

{@code
-   * private final StatsContextFactory statsCtxFactory =
-   *     checkNotNull(Stats.getStatsContextFactory(), "statsCtxFactory");
-   * void doWork() {
-   *   // Construct a new StatsContext with required tags to be set into current context.
-   *   StatsContext statsCtx = statsCtxFactory.getCurrentStatsContext().with(tagKey, tagValue);
-   *   Scope scopedStatsCtx = statsCtxFactory.withStatsContext(statsCtx);
-   *   try {
-   *     doSomeOtherWork();  // Here "scopedStatsCtx" is the current StatsContext.
-   *   } finally {
-   *     scopedStatsCtx.close();
-   *   }
-   * }
-   * }
- * - * @param statsContext The {@link StatsContext} to be set to the current Context. - * @return an object that defines a scope where the given {@link StatsContext} will be set to the - * current Context. - * @throws NullPointerException if statsContext is null. - */ - public final Scope withStatsContext(StatsContext statsContext) { - return CurrentStatsContextUtils.withStatsContext(checkNotNull(statsContext, "statsContext")); - } -} diff --git a/core/src/main/java/io/opencensus/stats/StatsRecorder.java b/core/src/main/java/io/opencensus/stats/StatsRecorder.java index 6fec44fa9b..ebef1f180b 100644 --- a/core/src/main/java/io/opencensus/stats/StatsRecorder.java +++ b/core/src/main/java/io/opencensus/stats/StatsRecorder.java @@ -14,6 +14,7 @@ package io.opencensus.stats; import com.google.common.base.Preconditions; +import io.opencensus.tags.TagContext; import javax.annotation.concurrent.Immutable; /** Provides methods to record stats against tags. */ @@ -32,7 +33,7 @@ public abstract class StatsRecorder { * @param tags the tags associated with the measurements. * @param measurementValues the measurements to record. */ - abstract void record(StatsContext tags, MeasureMap measurementValues); + abstract void record(TagContext tags, MeasureMap measurementValues); /** * Returns a {@code StatsRecorder} that does not record any data. @@ -47,7 +48,7 @@ static StatsRecorder getNoopStatsRecorder() { private static final class NoopStatsRecorder extends StatsRecorder { @Override - void record(StatsContext tags, MeasureMap measurementValues) { + void record(TagContext tags, MeasureMap measurementValues) { Preconditions.checkNotNull(tags); Preconditions.checkNotNull(measurementValues); } diff --git a/core/src/main/java/io/opencensus/stats/Tag.java b/core/src/main/java/io/opencensus/stats/Tag.java deleted file mode 100644 index 995af976d5..0000000000 --- a/core/src/main/java/io/opencensus/stats/Tag.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import com.google.auto.value.AutoValue; -import javax.annotation.concurrent.Immutable; - -/** - * A pair of consisting of an associated {@link TagKey} and {@link TagValue}. - */ -@Immutable -@AutoValue -public abstract class Tag { - Tag() {} - - /** - * Constructs a new {@link Tag} from the given key and value. - */ - public static Tag create(TagKey key, TagValue value) { - return new AutoValue_Tag(key, value); - } - - /** - * Returns the associated tag key. - */ - public abstract TagKey getKey(); - - /** - * Returns the associated tag key. - */ - public abstract TagValue getValue(); -} diff --git a/core/src/main/java/io/opencensus/stats/TagKey.java b/core/src/main/java/io/opencensus/stats/TagKey.java deleted file mode 100644 index 1732b4c6f0..0000000000 --- a/core/src/main/java/io/opencensus/stats/TagKey.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import com.google.auto.value.AutoValue; -import io.opencensus.internal.StringUtil; -import javax.annotation.concurrent.Immutable; - -/** - * Tag keys. - * - *

TagKey's are {@link String}s with enforced restrictions. - */ -@Immutable -@AutoValue -public abstract class TagKey { - public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; - - TagKey() {} - - /** - * Constructs a new {@link TagKey} from the given string. The string will be sanitize such that: - *

    - *
  1. length is restricted to {@link #MAX_LENGTH}, strings longer than that will be truncated. - *
  2. characters are restricted to printable ascii characters, non-printable characters will be - * replaced by an underscore '_'. - *
- */ - public static TagKey create(String key) { - return new AutoValue_TagKey(StringUtil.sanitize(key)); - } - - public abstract String asString(); - - // TODO(sebright) Use the default AutoValue toString(), which is more useful for debugging. - // gRPC is currently calling toString() to access the key field, so we can't change it yet. - @Override - public final String toString() { - return asString(); - } -} diff --git a/core/src/main/java/io/opencensus/stats/TagValue.java b/core/src/main/java/io/opencensus/stats/TagValue.java deleted file mode 100644 index 84f795c273..0000000000 --- a/core/src/main/java/io/opencensus/stats/TagValue.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import com.google.auto.value.AutoValue; -import io.opencensus.internal.StringUtil; -import javax.annotation.concurrent.Immutable; - -/** - * Tag values. - * - *

TagValue's are {@link String}s with enforced restrictions. - */ -@Immutable -@AutoValue -public abstract class TagValue { - public static final int MAX_LENGTH = StringUtil.MAX_LENGTH; - - TagValue() {} - - /** - * Constructs a new {@link TagValue} from the given string. The string will be sanitize such that: - *

    - *
  1. length is restricted to {@link MAX_LENGTH}, strings longer than that will be truncated. - *
  2. characters are restricted to printable ascii characters, non-printable characters will be - * replaced by an underscore '_'. - *
- */ - public static TagValue create(String value) { - return new AutoValue_TagValue(StringUtil.sanitize(value)); - } - - public abstract String asString(); - - // TODO(sebright) Use the default AutoValue toString(), which is more useful for debugging. - // gRPC is currently calling toString() to access the value field, so we can't change it yet. - @Override - public final String toString() { - return asString(); - } -} diff --git a/core/src/main/java/io/opencensus/stats/View.java b/core/src/main/java/io/opencensus/stats/View.java index 6cbddf29ef..503111c9c4 100644 --- a/core/src/main/java/io/opencensus/stats/View.java +++ b/core/src/main/java/io/opencensus/stats/View.java @@ -18,6 +18,7 @@ import com.google.auto.value.AutoValue; import io.opencensus.common.Duration; import io.opencensus.common.Function; +import io.opencensus.tags.TagKey; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -89,7 +90,7 @@ public static View create( String description, Measure measure, List aggregations, - List columns, + List columns, Window window) { checkArgument(new HashSet(aggregations).size() == aggregations.size(), "Aggregations have duplicate."); diff --git a/core/src/main/java/io/opencensus/stats/ViewData.java b/core/src/main/java/io/opencensus/stats/ViewData.java index 7fd130b299..05c860c3ec 100644 --- a/core/src/main/java/io/opencensus/stats/ViewData.java +++ b/core/src/main/java/io/opencensus/stats/ViewData.java @@ -39,10 +39,11 @@ public abstract class ViewData { public abstract View getView(); /** - * The {@link AggregationData}s grouped by combination of {@link TagValue}s, associated with this + * The {@link AggregationData}s grouped by combination of tag values, associated with this * {@link ViewData}. */ - public abstract Map, List> getAggregationMap(); + // TODO(sebright): Create a TagValue class. + public abstract Map, List> getAggregationMap(); /** * Returns the {@link WindowData} associated with this {@link ViewData}. @@ -53,7 +54,9 @@ public abstract class ViewData { /** Constructs a new {@link ViewData}. */ public static ViewData create( - View view, Map, List> map, final WindowData windowData) { + View view, + Map, List> map, + final WindowData windowData) { view.getWindow() .match( new Function() { @@ -86,11 +89,11 @@ public Void apply(View.Window.Interval arg) { }, Functions.throwIllegalArgumentException()); - Map, List> deepCopy = - new HashMap, List>(); - for (Entry, List> entry : map.entrySet()) { + Map, List> deepCopy = + new HashMap, List>(); + for (Entry, List> entry : map.entrySet()) { deepCopy.put( - Collections.unmodifiableList(new ArrayList(entry.getKey())), + Collections.unmodifiableList(new ArrayList(entry.getKey())), Collections.unmodifiableList(new ArrayList(entry.getValue()))); } diff --git a/core/src/test/java/io/opencensus/stats/CurrentStatsContextUtilsTest.java b/core/src/test/java/io/opencensus/stats/CurrentStatsContextUtilsTest.java deleted file mode 100644 index 0c154cb7a4..0000000000 --- a/core/src/test/java/io/opencensus/stats/CurrentStatsContextUtilsTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2017, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import io.grpc.Context; -import io.opencensus.common.Scope; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -/** - * Unit tests for {@link CurrentStatsContextUtils}. - */ -@RunWith(JUnit4.class) -public class CurrentStatsContextUtilsTest { - - @Mock - private StatsContext statsContext; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void testGetCurrentStatsContext_WhenNoContext() { - assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isNull(); - } - - @Test - public void testWithStatsContext() { - assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isNull(); - Scope scopedStatsCtx = CurrentStatsContextUtils.withStatsContext(statsContext); - try { - assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isSameAs(statsContext); - } finally { - scopedStatsCtx.close(); - } - assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isNull(); - } - - @Test - public void testWithStatsContextUsingWrap() { - Runnable runnable; - Scope scopedStatsCtx = CurrentStatsContextUtils.withStatsContext(statsContext); - try { - assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isSameAs(statsContext); - runnable = Context.current().wrap( - new Runnable() { - @Override - public void run() { - assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isSameAs(statsContext); - } - }); - } finally { - scopedStatsCtx.close(); - } - assertThat(CurrentStatsContextUtils.getCurrentStatsContext()).isNull(); - // When we run the runnable we will have the statsContext in the current Context. - runnable.run(); - } -} diff --git a/core/src/test/java/io/opencensus/stats/StatsRecorderTest.java b/core/src/test/java/io/opencensus/stats/StatsRecorderTest.java index 0a74f9f072..ce36733d4f 100644 --- a/core/src/test/java/io/opencensus/stats/StatsRecorderTest.java +++ b/core/src/test/java/io/opencensus/stats/StatsRecorderTest.java @@ -13,8 +13,10 @@ package io.opencensus.stats; -import java.io.IOException; -import java.io.OutputStream; +import io.opencensus.tags.Tag; +import io.opencensus.tags.TagContext; +import java.util.Collections; +import java.util.Iterator; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -23,27 +25,18 @@ @RunWith(JUnit4.class) public final class StatsRecorderTest { - private final StatsContext statsContext = - new StatsContext() { + private final TagContext tagContext = + new TagContext() { @Override - public void serialize(OutputStream output) throws IOException { - } - - @Override - public StatsContext record(MeasureMap measurements) { - return null; - } - - @Override - public Builder builder() { - return null; + public Iterator unsafeGetIterator() { + return Collections.emptySet().iterator(); } }; @Test public void defaultRecord() { - StatsRecorder.getNoopStatsRecorder().record(statsContext, MeasureMap.builder().build()); + StatsRecorder.getNoopStatsRecorder().record(tagContext, MeasureMap.builder().build()); } @Test(expected = NullPointerException.class) @@ -53,6 +46,6 @@ public void defaultRecord_DisallowNullStatsContext() { @Test(expected = NullPointerException.class) public void defaultRecord_DisallowNullMeasureMap() { - StatsRecorder.getNoopStatsRecorder().record(statsContext, null); + StatsRecorder.getNoopStatsRecorder().record(tagContext, null); } } diff --git a/core/src/test/java/io/opencensus/stats/StatsTest.java b/core/src/test/java/io/opencensus/stats/StatsTest.java index 8db2ac395e..aa70da0a96 100644 --- a/core/src/test/java/io/opencensus/stats/StatsTest.java +++ b/core/src/test/java/io/opencensus/stats/StatsTest.java @@ -57,7 +57,6 @@ public Class loadClass(String name) throws ClassNotFoundException { @Test public void defaultValues() { - assertThat(Stats.getStatsContextFactory()).isNull(); assertThat(Stats.getStatsRecorder()).isEqualTo(StatsRecorder.getNoopStatsRecorder()); assertThat(Stats.getViewManager()).isNull(); } diff --git a/core/src/test/java/io/opencensus/stats/TagKeyTest.java b/core/src/test/java/io/opencensus/stats/TagKeyTest.java deleted file mode 100644 index 2398a3c7af..0000000000 --- a/core/src/test/java/io/opencensus/stats/TagKeyTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.testing.EqualsTester; -import io.opencensus.internal.StringUtil; -import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Tests for {@link TagKey}. */ -@RunWith(JUnit4.class) -public final class TagKeyTest { - @Test - public void testKeyMaxLength() { - char[] key = new char[TagKey.MAX_LENGTH]; - char[] truncKey = new char[TagKey.MAX_LENGTH + 10]; - Arrays.fill(key, 'k'); - Arrays.fill(truncKey, 'k'); - assertThat(TagKey.create(new String(key)).toString()) - .isEqualTo(TagKey.create(new String(truncKey)).toString()); - } - - @Test - public void testKeyBadChar() { - String key = "\2ab\3cd"; - assertThat(TagKey.create(key).toString()) - .isEqualTo(StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + "ab" - + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + "cd"); - } - - @Test - public void testEquals() { - new EqualsTester() - .addEqualityGroup(TagKey.create("foo"), TagKey.create("foo")) - .addEqualityGroup(TagKey.create("bar")) - .testEquals(); - } - - @Test - public void testToString() { - assertThat(TagKey.create("foo").toString()).isEqualTo("foo"); - } -} diff --git a/core/src/test/java/io/opencensus/stats/TagTest.java b/core/src/test/java/io/opencensus/stats/TagTest.java deleted file mode 100644 index 05135b15ce..0000000000 --- a/core/src/test/java/io/opencensus/stats/TagTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.testing.EqualsTester; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Tests for {@link Tag}. */ -@RunWith(JUnit4.class) -public final class TagTest { - @Test - public void testTagTest() { - Tag tag = Tag.create(K1, V1); - assertThat(tag.getKey()).isEqualTo(K1); - assertThat(tag.getValue()).isEqualTo(V1); - } - - @Test - public void testEquals() { - new EqualsTester() - .addEqualityGroup(Tag.create(K1, V1), Tag.create(K1, V1)) - .addEqualityGroup(Tag.create(K2, V1)) - .addEqualityGroup(Tag.create(K1, V2)) - .testEquals(); - } - - @Test - public void testHashCode() { - new EqualsTester() - .addEqualityGroup(Tag.create(K1, V1).hashCode(), Tag.create(K1, V1).hashCode()) - .addEqualityGroup(Tag.create(K2, V1).hashCode()) - .addEqualityGroup(Tag.create(K1, V2).hashCode()) - .testEquals(); - } - - private static final TagKey K1 = TagKey.create("k1"); - private static final TagKey K2 = TagKey.create("k2"); - private static final TagValue V1 = TagValue.create("v1"); - private static final TagValue V2 = TagValue.create("v2"); -} diff --git a/core/src/test/java/io/opencensus/stats/TagValueTest.java b/core/src/test/java/io/opencensus/stats/TagValueTest.java deleted file mode 100644 index e53bda139f..0000000000 --- a/core/src/test/java/io/opencensus/stats/TagValueTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.testing.EqualsTester; -import io.opencensus.internal.StringUtil; -import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Tests for {@link TagValue}. */ -@RunWith(JUnit4.class) -public final class TagValueTest { - @Test - public void testValueMaxLength() { - char[] value = new char[TagValue.MAX_LENGTH]; - char[] truncValue = new char[TagValue.MAX_LENGTH + 10]; - Arrays.fill(value, 'v'); - Arrays.fill(truncValue, 'v'); - assertThat(TagValue.create(new String(value)).toString()) - .isEqualTo(TagValue.create(new String(truncValue)).toString()); - } - - @Test - public void testValueBadChar() { - String value = "\2ab\3cd"; - assertThat(TagValue.create(value).toString()) - .isEqualTo(StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + "ab" - + StringUtil.UNPRINTABLE_CHAR_SUBSTITUTE + "cd"); - } - - @Test - public void testEquals() { - new EqualsTester() - .addEqualityGroup(TagValue.create("foo"), TagValue.create("foo")) - .addEqualityGroup(TagValue.create("bar")) - .testEquals(); - } - - @Test - public void testToString() { - assertThat(TagValue.create("foo").toString()).isEqualTo("foo"); - } -} diff --git a/core/src/test/java/io/opencensus/stats/ViewDataTest.java b/core/src/test/java/io/opencensus/stats/ViewDataTest.java index 19ef3ef2a6..3dee360c60 100644 --- a/core/src/test/java/io/opencensus/stats/ViewDataTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewDataTest.java @@ -40,6 +40,8 @@ import io.opencensus.stats.ViewData.WindowData; import io.opencensus.stats.ViewData.WindowData.CumulativeData; import io.opencensus.stats.ViewData.WindowData.IntervalData; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -114,7 +116,7 @@ public void testViewDataEquals() { IntervalData.create(Timestamp.fromMillis(2000)))) .addEqualityGroup( ViewData.create( - intervalView, Collections., List>emptyMap(), + intervalView, Collections., List>emptyMap(), IntervalData.create(Timestamp.fromMillis(2000)))) .testEquals(); } @@ -186,15 +188,15 @@ public void preventStartTimeLaterThanEndTime() { } // tag keys - private static final TagKey K1 = TagKey.create("k1"); - private static final TagKey K2 = TagKey.create("k2"); - private final List tagKeys = Arrays.asList(K1, K2); + private static final TagKeyString K1 = TagKeyString.create("k1"); + private static final TagKeyString K2 = TagKeyString.create("k2"); + private final List tagKeys = Arrays.asList(K1, K2); // tag values - private static final TagValue V1 = TagValue.create("v1"); - private static final TagValue V2 = TagValue.create("v2"); - private static final TagValue V10 = TagValue.create("v10"); - private static final TagValue V20 = TagValue.create("v20"); + private static final TagValueString V1 = TagValueString.create("v1"); + private static final TagValueString V2 = TagValueString.create("v2"); + private static final TagValueString V10 = TagValueString.create("v10"); + private static final TagValueString V20 = TagValueString.create("v20"); private static final Window CUMULATIVE = Cumulative.create(); private static final Window INTERVAL_HOUR = Interval.create(Duration.create(3600, 0)); @@ -206,7 +208,7 @@ public void preventStartTimeLaterThanEndTime() { Sum.create(), Count.create(), Range.create(), Histogram.create(BUCKET_BOUNDARIES), Mean.create(), StdDev.create())); - private static final ImmutableMap, List> ENTRIES = + private static final ImmutableMap, List> ENTRIES = ImmutableMap.of( Arrays.asList(V1, V2), Arrays.asList( diff --git a/core/src/test/java/io/opencensus/stats/ViewTest.java b/core/src/test/java/io/opencensus/stats/ViewTest.java index 0255c4918e..4756db5972 100644 --- a/core/src/test/java/io/opencensus/stats/ViewTest.java +++ b/core/src/test/java/io/opencensus/stats/ViewTest.java @@ -21,6 +21,7 @@ import io.opencensus.stats.Aggregation.Sum; import io.opencensus.stats.View.Window.Cumulative; import io.opencensus.stats.View.Window.Interval; +import io.opencensus.tags.TagKey.TagKeyString; import java.util.Arrays; import java.util.List; import org.junit.Test; @@ -87,8 +88,13 @@ public void preventDuplicateAggregations() { @Test(expected = IllegalArgumentException.class) public void preventDuplicateColumns() { - View.create(name, description, measure, aggregations, - Arrays.asList(TagKey.create("duplicate"), TagKey.create("duplicate")), Cumulative.create()); + View.create( + name, + description, + measure, + aggregations, + Arrays.asList(TagKeyString.create("duplicate"), TagKeyString.create("duplicate")), + Cumulative.create()); } @Test(expected = NullPointerException.class) @@ -119,9 +125,9 @@ public void testViewNameEquals() { private final String description = "test-view-name description"; private final Measure measure = Measure.MeasureDouble.create( "measure", "measure description", "1"); - private static final TagKey FOO = TagKey.create("foo"); - private static final TagKey BAR = TagKey.create("bar"); - private final List keys = Arrays.asList(FOO, BAR); + private static final TagKeyString FOO = TagKeyString.create("foo"); + private static final TagKeyString BAR = TagKeyString.create("bar"); + private final List keys = Arrays.asList(FOO, BAR); private final List aggregations = Arrays.asList(Sum.create(), Count.create()); private final Duration minute = Duration.create(60, 0); private final Duration twoMinutes = Duration.create(120, 0); diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java index a9fca43bd6..658a48cf82 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextImpl.java @@ -33,7 +33,7 @@ import javax.annotation.concurrent.Immutable; @Immutable -final class TagContextImpl extends TagContext { +public final class TagContextImpl extends TagContext { static final TagContextImpl EMPTY = new TagContextImpl(Collections.emptyMap()); @@ -44,7 +44,7 @@ final class TagContextImpl extends TagContext { this.tags = Collections.unmodifiableMap(new HashMap(tags)); } - Map getTags() { + public Map getTags() { return tags; } diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextsImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextsImpl.java index c75eb954f5..3d182ecf4e 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextsImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextsImpl.java @@ -19,8 +19,7 @@ import io.opencensus.tags.TagContexts; import java.util.Iterator; -final class TagContextsImpl extends TagContexts { - TagContextsImpl() {} +public final class TagContextsImpl extends TagContexts { @Override public TagContextImpl empty() { diff --git a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java index fe4fc38c9d..4c99377afb 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java +++ b/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java @@ -19,6 +19,7 @@ import io.opencensus.common.Function; import io.opencensus.stats.Measurement.MeasurementDouble; import io.opencensus.stats.Measurement.MeasurementLong; +import io.opencensus.tags.TagContext; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; @@ -84,7 +85,7 @@ synchronized void registerView(View view, Clock clock) { } // Records stats with a set of tags. - synchronized void record(StatsContextImpl tags, MeasureMap stats) { + synchronized void record(TagContext tags, MeasureMap stats) { Iterator iterator = stats.iterator(); while (iterator.hasNext()) { Measurement measurement = iterator.next(); @@ -103,10 +104,10 @@ public Void apply(MeasurementDouble arg) { return null; } - private final StatsContextImpl tags; + private final TagContext tags; private final MutableViewData view; - private RecordDoubleValueFunc(StatsContextImpl tags, MutableViewData view) { + private RecordDoubleValueFunc(TagContext tags, MutableViewData view) { this.tags = tags; this.view = view; } @@ -119,10 +120,10 @@ public Void apply(MeasurementLong arg) { return null; } - private final StatsContextImpl tags; + private final TagContext tags; private final MutableViewData view; - private RecordLongValueFunc(StatsContextImpl tags, MutableViewData view) { + private RecordLongValueFunc(TagContext tags, MutableViewData view) { this.tags = tags; this.view = view; } diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java index a04ef93291..f605853ba5 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java +++ b/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java @@ -20,6 +20,7 @@ import io.opencensus.common.Function; import io.opencensus.common.Functions; import io.opencensus.common.Timestamp; +import io.opencensus.impl.tags.TagContextImpl; import io.opencensus.stats.Aggregation.Count; import io.opencensus.stats.Aggregation.Histogram; import io.opencensus.stats.Aggregation.Mean; @@ -41,7 +42,14 @@ import io.opencensus.stats.View.Window.Cumulative; import io.opencensus.stats.View.Window.Interval; import io.opencensus.stats.ViewData.WindowData.CumulativeData; +import io.opencensus.tags.Tag; +import io.opencensus.tags.Tag.TagBoolean; +import io.opencensus.tags.Tag.TagLong; +import io.opencensus.tags.Tag.TagString; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagKey; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -52,12 +60,36 @@ */ final class MutableViewData { - // TODO(songya): might want to update the default tag value later. + private static final Function GET_STRING_TAG_VALUE = + new Function() { + @Override + public Object apply(TagString tag) { + return tag.getValue(); + } + }; + + private static final Function GET_LONG_TAG_VALUE = + new Function() { + @Override + public Object apply(TagLong tag) { + return tag.getValue(); + } + }; + + private static final Function GET_BOOLEAN_TAG_VALUE = + new Function() { + @Override + public Object apply(TagBoolean tag) { + return tag.getValue(); + } + }; + + // TODO(sebright): Change this field to type TagValue once we have a TagValue class. @VisibleForTesting - static final TagValue UNKNOWN_TAG_VALUE = TagValue.create("unknown/not set"); + static final Object UNKNOWN_TAG_VALUE = null; private final View view; - private final Map, List> tagValueAggregationMap = + private final Map, List> tagValueAggregationMap = Maps.newHashMap(); @Nullable private final Timestamp start; @@ -101,8 +133,8 @@ View getView() { /** * Record double stats with the given tags. */ - void record(StatsContextImpl context, double value) { - List tagValues = getTagValues(context.tags, view.getColumns()); + void record(TagContext context, double value) { + List tagValues = getTagValues(getTagMap(context), view.getColumns()); if (!tagValueAggregationMap.containsKey(tagValues)) { List aggregations = Lists.newArrayList(); for (Aggregation aggregation : view.getAggregations()) { @@ -118,17 +150,36 @@ void record(StatsContextImpl context, double value) { /** * Record long stats with the given tags. */ - void record(StatsContextImpl tags, long value) { + void record(TagContext tags, long value) { // TODO(songya): modify MutableDistribution to support long values. throw new UnsupportedOperationException("Not implemented."); } + private static Map getTagMap(TagContext ctx) { + if (ctx instanceof TagContextImpl) { + return ((TagContextImpl) ctx).getTags(); + } else { + Map tags = Maps.newHashMap(); + for (Iterator i = ctx.unsafeGetIterator(); i.hasNext(); ) { + Tag tag = i.next(); + tags.put( + tag.getKey(), + tag.match( + GET_STRING_TAG_VALUE, + GET_LONG_TAG_VALUE, + GET_BOOLEAN_TAG_VALUE, + Functions.throwAssertionError())); + } + return tags; + } + } + /** * Convert this {@link MutableViewData} to {@link ViewData}. */ ViewData toViewData(Clock clock) { - Map, List> map = Maps.newHashMap(); - for (Entry, List> entry : + Map, List> map = Maps.newHashMap(); + for (Entry, List> entry : tagValueAggregationMap.entrySet()) { List aggregates = Lists.newArrayList(); for (MutableAggregation aggregation : entry.getValue()) { @@ -148,8 +199,9 @@ Timestamp getStart() { } @VisibleForTesting - static List getTagValues(Map tags, List columns) { - List tagValues = new ArrayList(columns.size()); + static List getTagValues( + Map tags, List columns) { + List tagValues = new ArrayList(columns.size()); // Record all the measures in a "Greedy" way. // Every view aggregates every measure. This is similar to doing a GROUPBY view’s keys. for (int i = 0; i < columns.size(); ++i) { diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java b/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java index ddde102a46..cd423124a4 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java @@ -21,13 +21,11 @@ class StatsComponentImplBase extends StatsComponent { private final ViewManagerImpl viewManager; private final StatsRecorderImpl statsRecorder; - private final StatsContextFactoryImpl statsContextFactory; StatsComponentImplBase(EventQueue queue, Clock clock) { StatsManager statsManager = new StatsManager(queue, clock); this.viewManager = new ViewManagerImpl(statsManager); this.statsRecorder = new StatsRecorderImpl(statsManager); - this.statsContextFactory = new StatsContextFactoryImpl(statsRecorder); } @Override @@ -39,9 +37,4 @@ public ViewManagerImpl getViewManager() { public StatsRecorderImpl getStatsRecorder() { return statsRecorder; } - - @Override - StatsContextFactoryImpl getStatsContextFactory() { - return statsContextFactory; - } } diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsContextFactoryImpl.java b/core_impl/src/main/java/io/opencensus/stats/StatsContextFactoryImpl.java deleted file mode 100644 index ef2a7cc0b0..0000000000 --- a/core_impl/src/main/java/io/opencensus/stats/StatsContextFactoryImpl.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import com.google.common.base.Preconditions; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; - -/** - * Native Implementation of {@link StatsContextFactory}. - */ -final class StatsContextFactoryImpl extends StatsContextFactory { - private final StatsRecorderImpl statsRecorder; - private final StatsContextImpl defaultStatsContext; - - StatsContextFactoryImpl(StatsRecorderImpl statsRecorder) { - this.statsRecorder = Preconditions.checkNotNull(statsRecorder); - this.defaultStatsContext = - new StatsContextImpl(statsRecorder, Collections.emptyMap()); - } - - /** - * Deserializes a {@link StatsContextImpl} using the format defined in {@code StatsSerializer}.. - * - *

The encoded tags are of the form: {@code } - */ - @Override - public StatsContextImpl deserialize(InputStream input) throws IOException { - return StatsSerializer.deserialize(statsRecorder, input); - } - - @Override - public StatsContextImpl getDefault() { - return defaultStatsContext; - } -} diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java b/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java deleted file mode 100644 index 155e91c4c3..0000000000 --- a/core_impl/src/main/java/io/opencensus/stats/StatsContextImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import com.google.common.base.Preconditions; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * Native Implementation of {@link StatsContext}. - */ -final class StatsContextImpl extends StatsContext { - private final StatsRecorderImpl statsRecorder; - final Map tags; - - StatsContextImpl(StatsRecorderImpl statsRecorder, Map tags) { - this.statsRecorder = Preconditions.checkNotNull(statsRecorder); - this.tags = Preconditions.checkNotNull(tags); - } - - @Override - public Builder builder() { - return new Builder(statsRecorder, tags); - } - - @Override - public StatsContextImpl record(MeasureMap stats) { - statsRecorder.record(this, stats); - return this; - } - - /** - * Serializes a {@link StatsContextImpl} using the format defined in {@code StatsSerializer}. - * - *

The encoded tags are of the form: {@code } - */ - @Override - public void serialize(OutputStream output) throws IOException { - StatsSerializer.serialize(this, output); - } - - @Override - public boolean equals(Object obj) { - return (obj instanceof StatsContextImpl) && tags.equals(((StatsContextImpl) obj).tags); - } - - @Override - public int hashCode() { - return tags.hashCode(); - } - - @Override - public String toString() { - return tags.toString(); - } - - static final class Builder extends StatsContext.Builder { - private final StatsRecorderImpl statsRecorder; - private final HashMap tags; - - private Builder(StatsRecorderImpl statsRecorder, Map tags) { - this.statsRecorder = statsRecorder; - this.tags = new HashMap(tags); - } - - @Override - public Builder set(TagKey key, TagValue value) { - tags.put(key, value); - return this; - } - - @Override - public StatsContextImpl build() { - return new StatsContextImpl( - statsRecorder, Collections.unmodifiableMap(new HashMap(tags))); - } - } -} diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java index 1ece888ed3..7f2f08a315 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java @@ -15,6 +15,7 @@ import io.opencensus.common.Clock; import io.opencensus.internal.EventQueue; +import io.opencensus.tags.TagContext; /** Object that stores all views and stats. */ final class StatsManager { @@ -48,17 +49,17 @@ ViewData getView(View.Name viewName) { } } - void record(StatsContextImpl tags, MeasureMap measurementValues) { + void record(TagContext tags, MeasureMap measurementValues) { queue.enqueue(new StatsEvent(this, tags, measurementValues)); } // An EventQueue entry that records the stats from one call to StatsManager.record(...). private static final class StatsEvent implements EventQueue.Entry { - private final StatsContextImpl tags; + private final TagContext tags; private final MeasureMap stats; private final StatsManager viewManager; - StatsEvent(StatsManager viewManager, StatsContextImpl tags, MeasureMap stats) { + StatsEvent(StatsManager viewManager, TagContext tags, MeasureMap stats) { this.viewManager = viewManager; this.tags = tags; this.stats = stats; diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java b/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java index 3eca8b3926..ff9eadde34 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java @@ -13,6 +13,8 @@ package io.opencensus.stats; +import io.opencensus.tags.TagContext; + /** Implementation of {@link StatsRecorder}. */ final class StatsRecorderImpl extends StatsRecorder { private final StatsManager statsManager; @@ -22,8 +24,7 @@ final class StatsRecorderImpl extends StatsRecorder { } @Override - void record(StatsContext tags, MeasureMap measurementValues) { - // TODO(sebright): Replace StatsContext with TagContext, and then this cast won't be necessary. - statsManager.record((StatsContextImpl) tags, measurementValues); + void record(TagContext tags, MeasureMap measurementValues) { + statsManager.record(tags, measurementValues); } } diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsSerializer.java b/core_impl/src/main/java/io/opencensus/stats/StatsSerializer.java deleted file mode 100644 index 449be11b47..0000000000 --- a/core_impl/src/main/java/io/opencensus/stats/StatsSerializer.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.io.ByteStreams; -import io.opencensus.internal.VarInt; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map.Entry; -import java.util.Set; - -/** - * Native implementation {@link StatsContext} serialization. - * - *

Encoding of stats context information (tags) for passing across RPC's:

- * - *
    - *
  • Tags are encoded in single byte sequence. The version 0 format is: - *
  • {@code } - *
  • {@code == a single byte, value 0} - *
  • {@code == ()*} - *
      - *
    • {@code } == a single byte, value 0 (string tag), 1 (int tag), - * 2 (true bool tag), 3 (false bool tag) - *
    • {@code }: - *
        - *
      • {@code (tag_field_id == 0) == } - *
          - *
        • {@code } == varint encoded integer - *
        • {@code } == tag_key_len bytes comprising tag key name - *
        • {@code } == varint encoded integer - *
        • {@code } == tag_val_len bytes comprising UTF-8 string - *
        - *
      • {@code (tag_field_id == 1) == } - *
          - *
        • {@code } == varint encoded integer - *
        • {@code } == tag_key_len bytes comprising tag key name - *
        • {@code } == 8 bytes, little-endian integer - *
        - *
      • {@code (tag_field_id == 2 || tag_field_id == 3) == } - *
          - *
        • {@code } == varint encoded integer - *
        • {@code } == tag_key_len bytes comprising tag key name - *
        - *
      - *
    - *
- */ -final class StatsSerializer { - - // TODO(songya): Currently we only support encoding on string type. - @VisibleForTesting static final int VERSION_ID = 0; - @VisibleForTesting static final int VALUE_TYPE_STRING = 0; - @VisibleForTesting static final int VALUE_TYPE_INTEGER = 1; - @VisibleForTesting static final int VALUE_TYPE_TRUE = 2; - @VisibleForTesting static final int VALUE_TYPE_FALSE = 3; - - - // Serializes a StatsContext to the on-the-wire format. - // Encoded tags are of the form: - static void serialize(StatsContextImpl context, OutputStream output) throws IOException { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - byteArrayOutputStream.write(VERSION_ID); - - // TODO(songya): add support for value types integer and boolean - Set> tags = context.tags.entrySet(); - for (Entry tag : tags) { - encodeStringTag(tag.getKey(), tag.getValue(), byteArrayOutputStream); - } - byteArrayOutputStream.writeTo(output); - } - - // Deserializes input to StatsContext based on the binary format standard. - // The encoded tags are of the form: - static StatsContextImpl deserialize(StatsRecorderImpl statsRecorder, InputStream input) - throws IOException { - try { - byte[] bytes = ByteStreams.toByteArray(input); - HashMap tags = new HashMap(); - if (bytes.length == 0) { - // Does not allow empty byte array. - throw new IOException("Input byte stream can not be empty."); - } - - ByteBuffer buffer = ByteBuffer.wrap(bytes).asReadOnlyBuffer(); - int versionId = buffer.get(); - if (versionId != VERSION_ID) { - throw new IOException( - "Wrong Version ID: " + versionId + ". Currently supported version is: " + VERSION_ID); - } - - int limit = buffer.limit(); - while (buffer.position() < limit) { - int type = buffer.get(); - switch (type) { - case VALUE_TYPE_STRING: - TagKey key = TagKey.create(decodeString(buffer)); - TagValue val = TagValue.create(decodeString(buffer)); - tags.put(key, val); - break; - case VALUE_TYPE_INTEGER: - case VALUE_TYPE_TRUE: - case VALUE_TYPE_FALSE: - default: - // TODO(songya): add support for value types integer and boolean - throw new IOException("Unsupported tag value type."); - } - } - return new StatsContextImpl(statsRecorder, tags); - } catch (BufferUnderflowException exn) { - throw new IOException(exn.toString()); // byte array format error. - } - } - - // TODO(songya): Currently we only support encoding on string type. - private static final void encodeStringTag( - TagKey key, TagValue value, ByteArrayOutputStream byteArrayOutputStream) - throws IOException { - byteArrayOutputStream.write(VALUE_TYPE_STRING); - encodeString(key.asString(), byteArrayOutputStream); - encodeString(value.asString(), byteArrayOutputStream); - } - - private static final void encodeString(String input, ByteArrayOutputStream byteArrayOutputStream) - throws IOException { - VarInt.putVarInt(input.length(), byteArrayOutputStream); - byteArrayOutputStream.write(input.getBytes("UTF-8")); - } - - private static final String decodeString(ByteBuffer buffer) { - int length = VarInt.getVarInt(buffer); - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < length; i++) { - builder.append((char) buffer.get()); - } - return builder.toString(); - } -} \ No newline at end of file diff --git a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java index 948622f18d..47b71faee1 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java @@ -17,10 +17,10 @@ import io.opencensus.common.Timestamp; import io.opencensus.stats.ViewData.WindowData.CumulativeData; +import io.opencensus.tags.TagKey.TagKeyString; import io.opencensus.testing.common.TestClock; import java.util.Arrays; import java.util.List; - import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -45,7 +45,7 @@ public class MeasureToViewMapTest { private static final View VIEW = View.create(VIEW_NAME, "view description", MEASURE, AGGREGATIONS_NO_HISTOGRAM, - Arrays.asList(TagKey.create("my key")), CUMULATIVE); + Arrays.asList(TagKeyString.create("my key")), CUMULATIVE); @Test public void testRegisterAndGetView() { diff --git a/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java b/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java index 35d86f47cb..3b5368ed7f 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java @@ -34,6 +34,8 @@ import io.opencensus.stats.MutableAggregation.MutableRange; import io.opencensus.stats.MutableAggregation.MutableStdDev; import io.opencensus.stats.MutableAggregation.MutableSum; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -48,21 +50,22 @@ public class MutableViewDataTest { private static final double EPSILON = 1e-7; - private static final TagKey ORIGINATOR = TagKey.create("originator"); - private static final TagKey CALLER = TagKey.create("caller"); - private static final TagKey METHOD = TagKey.create("method"); - private static final TagValue CALLER_V = TagValue.create("some caller"); - private static final TagValue METHOD_V = TagValue.create("some method"); + private static final TagKeyString ORIGINATOR = TagKeyString.create("originator"); + private static final TagKeyString CALLER = TagKeyString.create("caller"); + private static final TagKeyString METHOD = TagKeyString.create("method"); + private static final TagValueString CALLER_V = TagValueString.create("some caller"); + private static final TagValueString METHOD_V = TagValueString.create("some method"); @Test public void testConstants() { - assertThat(MutableViewData.UNKNOWN_TAG_VALUE.asString()).isEqualTo("unknown/not set"); + assertThat(MutableViewData.UNKNOWN_TAG_VALUE).isNull(); } @Test public void testGetTagValues() { - List columns = Arrays.asList(CALLER, METHOD, ORIGINATOR); - Map tags = ImmutableMap.of(CALLER, CALLER_V, METHOD, METHOD_V); + List columns = Arrays.asList(CALLER, METHOD, ORIGINATOR); + Map tags = + ImmutableMap.of(CALLER, CALLER_V, METHOD, METHOD_V); assertThat(MutableViewData.getTagValues(tags, columns)) .containsExactly(CALLER_V, METHOD_V, MutableViewData.UNKNOWN_TAG_VALUE) diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java deleted file mode 100644 index df06e2a212..0000000000 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextFactoryTest.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import io.grpc.Context; -import io.opencensus.common.Scope; -import io.opencensus.internal.SimpleEventQueue; -import io.opencensus.internal.VarInt; -import io.opencensus.testing.common.TestClock; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests for {@link StatsContextFactory}. - */ -@RunWith(JUnit4.class) -public class StatsContextFactoryTest { - - private static final String KEY = "Key"; - private static final String VALUE_STRING = "String"; - private static final int VALUE_INT = 10; - - private final StatsComponentImplBase statsComponent = - new StatsComponentImplBase(new SimpleEventQueue(), TestClock.create()); - private final StatsContextFactory factory = statsComponent.getStatsContextFactory(); - private final StatsRecorderImpl statsRecorder = statsComponent.getStatsRecorder(); - private final HashMap sampleTags = new HashMap(); - private final StatsContext defaultCtx = factory.getDefault(); - private final StatsContext statsContext = factory.getDefault() - .with(TagKey.create(KEY), TagValue.create(VALUE_STRING)); - - public StatsContextFactoryTest() { - sampleTags.put( - TagKey.create(KEY + StatsSerializer.VALUE_TYPE_STRING), TagValue.create(VALUE_STRING)); - } - - @Test - public void testVersionAndValueTypeConstants() { - // Refer to the JavaDoc on StatsSerializer for the definitions on these constants. - assertThat(StatsSerializer.VERSION_ID).isEqualTo(0); - assertThat(StatsSerializer.VALUE_TYPE_STRING).isEqualTo(0); - assertThat(StatsSerializer.VALUE_TYPE_INTEGER).isEqualTo(1); - assertThat(StatsSerializer.VALUE_TYPE_TRUE).isEqualTo(2); - assertThat(StatsSerializer.VALUE_TYPE_FALSE).isEqualTo(3); - } - - @Test - public void testDeserializeNoTags() throws Exception { - StatsContext expected = factory.getDefault(); - StatsContext actual = testDeserialize( - new ByteArrayInputStream( - new byte[]{StatsSerializer.VERSION_ID})); // One byte that represents Version ID. - assertThat(actual).isEqualTo(expected); - } - - @Test(expected = IOException.class) - public void testDeserializeEmptyByteArrayThrowException() throws Exception { - testDeserialize(new ByteArrayInputStream(new byte[0])); - } - - @Test - public void testDeserializeValueTypeString() throws Exception { - StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); - StatsContext actual = testDeserialize( - constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_STRING)); - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testDeserializeMultipleString() throws Exception { - sampleTags.put(TagKey.create("Key2"), TagValue.create("String2")); - - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - byteArrayOutputStream.write(StatsSerializer.VERSION_ID); - encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_STRING, byteArrayOutputStream); - byteArrayOutputStream.write(StatsSerializer.VALUE_TYPE_STRING); - encodeString("Key2", byteArrayOutputStream); - encodeString("String2", byteArrayOutputStream); - StatsContext actual = testDeserialize( - new ByteArrayInputStream(byteArrayOutputStream.toByteArray())); - - StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); - assertThat(actual).isEqualTo(expected); - } - - @Test(expected = IOException.class) - public void testDeserializeValueTypeInteger() throws Exception { - // TODO(songya): test should pass after we add support for type integer - testDeserialize(constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_INTEGER)); - } - - @Test(expected = IOException.class) - public void testDeserializeValueTypeTrue() throws Exception { - // TODO(songya): test should pass after we add support for type boolean - testDeserialize(constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_TRUE)); - } - - @Test(expected = IOException.class) - public void testDeserializeValueTypeFalse() throws Exception { - // TODO(songya): test should pass after we add support for type boolean - testDeserialize(constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_FALSE)); - } - - @Test(expected = IOException.class) - public void testDeserializeMultipleValueType() throws Exception { - // TODO(songya): test should pass after we add support for type integer and boolean - testDeserialize(constructMultiTypeTagInputStream()); - } - - @Test(expected = IOException.class) - public void testDeserializeWrongFormat() throws Exception { - // encoded tags should follow the format ()* - testDeserialize(new ByteArrayInputStream(new byte[3])); - } - - @Test(expected = IOException.class) - public void testDeserializeWrongVersionId() throws Exception { - testDeserialize(new ByteArrayInputStream(new byte[]{(byte) (StatsSerializer.VERSION_ID + 1)})); - } - - @Test - public void testGetDefaultForCurrentStatsContextWhenNotSet() { - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - } - - @Test - public void testGetCurrentStatsContext() { - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - Context origContext = Context.current().withValue( - CurrentStatsContextUtils.STATS_CONTEXT_KEY, statsContext) - .attach(); - // Make sure context is detached even if test fails. - try { - assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); - } finally { - Context.current().detach(origContext); - } - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - } - - @Test(expected = NullPointerException.class) - public void testWithNullStatsContext() { - factory.withStatsContext(null); - } - - @Test - public void testWithStatsContext() { - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - Scope scopedStatsCtx = factory.withStatsContext(statsContext); - try { - assertThat(factory.getCurrentStatsContext()).isEqualTo(statsContext); - } finally { - scopedStatsCtx.close(); - } - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - } - - @Test - public void testWithStatsContextUsingWrap() { - Runnable runnable; - Scope scopedStatsCtx = factory.withStatsContext(statsContext); - try { - assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); - runnable = Context.current().wrap( - new Runnable() { - @Override - public void run() { - assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); - } - }); - } finally { - scopedStatsCtx.close(); - } - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - // When we run the runnable we will have the statsContext in the current Context. - runnable.run(); - } - - private StatsContext testDeserialize(InputStream inputStream) - throws IOException { - return factory.deserialize(inputStream); - } - - /* - * Construct an InputStream with the given type of tag. - * The input format is: - * , and == ()* - * TODO(songya): after supporting serialize integer and boolean, - * remove this method and use StatsContext.serialize() instead. - * Currently StatsContext.serialize() can only serialize strings. - */ - private static InputStream constructSingleTypeTagInputStream(int valueType) throws IOException { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - byteArrayOutputStream.write(StatsSerializer.VERSION_ID); - encodeSingleTypeTagToOutputStream(valueType, byteArrayOutputStream); - return new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); - } - - // Construct an InputStream with all 4 types of tags. - private static InputStream constructMultiTypeTagInputStream() throws IOException { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - byteArrayOutputStream.write(StatsSerializer.VERSION_ID); - encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_STRING, byteArrayOutputStream); - encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_INTEGER, byteArrayOutputStream); - encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_TRUE, byteArrayOutputStream); - encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_FALSE, byteArrayOutputStream); - return new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); - } - - private static void encodeSingleTypeTagToOutputStream( - int valueType, ByteArrayOutputStream byteArrayOutputStream) throws IOException { - byteArrayOutputStream.write(valueType); - - // encode , tag key is a string "KEY" appended by the field id here. - encodeString(KEY + valueType, byteArrayOutputStream); - switch (valueType) { - case StatsSerializer.VALUE_TYPE_STRING: - // String encoded format: . - encodeString(VALUE_STRING, byteArrayOutputStream); - break; - case StatsSerializer.VALUE_TYPE_INTEGER: - // Integer encoded format: . - encodeInteger(VALUE_INT, byteArrayOutputStream); - break; - case StatsSerializer.VALUE_TYPE_TRUE: - case StatsSerializer.VALUE_TYPE_FALSE: - // Boolean encoded format: . No tag_value is needed - break; - default: - return; - } - } - - // (tag_field_id == 0) == - // - // == varint encoded integer - // == tag_key_len bytes comprising tag key name - // == varint encoded integer - // == tag_val_len bytes comprising UTF-8 string - private static void encodeString(String input, ByteArrayOutputStream byteArrayOutputStream) - throws IOException { - VarInt.putVarInt(input.length(), byteArrayOutputStream); - byteArrayOutputStream.write(input.getBytes("UTF-8")); - } - - // (tag_field_id == 1) == - // - // == varint encoded integer - // == tag_key_len bytes comprising tag key name - // == 8 bytes, little-endian integer - private static void encodeInteger(int input, ByteArrayOutputStream byteArrayOutputStream) { - byteArrayOutputStream.write((byte) input); - } -} diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java b/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java deleted file mode 100644 index a81857d571..0000000000 --- a/core_impl/src/test/java/io/opencensus/stats/StatsContextTest.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright 2016, Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.opencensus.stats; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.collect.Collections2; -import com.google.common.testing.EqualsTester; -import io.opencensus.internal.SimpleEventQueue; -import io.opencensus.internal.VarInt; -import io.opencensus.stats.Measure.MeasureLong; -import io.opencensus.testing.common.TestClock; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Tests for {@link StatsContext}. */ -@RunWith(JUnit4.class) -public class StatsContextTest { - - @Rule - public final ExpectedException thrown = ExpectedException.none(); - - private static final double TOLERANCE = 1e-6; - - private final StatsComponentImplBase statsComponent = - new StatsComponentImplBase(new SimpleEventQueue(), TestClock.create()); - private final ViewManager viewManager = statsComponent.getViewManager(); - private final StatsContextFactory factory = statsComponent.getStatsContextFactory(); - private final StatsContext defaultStatsContext = factory.getDefault(); - - private static final int VERSION_ID = 0; - private static final int VALUE_TYPE_STRING = 0; - - private static final TagKey K_EMPTY = TagKey.create(""); - private static final TagKey K1 = TagKey.create("k1"); - private static final TagKey K2 = TagKey.create("k2"); - private static final TagKey K3 = TagKey.create("k3"); - private static final TagKey K4 = TagKey.create("k4"); - private static final TagKey K10 = TagKey.create("k10"); - - private static final TagValue V_EMPTY = TagValue.create(""); - private static final TagValue V1 = TagValue.create("v1"); - private static final TagValue V2 = TagValue.create("v2"); - private static final TagValue V3 = TagValue.create("v3"); - private static final TagValue V4 = TagValue.create("v4"); - private static final TagValue V10 = TagValue.create("v10"); - private static final TagValue V20 = TagValue.create("v20"); - private static final TagValue V30 = TagValue.create("v30"); - private static final TagValue V100 = TagValue.create("v100"); - - private static final Tag T1 = Tag.create(K1, V1); - private static final Tag T2 = Tag.create(K2, V2); - private static final Tag T3 = Tag.create(K3, V3); - private static final Tag T4 = Tag.create(K4, V4); - - private static final List AGGREGATIONS_NO_HISTOGRAM = Arrays.asList( - Aggregation.Sum.create(), Aggregation.Count.create(), Aggregation.Range.create(), - Aggregation.Mean.create(), Aggregation.StdDev.create()); - - private static final View.Window.Cumulative CUMULATIVE = View.Window.Cumulative.create(); - - @Test - public void testWith() { - assertThat(defaultStatsContext.builder().set(K1, V1).build()) - .isEqualTo(defaultStatsContext.with(K1, V1)); - - assertThat(defaultStatsContext.builder().set(K1, V1).set(K2, V2).build()) - .isEqualTo(defaultStatsContext.with(K1, V1, K2, V2)); - - assertThat(defaultStatsContext.builder().set(K1, V1).set(K2, V2).set(K3, V3).build()) - .isEqualTo(defaultStatsContext.with(K1, V1, K2, V2, K3, V3)); - } - - @Test - public void testWithComposed() { - StatsContext context1 = defaultStatsContext.with(K1, V1); - assertThat(defaultStatsContext.builder().set(K1, V1).build()).isEqualTo(context1); - - StatsContext context2 = context1.with(K1, V10, K2, V2); - assertThat(defaultStatsContext.with(K1, V10, K2, V2)).isEqualTo(context2); - - StatsContext context3 = context2.with(K1, V100, K2, V20, K3, V3); - assertThat(defaultStatsContext.with(K1, V100, K2, V20, K3, V3)).isEqualTo(context3); - - StatsContext context4 = context3.with(K3, V30, K4, V4); - assertThat( - defaultStatsContext - .builder() - .set(K1, V100) - .set(K2, V20) - .set(K3, V30) - .set(K4, V4) - .build()) - .isEqualTo(context4); - } - - // The main tests for stats recording are in ViewManagerImplTest. - @Test - public void testRecordDouble() { - viewManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - ViewData beforeViewData = - viewManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - assertThat(beforeViewData.getAggregationMap()).isEmpty(); - StatsContext context = - defaultStatsContext.with( - RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); - MeasureMap measurements = - MeasureMap.builder() - .set(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); - context.record(measurements); - ViewData afterViewData = - viewManager.getView( - RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - assertThat(afterViewData.getAggregationMap()).hasSize(1); - for (Entry, List> entry : - afterViewData.getAggregationMap().entrySet()) { - assertThat(entry.getKey()).containsExactly(TagValue.create("myMethod")); - assertThat(entry.getValue()).hasSize(3); - StatsTestUtil.assertAggregationDataListEquals( - Arrays.asList( - AggregationData.SumData.create(5.1), - AggregationData.CountData.create(1), - AggregationData.HistogramData.create(0, 0, 0, 0, 0, 0, 1)), - entry.getValue(), - TOLERANCE); - } - } - - @Test - public void testRecordLong() { - MeasureLong measure = MeasureLong.create("long measure", "description", "1"); - viewManager.registerView(View.create( - View.Name.create("name"), "description", measure, AGGREGATIONS_NO_HISTOGRAM, - Arrays.asList(K1), CUMULATIVE)); - MeasureMap measureMap = MeasureMap.builder().set(measure, 1L).build(); - StatsContext context = defaultStatsContext.with(K1, V1); - thrown.expect(UnsupportedOperationException.class); - context.record(measureMap); - } - - @Test - public void testSerializeDefault() throws Exception { - testSerialize(); - } - - @Test - public void testSerializeWithOneStringTag() throws Exception { - testSerialize(T1); - } - - @Test - public void testSerializeWithMultiStringTags() throws Exception { - testSerialize(T1, T2, T3, T4); - } - - @Test - public void testRoundtripSerialization() throws Exception { - testRoundtripSerialization(defaultStatsContext.builder().build()); - testRoundtripSerialization(defaultStatsContext.with(K1, V1)); - testRoundtripSerialization(defaultStatsContext.with(K1, V1, K2, V2, K3, V3)); - testRoundtripSerialization(defaultStatsContext.with(K1, V_EMPTY)); - testRoundtripSerialization(defaultStatsContext.with(K_EMPTY, V1)); - testRoundtripSerialization(defaultStatsContext.with(K_EMPTY, V_EMPTY)); - } - - private void testRoundtripSerialization(StatsContext expected) throws Exception { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - expected.serialize(output); - ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); - StatsContext actual = factory.deserialize(input); - assertThat(actual).isEqualTo(expected); - } - - // Tests for Object overrides. - - @Test - public void testEquals() { - new EqualsTester() - .addEqualityGroup(defaultStatsContext, defaultStatsContext) - .addEqualityGroup(defaultStatsContext.with(K1, V1), defaultStatsContext.with(K1, V1)) - .addEqualityGroup( - defaultStatsContext.with(K1, V1, K2, V2), - defaultStatsContext.with(K1, V1, K2, V2), - defaultStatsContext.with(K2, V2, K1, V1)) - .addEqualityGroup(defaultStatsContext.with(K10, V1)) - .addEqualityGroup(defaultStatsContext.with(K1, V10)) - .addEqualityGroup("foo") - .testEquals(); - } - - @Test - public void testToString() { - assertThat(defaultStatsContext.with(K1, V1).toString()) - .isEqualTo(defaultStatsContext.with(K1, V1).toString()); - assertThat(defaultStatsContext.with(K10, V1).toString()) - .isNotEqualTo(defaultStatsContext.with(K1, V1).toString()); - assertThat(defaultStatsContext.with(K1, V10).toString()) - .isNotEqualTo(defaultStatsContext.with(K1, V1).toString()); - } - - private void testSerialize(Tag... tags) throws IOException { - StatsContext.Builder builder = defaultStatsContext.builder(); - for (Tag tag : tags) { - builder.set(tag.getKey(), tag.getValue()); - } - - ByteArrayOutputStream actual = new ByteArrayOutputStream(); - builder.build().serialize(actual); - - Collection> tagPermutation = Collections2.permutations(Arrays.asList(tags)); - Set possibleOutputs = new HashSet(); - for (List list : tagPermutation) { - ByteArrayOutputStream expected = new ByteArrayOutputStream(); - expected.write(VERSION_ID); - for (Tag tag : list) { - expected.write(VALUE_TYPE_STRING); - encodeString(tag.getKey().asString(), expected); - encodeString(tag.getValue().asString(), expected); - } - possibleOutputs.add(expected.toString()); - } - - assertThat(possibleOutputs).contains(actual.toString()); - } - - private static final void encodeString(String input, ByteArrayOutputStream byteArrayOutputStream) - throws IOException { - VarInt.putVarInt(input.length(), byteArrayOutputStream); - byteArrayOutputStream.write(input.getBytes("UTF-8")); - } -} diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java index 1567d8c6fc..f744771084 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java +++ b/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java @@ -33,32 +33,6 @@ final class StatsTestUtil { private StatsTestUtil() {} - static StatsContextImpl createContext( - StatsContextFactoryImpl factory, TagKey key, TagValue value) { - return createContext(factory, Tag.create(key, value)); - } - - static StatsContextImpl createContext( - StatsContextFactoryImpl factory, TagKey key1, TagValue value1, TagKey key2, TagValue value2) { - return createContext(factory, Tag.create(key1, value1), Tag.create(key2, value2)); - } - - /** - * Creates a {@code StatsContextImpl} from a factory and a list tags. - * - * @param factory the factory used to produce the {@code StatsContextImpl}. - * @param tags a list of tags to add to the {@code StatsContextImpl}. - * @return a {@code StatsContextImpl} with the given tags. - */ - private static StatsContextImpl createContext( - StatsContextFactoryImpl factory, Tag... tags) { - StatsContextImpl.Builder builder = factory.getDefault().builder(); - for (Tag tag : tags) { - builder.set(tag.getKey(), tag.getValue()); - } - return builder.build(); - } - /** * Creates a list of {@link AggregationData}s by adding the given sequence of values, based on the * definition of the given {@link Aggregation}s. @@ -89,11 +63,11 @@ static List createAggregationData( * @param tolerance the tolerance used for {@code double} comparison. */ static void assertAggregationMapEquals( - Map, List> actual, - Map, List> expected, + Map, List> actual, + Map, List> expected, double tolerance) { assertThat(actual.keySet()).containsExactlyElementsIn(expected.keySet()); - for (List tagValues : actual.keySet()) { + for (List tagValues : actual.keySet()) { assertAggregationDataListEquals(expected.get(tagValues), actual.get(tagValues), tolerance); } } diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index 8688cd99e2..190072ea5e 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -14,11 +14,11 @@ package io.opencensus.stats; import static com.google.common.truth.Truth.assertThat; -import static io.opencensus.stats.StatsTestUtil.createContext; import com.google.common.collect.ImmutableMap; import io.opencensus.common.Duration; import io.opencensus.common.Timestamp; +import io.opencensus.impl.tags.TagContextsImpl; import io.opencensus.internal.SimpleEventQueue; import io.opencensus.stats.Aggregation.Count; import io.opencensus.stats.Aggregation.Histogram; @@ -30,6 +30,10 @@ import io.opencensus.stats.View.Window.Cumulative; import io.opencensus.stats.View.Window.Interval; import io.opencensus.stats.ViewData.WindowData.CumulativeData; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContexts; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; import io.opencensus.testing.common.TestClock; import java.util.Arrays; import java.util.Collections; @@ -44,13 +48,12 @@ @RunWith(JUnit4.class) public class ViewManagerImplTest { - @Rule - public final ExpectedException thrown = ExpectedException.none(); + @Rule public final ExpectedException thrown = ExpectedException.none(); - private static final TagKey KEY = TagKey.create("KEY"); + private static final TagKeyString KEY = TagKeyString.create("KEY"); - private static final TagValue VALUE = TagValue.create("VALUE"); - private static final TagValue VALUE_2 = TagValue.create("VALUE_2"); + private static final TagValueString VALUE = TagValueString.create("VALUE"); + private static final TagValueString VALUE_2 = TagValueString.create("VALUE_2"); private static final String MEASURE_NAME = "my measurement"; @@ -71,39 +74,38 @@ public class ViewManagerImplTest { private static final Cumulative CUMULATIVE = Cumulative.create(); private static final double EPSILON = 1e-7; - + private static final BucketBoundaries BUCKET_BOUNDARIES = BucketBoundaries.create( Arrays.asList( 0.0, 0.2, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0)); private static final List AGGREGATIONS = - Collections.unmodifiableList(Arrays.asList( - Sum.create(), Count.create(), Range.create(), - Histogram.create(BUCKET_BOUNDARIES), Mean.create(), - StdDev.create())); + Collections.unmodifiableList( + Arrays.asList( + Sum.create(), + Count.create(), + Range.create(), + Histogram.create(BUCKET_BOUNDARIES), + Mean.create(), + StdDev.create())); private final TestClock clock = TestClock.create(); private final StatsComponentImplBase statsComponent = new StatsComponentImplBase(new SimpleEventQueue(), clock); - private final StatsContextFactoryImpl factory = statsComponent.getStatsContextFactory(); + private final TagContexts tagContexts = new TagContextsImpl(); private final ViewManagerImpl viewManager = statsComponent.getViewManager(); private final StatsRecorder statsRecorder = statsComponent.getStatsRecorder(); private static View createCumulativeView() { - return createCumulativeView( - VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(KEY)); + return createCumulativeView(VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(KEY)); } private static View createCumulativeView( - View.Name name, - Measure measure, - List aggregations, - List keys) { - return View.create( - name, VIEW_DESCRIPTION, measure, aggregations, keys, CUMULATIVE); + View.Name name, Measure measure, List aggregations, List keys) { + return View.create(name, VIEW_DESCRIPTION, measure, aggregations, keys, CUMULATIVE); } @Test @@ -139,12 +141,7 @@ public void allowRegisteringSameViewTwice() { public void preventRegisteringDifferentViewWithSameName() { View view1 = View.create( - VIEW_NAME, - "View description.", - MEASURE, - AGGREGATIONS, - Arrays.asList(KEY), - CUMULATIVE); + VIEW_NAME, "View description.", MEASURE, AGGREGATIONS, Arrays.asList(KEY), CUMULATIVE); viewManager.registerView(view1); View view2 = View.create( @@ -171,15 +168,10 @@ public void disallowGettingNonexistentViewData() { @Test public void testRecord() { - View view = - createCumulativeView( - VIEW_NAME, - MEASURE, - AGGREGATIONS, - Arrays.asList(KEY)); + View view = createCumulativeView(VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 2)); viewManager.registerView(view); - StatsContextImpl tags = createContext(factory, KEY, VALUE); + TagContext tags = tagContexts.emptyBuilder().set(KEY, VALUE).build(); double[] values = {10.0, 20.0, 30.0, 40.0}; for (double val : values) { statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, val).build()); @@ -187,37 +179,30 @@ public void testRecord() { clock.setTime(Timestamp.create(3, 4)); ViewData viewData = viewManager.getView(VIEW_NAME); assertThat(viewData.getView()).isEqualTo(view); - assertThat(viewData.getWindowData()).isEqualTo( - CumulativeData.create(Timestamp.create(1, 2), Timestamp.create(3, 4))); + assertThat(viewData.getWindowData()) + .isEqualTo(CumulativeData.create(Timestamp.create(1, 2), Timestamp.create(3, 4))); StatsTestUtil.assertAggregationMapEquals( viewData.getAggregationMap(), ImmutableMap.of( - Arrays.asList(VALUE), - StatsTestUtil.createAggregationData(AGGREGATIONS, values)), + Arrays.asList(VALUE), StatsTestUtil.createAggregationData(AGGREGATIONS, values)), EPSILON); } @Test public void getViewDoesNotClearStats() { - View view = - createCumulativeView( - VIEW_NAME, - MEASURE, - AGGREGATIONS, - Arrays.asList(KEY)); + View view = createCumulativeView(VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(KEY)); clock.setTime(Timestamp.create(10, 0)); viewManager.registerView(view); - StatsContextImpl tags = createContext(factory, KEY, VALUE); + TagContext tags = tagContexts.emptyBuilder().set(KEY, VALUE).build(); statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.1).build()); clock.setTime(Timestamp.create(11, 0)); ViewData viewData1 = viewManager.getView(VIEW_NAME); - assertThat(viewData1.getWindowData()).isEqualTo( - CumulativeData.create(Timestamp.create(10, 0), Timestamp.create(11, 0))); + assertThat(viewData1.getWindowData()) + .isEqualTo(CumulativeData.create(Timestamp.create(10, 0), Timestamp.create(11, 0))); StatsTestUtil.assertAggregationMapEquals( viewData1.getAggregationMap(), ImmutableMap.of( - Arrays.asList(VALUE), - StatsTestUtil.createAggregationData(AGGREGATIONS, 0.1)), + Arrays.asList(VALUE), StatsTestUtil.createAggregationData(AGGREGATIONS, 0.1)), EPSILON); statsRecorder.record(tags, MeasureMap.builder().set(MEASURE, 0.2).build()); @@ -226,32 +211,27 @@ public void getViewDoesNotClearStats() { // The second view should have the same start time as the first view, and it should include both // recorded values: - assertThat(viewData2.getWindowData()).isEqualTo( - CumulativeData.create(Timestamp.create(10, 0), Timestamp.create(12, 0))); + assertThat(viewData2.getWindowData()) + .isEqualTo(CumulativeData.create(Timestamp.create(10, 0), Timestamp.create(12, 0))); StatsTestUtil.assertAggregationMapEquals( viewData2.getAggregationMap(), ImmutableMap.of( - Arrays.asList(VALUE), - StatsTestUtil.createAggregationData(AGGREGATIONS, 0.1, 0.2)), + Arrays.asList(VALUE), StatsTestUtil.createAggregationData(AGGREGATIONS, 0.1, 0.2)), EPSILON); } @Test public void testRecordMultipleTagValues() { viewManager.registerView( - createCumulativeView( - VIEW_NAME, - MEASURE, - AGGREGATIONS, - Arrays.asList(KEY))); + createCumulativeView(VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(KEY))); statsRecorder.record( - createContext(factory, KEY, VALUE), + tagContexts.emptyBuilder().set(KEY, VALUE).build(), MeasureMap.builder().set(MEASURE, 10.0).build()); statsRecorder.record( - createContext(factory, KEY, VALUE_2), + tagContexts.emptyBuilder().set(KEY, VALUE_2).build(), MeasureMap.builder().set(MEASURE, 30.0).build()); statsRecorder.record( - createContext(factory, KEY, VALUE_2), + tagContexts.emptyBuilder().set(KEY, VALUE_2).build(), MeasureMap.builder().set(MEASURE, 50.0).build()); ViewData viewData = viewManager.getView(VIEW_NAME); StatsTestUtil.assertAggregationMapEquals( @@ -269,21 +249,16 @@ public void testRecordMultipleTagValues() { @Test public void allowRecordingWithoutRegisteringMatchingViewData() { statsRecorder.record( - createContext(factory, KEY, VALUE), + tagContexts.emptyBuilder().set(KEY, VALUE).build(), MeasureMap.builder().set(MEASURE, 10).build()); } @Test public void testRecordWithEmptyStatsContext() { viewManager.registerView( - createCumulativeView( - VIEW_NAME, - MEASURE, - AGGREGATIONS, - Arrays.asList(KEY))); + createCumulativeView(VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(KEY))); // DEFAULT doesn't have tags, but the view has tag key "KEY". - statsRecorder.record(factory.getDefault(), - MeasureMap.builder().set(MEASURE, 10.0).build()); + statsRecorder.record(tagContexts.empty(), MeasureMap.builder().set(MEASURE, 10.0).build()); ViewData viewData = viewManager.getView(VIEW_NAME); StatsTestUtil.assertAggregationMapEquals( viewData.getAggregationMap(), @@ -304,9 +279,9 @@ public void testRecordWithNonExistentMeasurement() { Measure.MeasureDouble.create(MEASURE_NAME, "measure", MEASURE_UNIT), AGGREGATIONS, Arrays.asList(KEY))); - MeasureDouble measure2 = - Measure.MeasureDouble.create(MEASURE_NAME_2, "measure", MEASURE_UNIT); - statsRecorder.record(createContext(factory, KEY, VALUE), + MeasureDouble measure2 = Measure.MeasureDouble.create(MEASURE_NAME_2, "measure", MEASURE_UNIT); + statsRecorder.record( + tagContexts.emptyBuilder().set(KEY, VALUE).build(), MeasureMap.builder().set(measure2, 10.0).build()); ViewData view = viewManager.getView(VIEW_NAME); assertThat(view.getAggregationMap()).isEmpty(); @@ -315,16 +290,12 @@ public void testRecordWithNonExistentMeasurement() { @Test public void testRecordWithTagsThatDoNotMatchViewData() { viewManager.registerView( - createCumulativeView( - VIEW_NAME, - MEASURE, - AGGREGATIONS, - Arrays.asList(KEY))); + createCumulativeView(VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(KEY))); statsRecorder.record( - createContext(factory, TagKey.create("wrong key"), VALUE), + tagContexts.emptyBuilder().set(TagKeyString.create("wrong key"), VALUE).build(), MeasureMap.builder().set(MEASURE, 10.0).build()); statsRecorder.record( - createContext(factory, TagKey.create("another wrong key"), VALUE), + tagContexts.emptyBuilder().set(TagKeyString.create("another wrong key"), VALUE).build(), MeasureMap.builder().set(MEASURE, 50.0).build()); ViewData viewData = viewManager.getView(VIEW_NAME); StatsTestUtil.assertAggregationMapEquals( @@ -340,79 +311,79 @@ public void testRecordWithTagsThatDoNotMatchViewData() { @Test public void testViewDataWithMultipleTagKeys() { - TagKey key1 = TagKey.create("Key-1"); - TagKey key2 = TagKey.create("Key-2"); + TagKeyString key1 = TagKeyString.create("Key-1"); + TagKeyString key2 = TagKeyString.create("Key-2"); viewManager.registerView( - createCumulativeView( - VIEW_NAME, - MEASURE, - AGGREGATIONS, - Arrays.asList(key1, key2))); + createCumulativeView(VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(key1, key2))); statsRecorder.record( - createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), + tagContexts + .emptyBuilder() + .set(key1, TagValueString.create("v1")) + .set(key2, TagValueString.create("v10")) + .build(), MeasureMap.builder().set(MEASURE, 1.1).build()); statsRecorder.record( - createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v20")), + tagContexts + .emptyBuilder() + .set(key1, TagValueString.create("v1")) + .set(key2, TagValueString.create("v20")) + .build(), MeasureMap.builder().set(MEASURE, 2.2).build()); statsRecorder.record( - createContext(factory, key1, TagValue.create("v2"), key2, TagValue.create("v10")), + tagContexts + .emptyBuilder() + .set(key1, TagValueString.create("v2")) + .set(key2, TagValueString.create("v10")) + .build(), MeasureMap.builder().set(MEASURE, 3.3).build()); statsRecorder.record( - createContext(factory, key1, TagValue.create("v1"), key2, TagValue.create("v10")), + tagContexts + .emptyBuilder() + .set(key1, TagValueString.create("v1")) + .set(key2, TagValueString.create("v10")) + .build(), MeasureMap.builder().set(MEASURE, 4.4).build()); ViewData viewData = viewManager.getView(VIEW_NAME); StatsTestUtil.assertAggregationMapEquals( viewData.getAggregationMap(), ImmutableMap.of( - Arrays.asList(TagValue.create("v1"), TagValue.create("v10")), + Arrays.asList(TagValueString.create("v1"), TagValueString.create("v10")), StatsTestUtil.createAggregationData(AGGREGATIONS, 1.1, 4.4), - Arrays.asList(TagValue.create("v1"), TagValue.create("v20")), + Arrays.asList(TagValueString.create("v1"), TagValueString.create("v20")), StatsTestUtil.createAggregationData(AGGREGATIONS, 2.2), - Arrays.asList(TagValue.create("v2"), TagValue.create("v10")), + Arrays.asList(TagValueString.create("v2"), TagValueString.create("v10")), StatsTestUtil.createAggregationData(AGGREGATIONS, 3.3)), EPSILON); } @Test public void testMultipleViewSameMeasure() { - final View view1 = - createCumulativeView( - VIEW_NAME, - MEASURE, - AGGREGATIONS, - Arrays.asList(KEY)); - final View view2 = - createCumulativeView( - VIEW_NAME_2, - MEASURE, - AGGREGATIONS, - Arrays.asList(KEY)); + final View view1 = createCumulativeView(VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(KEY)); + final View view2 = createCumulativeView(VIEW_NAME_2, MEASURE, AGGREGATIONS, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 1)); viewManager.registerView(view1); clock.setTime(Timestamp.create(2, 2)); viewManager.registerView(view2); statsRecorder.record( - createContext(factory, KEY, VALUE), + tagContexts.emptyBuilder().set(KEY, VALUE).build(), MeasureMap.builder().set(MEASURE, 5.0).build()); clock.setTime(Timestamp.create(3, 3)); ViewData viewData1 = viewManager.getView(VIEW_NAME); clock.setTime(Timestamp.create(4, 4)); ViewData viewData2 = viewManager.getView(VIEW_NAME_2); - assertThat(viewData1.getWindowData()).isEqualTo( - CumulativeData.create(Timestamp.create(1, 1), Timestamp.create(3, 3))); + assertThat(viewData1.getWindowData()) + .isEqualTo(CumulativeData.create(Timestamp.create(1, 1), Timestamp.create(3, 3))); StatsTestUtil.assertAggregationMapEquals( viewData1.getAggregationMap(), ImmutableMap.of( - Arrays.asList(VALUE), - StatsTestUtil.createAggregationData(AGGREGATIONS, 5.0)), + Arrays.asList(VALUE), StatsTestUtil.createAggregationData(AGGREGATIONS, 5.0)), EPSILON); - assertThat(viewData2.getWindowData()).isEqualTo( - CumulativeData.create(Timestamp.create(2, 2), Timestamp.create(4, 4))); + assertThat(viewData2.getWindowData()) + .isEqualTo(CumulativeData.create(Timestamp.create(2, 2), Timestamp.create(4, 4))); StatsTestUtil.assertAggregationMapEquals( viewData2.getAggregationMap(), ImmutableMap.of( - Arrays.asList(VALUE), - StatsTestUtil.createAggregationData(AGGREGATIONS, 5.0)), + Arrays.asList(VALUE), StatsTestUtil.createAggregationData(AGGREGATIONS, 5.0)), EPSILON); } @@ -422,59 +393,51 @@ public void testMultipleViewsDifferentMeasures() { Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); MeasureDouble measure2 = Measure.MeasureDouble.create(MEASURE_NAME_2, MEASURE_DESCRIPTION, MEASURE_UNIT); - final View view1 = - createCumulativeView( - VIEW_NAME, measure1, AGGREGATIONS, Arrays.asList(KEY)); + final View view1 = createCumulativeView(VIEW_NAME, measure1, AGGREGATIONS, Arrays.asList(KEY)); final View view2 = - createCumulativeView( - VIEW_NAME_2, measure2, AGGREGATIONS, Arrays.asList(KEY)); + createCumulativeView(VIEW_NAME_2, measure2, AGGREGATIONS, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); viewManager.registerView(view1); clock.setTime(Timestamp.create(2, 0)); viewManager.registerView(view2); statsRecorder.record( - createContext(factory, KEY, VALUE), + tagContexts.emptyBuilder().set(KEY, VALUE).build(), MeasureMap.builder().set(measure1, 1.1).set(measure2, 2.2).build()); clock.setTime(Timestamp.create(3, 0)); ViewData viewData1 = viewManager.getView(VIEW_NAME); clock.setTime(Timestamp.create(4, 0)); ViewData viewData2 = viewManager.getView(VIEW_NAME_2); - assertThat(viewData1.getWindowData()).isEqualTo( - CumulativeData.create(Timestamp.create(1, 0), Timestamp.create(3, 0))); + assertThat(viewData1.getWindowData()) + .isEqualTo(CumulativeData.create(Timestamp.create(1, 0), Timestamp.create(3, 0))); StatsTestUtil.assertAggregationMapEquals( viewData1.getAggregationMap(), ImmutableMap.of( - Arrays.asList(VALUE), - StatsTestUtil.createAggregationData(AGGREGATIONS, 1.1)), + Arrays.asList(VALUE), StatsTestUtil.createAggregationData(AGGREGATIONS, 1.1)), EPSILON); - assertThat(viewData2.getWindowData()).isEqualTo( - CumulativeData.create(Timestamp.create(2, 0), Timestamp.create(4, 0))); + assertThat(viewData2.getWindowData()) + .isEqualTo(CumulativeData.create(Timestamp.create(2, 0), Timestamp.create(4, 0))); StatsTestUtil.assertAggregationMapEquals( viewData2.getAggregationMap(), ImmutableMap.of( - Arrays.asList(VALUE), - StatsTestUtil.createAggregationData(AGGREGATIONS, 2.2)), + Arrays.asList(VALUE), StatsTestUtil.createAggregationData(AGGREGATIONS, 2.2)), EPSILON); } @Test public void testGetCumulativeViewDataWithoutBucketBoundaries() { - List aggregationsNoHistogram = Arrays.asList( - Sum.create(), Count.create(), Mean.create(), Range.create(), StdDev.create()); + List aggregationsNoHistogram = + Arrays.asList(Sum.create(), Count.create(), Mean.create(), Range.create(), StdDev.create()); View view = - createCumulativeView( - VIEW_NAME, MEASURE, - aggregationsNoHistogram, - Arrays.asList(KEY)); + createCumulativeView(VIEW_NAME, MEASURE, aggregationsNoHistogram, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); viewManager.registerView(view); statsRecorder.record( - createContext(factory, KEY, VALUE), + tagContexts.emptyBuilder().set(KEY, VALUE).build(), MeasureMap.builder().set(MEASURE, 1.1).build()); clock.setTime(Timestamp.create(3, 0)); ViewData viewData = viewManager.getView(VIEW_NAME); - assertThat(viewData.getWindowData()).isEqualTo( - CumulativeData.create(Timestamp.create(1, 0), Timestamp.create(3, 0))); + assertThat(viewData.getWindowData()) + .isEqualTo(CumulativeData.create(Timestamp.create(1, 0), Timestamp.create(3, 0))); StatsTestUtil.assertAggregationMapEquals( viewData.getAggregationMap(), ImmutableMap.of( diff --git a/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java b/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java index 8c423d80c6..af932ea79a 100644 --- a/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java +++ b/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java @@ -33,9 +33,4 @@ public void getStatsRecorder() { public void getViewManager() { assertThat(Stats.getViewManager()).isInstanceOf(ViewManagerImpl.class); } - - @Test - public void getStatsContextFactory() { - assertThat(Stats.getStatsContextFactory()).isInstanceOf(StatsContextFactoryImpl.class); - } } diff --git a/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java b/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java index 8002c2f755..28752964d1 100644 --- a/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java +++ b/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java @@ -31,9 +31,4 @@ public void getStatsRecorder() { public void getViewManager() { assertThat(Stats.getViewManager()).isInstanceOf(ViewManagerImpl.class); } - - @Test - public void getStatsContextFactory() { - assertThat(Stats.getStatsContextFactory()).isInstanceOf(StatsContextFactoryImpl.class); - } } diff --git a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java index 3c6e4f4e6c..c735dfd040 100644 --- a/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java +++ b/examples/src/main/java/io/opencensus/examples/stats/StatsRunner.java @@ -13,63 +13,58 @@ package io.opencensus.examples.stats; -import io.opencensus.common.Scope; import io.opencensus.stats.Measure.MeasureDouble; -import io.opencensus.stats.MeasureMap; -import io.opencensus.stats.Stats; -import io.opencensus.stats.StatsContext; -import io.opencensus.stats.StatsContextFactory; -import io.opencensus.stats.TagKey; -import io.opencensus.stats.TagValue; +import io.opencensus.tags.TagContexts; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; +import io.opencensus.tags.Tags; -/** - * Simple program that uses Stats contexts. - */ +/** Simple program that uses Stats contexts. */ public class StatsRunner { - private static final TagKey K1 = TagKey.create("k1"); - private static final TagKey K2 = TagKey.create("k2"); - private static final TagKey K3 = TagKey.create("k3"); - private static final TagKey K4 = TagKey.create("k4"); + private static final TagKeyString K1 = TagKeyString.create("k1"); + private static final TagKeyString K2 = TagKeyString.create("k2"); + private static final TagKeyString K3 = TagKeyString.create("k3"); + private static final TagKeyString K4 = TagKeyString.create("k4"); - private static final TagValue V1 = TagValue.create("v1"); - private static final TagValue V2 = TagValue.create("v2"); - private static final TagValue V3 = TagValue.create("v3"); - private static final TagValue V4 = TagValue.create("v4"); + private static final TagValueString V1 = TagValueString.create("v1"); + private static final TagValueString V2 = TagValueString.create("v2"); + private static final TagValueString V3 = TagValueString.create("v3"); + private static final TagValueString V4 = TagValueString.create("v4"); private static final String UNIT = "1"; - private static final MeasureDouble M1 = - MeasureDouble.create("m1", "1st test metric", UNIT); - private static final MeasureDouble M2 = - MeasureDouble.create("m2", "2nd test metric", UNIT); + private static final MeasureDouble M1 = MeasureDouble.create("m1", "1st test metric", UNIT); + private static final MeasureDouble M2 = MeasureDouble.create("m2", "2nd test metric", UNIT); - private static final StatsContextFactory factory = Stats.getStatsContextFactory(); - private static final StatsContext DEFAULT = factory.getDefault(); + private static final TagContexts tagContexts = Tags.getTagContexts(); /** * Main method. * * @param args the main arguments. */ + // TODO(sebright): Uncomment all code in this method once we add methods that work with the + // current TagContext. public static void main(String[] args) { System.out.println("Hello Stats World"); - System.out.println("Default Tags: " + DEFAULT); - System.out.println("Current Tags: " + factory.getCurrentStatsContext()); - StatsContext tags1 = DEFAULT.with(K1, V1, K2, V2); - try (Scope scopedStatsCtx1 = factory.withStatsContext(tags1)) { - System.out.println(" Current Tags: " + factory.getCurrentStatsContext()); - System.out.println( - " Current == Default + tags1: " + factory.getCurrentStatsContext().equals(tags1)); - StatsContext tags2 = tags1.with(K3, V3, K4, V4); - try (Scope scopedStatsCtx2 = factory.withStatsContext(tags2)) { - System.out.println(" Current Tags: " + factory.getCurrentStatsContext()); - System.out.println( - " Current == Default + tags1 + tags2: " - + factory.getCurrentStatsContext().equals(tags2)); - factory.getCurrentStatsContext().record( - MeasureMap.builder().set(M1, 0.2).set(M2, 0.4).build()); - } - } - System.out.println("Current == Default: " + factory.getCurrentStatsContext().equals(DEFAULT)); + System.out.println("Default Tags: " + tagContexts.empty()); + // System.out.println("Current Tags: " + factory.getCurrentStatsContext()); + // TagContext tags1 = tagContexts.emptyBuilder().set(K1, V1).set(K2, V2).build(); + // try (Scope scopedStatsCtx1 = factory.withStatsContext(tags1)) { + // System.out.println(" Current Tags: " + factory.getCurrentStatsContext()); + // System.out.println( + // " Current == Default + tags1: " + factory.getCurrentStatsContext().equals(tags1)); + // TagContext tags2 = tagContexts.toBuilder(tags1).set(K3, V3).set(K4, V4).build(); + // try (Scope scopedStatsCtx2 = factory.withStatsContext(tags2)) { + // System.out.println(" Current Tags: " + factory.getCurrentStatsContext()); + // System.out.println( + // " Current == Default + tags1 + tags2: " + // + factory.getCurrentStatsContext().equals(tags2)); + // factory.getCurrentStatsContext().record( + // MeasureMap.builder().set(M1, 0.2).set(M2, 0.4).build()); + // } + // } + // System.out.println("Current == Default: " + + // factory.getCurrentStatsContext().equals(DEFAULT)); } } From 3b5ec6e482575bd6be1572c7ef65c7b7ab832320 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 15 Aug 2017 13:45:20 -0700 Subject: [PATCH 0386/1581] Move tracing implementation classes to io.opencensus.impl.trace. This is part of #379. The package name may still need to be changed again, but this commit includes all of the changes necessary to put the API and implementation in separate packages. Other changes in this commit: - Make TraceComponent's constructor public. - Leave deprecated copies of the TraceComponent subclasses in the io.opencensus.trace package so that they can be loaded by opencensus-api 0.5. - Move internal classes to io.opencensus.impl.internal. - Make TraceComponentImplBase and BinaryFormatImpl public. --- .../io/opencensus/trace/TraceComponent.java | 3 -- .../java/io/opencensus/trace/Tracing.java | 4 +-- ...ordTraceEventsNonSampledSpanBenchmark.java | 1 + ...RecordTraceEventsSampledSpanBenchmark.java | 1 + .../trace/StartEndSpanBenchmark.java | 1 + .../BinaryPropagationImplBenchmark.java | 1 + .../stats/StatsComponentImplBase.java | 2 +- .../io/opencensus/stats/StatsManager.java | 2 +- .../opencensus/stats/ViewManagerImplTest.java | 2 +- .../stats/StatsComponentImplLite.java | 4 +-- .../opencensus/stats/StatsComponentImpl.java | 4 +-- .../internal/DisruptorEventQueue.java | 3 +- .../impl/trace/TraceComponentImpl.java | 32 +++++++++++++++++++ .../opencensus/trace/TraceComponentImpl.java | 8 +++-- .../internal/ThreadLocalRandomHandler.java | 1 + .../{ => impl}/trace/TracingTest.java | 8 +++-- .../internal/DisruptorEventQueueTest.java | 2 ++ .../{ => impl}/common/MillisClock.java | 4 ++- .../{ => impl}/internal/EventQueue.java | 2 +- .../{ => impl}/internal/SimpleEventQueue.java | 2 +- .../internal/TimestampConverter.java | 2 +- .../{ => impl}/internal/VarInt.java | 2 +- .../{ => impl}/trace/SpanBuilderImpl.java | 14 ++++++-- .../opencensus/{ => impl}/trace/SpanImpl.java | 16 ++++++++-- .../{ => impl}/trace/StartEndHandlerImpl.java | 12 +++---- .../trace/TraceComponentImplBase.java | 29 +++++++++++------ .../{ => impl}/trace/TracerImpl.java | 8 +++-- .../trace/config/TraceConfigImpl.java | 5 ++- .../trace/export/ExportComponentImpl.java | 5 ++- .../trace/export/RunningSpanStoreImpl.java | 8 +++-- .../trace/export/SampledSpanStoreImpl.java | 6 ++-- .../trace/export/SpanExporterImpl.java | 7 ++-- .../internal/ConcurrentIntrusiveList.java | 4 +-- .../trace/internal/RandomHandler.java | 2 +- .../trace/propagation/BinaryFormatImpl.java | 7 ++-- .../propagation/PropagationComponentImpl.java | 5 ++- .../internal/TimestampConverterTest.java | 3 +- .../{ => impl}/trace/SpanBuilderImplTest.java | 11 +++++-- .../{ => impl}/trace/SpanImplTest.java | 16 ++++++++-- .../trace/TraceComponentImplBaseTest.java | 15 +++++---- .../{ => impl}/trace/TracerImplTest.java | 9 ++++-- .../trace/config/TraceConfigImplTest.java | 4 ++- .../trace/export/ExportComponentImplTest.java | 3 +- .../export/RunningSpanStoreImplTest.java | 12 +++---- .../export/SampledSpanStoreImplTest.java | 7 ++-- .../trace/export/SpanExporterImplTest.java | 13 ++++---- .../internal/ConcurrentIntrusiveListTest.java | 5 +-- .../propagation/BinaryFormatImplTest.java | 3 +- .../PropagationComponentImplTest.java | 3 +- .../impl/trace/TraceComponentImplLite.java | 27 ++++++++++++++++ .../trace/TraceComponentImplLite.java | 10 ++++-- .../trace/TraceComponentImplLiteTest.java | 9 +++--- 52 files changed, 261 insertions(+), 108 deletions(-) rename impl/src/main/java/io/opencensus/{ => impl}/internal/DisruptorEventQueue.java (98%) create mode 100644 impl/src/main/java/io/opencensus/impl/trace/TraceComponentImpl.java rename impl/src/test/java/io/opencensus/{ => impl}/trace/TracingTest.java (87%) rename impl_core/src/main/java/io/opencensus/{ => impl}/common/MillisClock.java (91%) rename impl_core/src/main/java/io/opencensus/{ => impl}/internal/EventQueue.java (96%) rename impl_core/src/main/java/io/opencensus/{ => impl}/internal/SimpleEventQueue.java (95%) rename impl_core/src/main/java/io/opencensus/{ => impl}/internal/TimestampConverter.java (97%) rename impl_core/src/main/java/io/opencensus/{ => impl}/internal/VarInt.java (99%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/SpanBuilderImpl.java (93%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/SpanImpl.java (96%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/StartEndHandlerImpl.java (93%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/TraceComponentImplBase.java (70%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/TracerImpl.java (86%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/config/TraceConfigImpl.java (90%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/export/ExportComponentImpl.java (92%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/export/RunningSpanStoreImpl.java (92%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/export/SampledSpanStoreImpl.java (98%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/export/SpanExporterImpl.java (96%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/internal/ConcurrentIntrusiveList.java (97%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/internal/RandomHandler.java (97%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/propagation/BinaryFormatImpl.java (96%) rename impl_core/src/main/java/io/opencensus/{ => impl}/trace/propagation/PropagationComponentImpl.java (84%) rename impl_core/src/test/java/io/opencensus/{ => impl}/internal/TimestampConverterTest.java (94%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/SpanBuilderImplTest.java (95%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/SpanImplTest.java (97%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/TraceComponentImplBaseTest.java (77%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/TracerImplTest.java (86%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/config/TraceConfigImplTest.java (92%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/export/ExportComponentImplTest.java (95%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/export/RunningSpanStoreImplTest.java (95%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/export/SampledSpanStoreImplTest.java (98%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/export/SpanExporterImplTest.java (96%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/internal/ConcurrentIntrusiveListTest.java (95%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/propagation/BinaryFormatImplTest.java (98%) rename impl_core/src/test/java/io/opencensus/{ => impl}/trace/propagation/PropagationComponentImplTest.java (91%) create mode 100644 impl_lite/src/main/java/io/opencensus/impl/trace/TraceComponentImplLite.java rename impl_lite/src/test/java/io/opencensus/{ => impl}/trace/TraceComponentImplLiteTest.java (85%) diff --git a/api/src/main/java/io/opencensus/trace/TraceComponent.java b/api/src/main/java/io/opencensus/trace/TraceComponent.java index 276999ccd3..033de24d50 100644 --- a/api/src/main/java/io/opencensus/trace/TraceComponent.java +++ b/api/src/main/java/io/opencensus/trace/TraceComponent.java @@ -67,9 +67,6 @@ public abstract class TraceComponent { */ public abstract TraceConfig getTraceConfig(); - // Disallow external overrides until we define the final API. - TraceComponent() {} - /** * Returns an instance that contains no-op implementations for all the instances. * diff --git a/api/src/main/java/io/opencensus/trace/Tracing.java b/api/src/main/java/io/opencensus/trace/Tracing.java index 70b0a70eda..316368a5d6 100644 --- a/api/src/main/java/io/opencensus/trace/Tracing.java +++ b/api/src/main/java/io/opencensus/trace/Tracing.java @@ -79,7 +79,7 @@ static TraceComponent loadTraceComponent(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. return Provider.createInstance( - Class.forName("io.opencensus.trace.TraceComponentImpl", true, classLoader), + Class.forName("io.opencensus.impl.trace.TraceComponentImpl", true, classLoader), TraceComponent.class); } catch (ClassNotFoundException e) { logger.log( @@ -91,7 +91,7 @@ static TraceComponent loadTraceComponent(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. return Provider.createInstance( - Class.forName("io.opencensus.trace.TraceComponentImplLite", true, classLoader), + Class.forName("io.opencensus.impl.trace.TraceComponentImplLite", true, classLoader), TraceComponent.class); } catch (ClassNotFoundException e) { logger.log( diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java index d35f2673c8..b7b4c53361 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsNonSampledSpanBenchmark.java @@ -13,6 +13,7 @@ package io.opencensus.trace; +import io.opencensus.impl.trace.SpanImpl; import io.opencensus.trace.samplers.Samplers; import java.util.HashMap; import java.util.concurrent.TimeUnit; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java index 36040c594a..492ee089ab 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/RecordTraceEventsSampledSpanBenchmark.java @@ -13,6 +13,7 @@ package io.opencensus.trace; +import io.opencensus.impl.trace.SpanImpl; import io.opencensus.trace.samplers.Samplers; import java.util.HashMap; import java.util.concurrent.TimeUnit; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java index c952fc4306..8eebf0328d 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/StartEndSpanBenchmark.java @@ -13,6 +13,7 @@ package io.opencensus.trace; +import io.opencensus.impl.trace.SpanImpl; import io.opencensus.trace.samplers.Samplers; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; diff --git a/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java b/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java index b5a658364c..4978e8c250 100644 --- a/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java +++ b/benchmarks/src/jmh/java/io/opencensus/trace/propagation/BinaryPropagationImplBenchmark.java @@ -13,6 +13,7 @@ package io.opencensus.trace.propagation; +import io.opencensus.impl.trace.propagation.BinaryFormatImpl; import io.opencensus.trace.SpanContext; import io.opencensus.trace.SpanId; import io.opencensus.trace.TraceId; diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java b/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java index cd423124a4..3f65918bb2 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java @@ -14,7 +14,7 @@ package io.opencensus.stats; import io.opencensus.common.Clock; -import io.opencensus.internal.EventQueue; +import io.opencensus.impl.internal.EventQueue; /** Base implementation of {@link StatsComponent}. */ class StatsComponentImplBase extends StatsComponent { diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java index 7f2f08a315..dea81b0d11 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java +++ b/core_impl/src/main/java/io/opencensus/stats/StatsManager.java @@ -14,7 +14,7 @@ package io.opencensus.stats; import io.opencensus.common.Clock; -import io.opencensus.internal.EventQueue; +import io.opencensus.impl.internal.EventQueue; import io.opencensus.tags.TagContext; /** Object that stores all views and stats. */ diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java index 190072ea5e..b920c94b02 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java @@ -18,8 +18,8 @@ import com.google.common.collect.ImmutableMap; import io.opencensus.common.Duration; import io.opencensus.common.Timestamp; +import io.opencensus.impl.internal.SimpleEventQueue; import io.opencensus.impl.tags.TagContextsImpl; -import io.opencensus.internal.SimpleEventQueue; import io.opencensus.stats.Aggregation.Count; import io.opencensus.stats.Aggregation.Histogram; import io.opencensus.stats.Aggregation.Mean; diff --git a/core_impl_android/src/main/java/io/opencensus/stats/StatsComponentImplLite.java b/core_impl_android/src/main/java/io/opencensus/stats/StatsComponentImplLite.java index 58cbd8cb31..1d7b453200 100644 --- a/core_impl_android/src/main/java/io/opencensus/stats/StatsComponentImplLite.java +++ b/core_impl_android/src/main/java/io/opencensus/stats/StatsComponentImplLite.java @@ -13,8 +13,8 @@ package io.opencensus.stats; -import io.opencensus.common.MillisClock; -import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.impl.common.MillisClock; +import io.opencensus.impl.internal.SimpleEventQueue; /** * Android-compatible implementation of {@link StatsComponent}. diff --git a/core_impl_java/src/main/java/io/opencensus/stats/StatsComponentImpl.java b/core_impl_java/src/main/java/io/opencensus/stats/StatsComponentImpl.java index d4790e253a..610fd2692d 100644 --- a/core_impl_java/src/main/java/io/opencensus/stats/StatsComponentImpl.java +++ b/core_impl_java/src/main/java/io/opencensus/stats/StatsComponentImpl.java @@ -13,8 +13,8 @@ package io.opencensus.stats; -import io.opencensus.common.MillisClock; -import io.opencensus.internal.DisruptorEventQueue; +import io.opencensus.impl.common.MillisClock; +import io.opencensus.impl.internal.DisruptorEventQueue; /** Java 7 and 8 implementation of {@link StatsComponent}. */ public final class StatsComponentImpl extends StatsComponentImplBase { diff --git a/impl/src/main/java/io/opencensus/internal/DisruptorEventQueue.java b/impl/src/main/java/io/opencensus/impl/internal/DisruptorEventQueue.java similarity index 98% rename from impl/src/main/java/io/opencensus/internal/DisruptorEventQueue.java rename to impl/src/main/java/io/opencensus/impl/internal/DisruptorEventQueue.java index 6360fe0e31..be2d422e32 100644 --- a/impl/src/main/java/io/opencensus/internal/DisruptorEventQueue.java +++ b/impl/src/main/java/io/opencensus/impl/internal/DisruptorEventQueue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.internal; +package io.opencensus.impl.internal; import com.lmax.disruptor.EventFactory; import com.lmax.disruptor.EventHandler; @@ -19,6 +19,7 @@ import com.lmax.disruptor.SleepingWaitStrategy; import com.lmax.disruptor.dsl.Disruptor; import com.lmax.disruptor.dsl.ProducerType; +import io.opencensus.impl.internal.EventQueue; import java.util.concurrent.Executors; import javax.annotation.concurrent.ThreadSafe; diff --git a/impl/src/main/java/io/opencensus/impl/trace/TraceComponentImpl.java b/impl/src/main/java/io/opencensus/impl/trace/TraceComponentImpl.java new file mode 100644 index 0000000000..639a356008 --- /dev/null +++ b/impl/src/main/java/io/opencensus/impl/trace/TraceComponentImpl.java @@ -0,0 +1,32 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.trace; + +import io.opencensus.impl.common.MillisClock; +import io.opencensus.impl.internal.DisruptorEventQueue; +import io.opencensus.impl.trace.TraceComponentImplBase; +import io.opencensus.trace.TraceComponent; +import io.opencensus.trace.internal.ThreadLocalRandomHandler; + +/** Java 7 and 8 implementation of the {@link TraceComponent}. */ +public final class TraceComponentImpl extends TraceComponentImplBase { + + /** Public constructor to be used with reflection loading. */ + public TraceComponentImpl() { + super( + MillisClock.getInstance(), + new ThreadLocalRandomHandler(), + DisruptorEventQueue.getInstance()); + } +} diff --git a/impl/src/main/java/io/opencensus/trace/TraceComponentImpl.java b/impl/src/main/java/io/opencensus/trace/TraceComponentImpl.java index 5d0700bde9..36ab3a140a 100644 --- a/impl/src/main/java/io/opencensus/trace/TraceComponentImpl.java +++ b/impl/src/main/java/io/opencensus/trace/TraceComponentImpl.java @@ -13,11 +13,15 @@ package io.opencensus.trace; -import io.opencensus.common.MillisClock; -import io.opencensus.internal.DisruptorEventQueue; +import io.opencensus.impl.common.MillisClock; +import io.opencensus.impl.internal.DisruptorEventQueue; +import io.opencensus.impl.trace.TraceComponentImplBase; import io.opencensus.trace.internal.ThreadLocalRandomHandler; /** Java 7 and 8 implementation of the {@link TraceComponent}. */ +// TraceComponentImpl was moved to io.opencensus.impl.trace. This class exists for backwards +// compatibility, so that it can be loaded by opencensus-api O.5. +@Deprecated public final class TraceComponentImpl extends TraceComponentImplBase { /** Public constructor to be used with reflection loading. */ diff --git a/impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java b/impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java index c291036bdb..94c5f3899a 100644 --- a/impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java +++ b/impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java @@ -13,6 +13,7 @@ package io.opencensus.trace.internal; +import io.opencensus.impl.trace.internal.RandomHandler; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; import javax.annotation.concurrent.ThreadSafe; diff --git a/impl/src/test/java/io/opencensus/trace/TracingTest.java b/impl/src/test/java/io/opencensus/impl/trace/TracingTest.java similarity index 87% rename from impl/src/test/java/io/opencensus/trace/TracingTest.java rename to impl/src/test/java/io/opencensus/impl/trace/TracingTest.java index 205fd68cb3..5c0ca65a33 100644 --- a/impl/src/test/java/io/opencensus/trace/TracingTest.java +++ b/impl/src/test/java/io/opencensus/impl/trace/TracingTest.java @@ -11,12 +11,14 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.impl.trace; import static com.google.common.truth.Truth.assertThat; -import io.opencensus.common.MillisClock; -import io.opencensus.trace.export.ExportComponentImpl; +import io.opencensus.impl.common.MillisClock; +import io.opencensus.impl.trace.export.ExportComponentImpl; +import io.opencensus.trace.TraceComponent; +import io.opencensus.trace.Tracing; import io.opencensus.trace.propagation.PropagationComponent; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/impl/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java b/impl/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java index 83a008472b..162e51eab7 100644 --- a/impl/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java +++ b/impl/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java @@ -15,6 +15,8 @@ import static com.google.common.truth.Truth.assertThat; +import io.opencensus.impl.internal.DisruptorEventQueue; +import io.opencensus.impl.internal.EventQueue; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/impl_core/src/main/java/io/opencensus/common/MillisClock.java b/impl_core/src/main/java/io/opencensus/impl/common/MillisClock.java similarity index 91% rename from impl_core/src/main/java/io/opencensus/common/MillisClock.java rename to impl_core/src/main/java/io/opencensus/impl/common/MillisClock.java index fc1ac12174..50f03d48b6 100644 --- a/impl_core/src/main/java/io/opencensus/common/MillisClock.java +++ b/impl_core/src/main/java/io/opencensus/impl/common/MillisClock.java @@ -11,8 +11,10 @@ * limitations under the License. */ -package io.opencensus.common; +package io.opencensus.impl.common; +import io.opencensus.common.Clock; +import io.opencensus.common.Timestamp; import javax.annotation.concurrent.ThreadSafe; /** A {@link Clock} that uses {@link System#currentTimeMillis()} and {@link System#nanoTime()}. */ diff --git a/impl_core/src/main/java/io/opencensus/internal/EventQueue.java b/impl_core/src/main/java/io/opencensus/impl/internal/EventQueue.java similarity index 96% rename from impl_core/src/main/java/io/opencensus/internal/EventQueue.java rename to impl_core/src/main/java/io/opencensus/impl/internal/EventQueue.java index d038e3d446..a7ef758163 100644 --- a/impl_core/src/main/java/io/opencensus/internal/EventQueue.java +++ b/impl_core/src/main/java/io/opencensus/impl/internal/EventQueue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.internal; +package io.opencensus.impl.internal; /** A queue that processes events. See {@code DisruptorEventQueue} for an example. */ public interface EventQueue { diff --git a/impl_core/src/main/java/io/opencensus/internal/SimpleEventQueue.java b/impl_core/src/main/java/io/opencensus/impl/internal/SimpleEventQueue.java similarity index 95% rename from impl_core/src/main/java/io/opencensus/internal/SimpleEventQueue.java rename to impl_core/src/main/java/io/opencensus/impl/internal/SimpleEventQueue.java index 380e51d6cb..27481cacbf 100644 --- a/impl_core/src/main/java/io/opencensus/internal/SimpleEventQueue.java +++ b/impl_core/src/main/java/io/opencensus/impl/internal/SimpleEventQueue.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.internal; +package io.opencensus.impl.internal; /** * An {@link EventQueue} that processes events in the current thread. This class can be used for diff --git a/impl_core/src/main/java/io/opencensus/internal/TimestampConverter.java b/impl_core/src/main/java/io/opencensus/impl/internal/TimestampConverter.java similarity index 97% rename from impl_core/src/main/java/io/opencensus/internal/TimestampConverter.java rename to impl_core/src/main/java/io/opencensus/impl/internal/TimestampConverter.java index 1bf258c9b2..02f0266eda 100644 --- a/impl_core/src/main/java/io/opencensus/internal/TimestampConverter.java +++ b/impl_core/src/main/java/io/opencensus/impl/internal/TimestampConverter.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.internal; +package io.opencensus.impl.internal; import io.opencensus.common.Clock; import io.opencensus.common.Timestamp; diff --git a/impl_core/src/main/java/io/opencensus/internal/VarInt.java b/impl_core/src/main/java/io/opencensus/impl/internal/VarInt.java similarity index 99% rename from impl_core/src/main/java/io/opencensus/internal/VarInt.java rename to impl_core/src/main/java/io/opencensus/impl/internal/VarInt.java index 2ac5c4e06a..1b7fc2651d 100644 --- a/impl_core/src/main/java/io/opencensus/internal/VarInt.java +++ b/impl_core/src/main/java/io/opencensus/impl/internal/VarInt.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.internal; +package io.opencensus.impl.internal; import java.io.IOException; import java.io.InputStream; diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java b/impl_core/src/main/java/io/opencensus/impl/trace/SpanBuilderImpl.java similarity index 93% rename from impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java rename to impl_core/src/main/java/io/opencensus/impl/trace/SpanBuilderImpl.java index b853f7812a..2bef65401f 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanBuilderImpl.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/SpanBuilderImpl.java @@ -11,16 +11,24 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.impl.trace; import static com.google.common.base.Preconditions.checkNotNull; import io.opencensus.common.Clock; -import io.opencensus.internal.TimestampConverter; +import io.opencensus.impl.internal.TimestampConverter; +import io.opencensus.impl.trace.internal.RandomHandler; +import io.opencensus.trace.Link; import io.opencensus.trace.Link.Type; +import io.opencensus.trace.Sampler; +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanBuilder; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceParams; -import io.opencensus.trace.internal.RandomHandler; import java.util.Collections; import java.util.EnumSet; import java.util.List; diff --git a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java b/impl_core/src/main/java/io/opencensus/impl/trace/SpanImpl.java similarity index 96% rename from impl_core/src/main/java/io/opencensus/trace/SpanImpl.java rename to impl_core/src/main/java/io/opencensus/impl/trace/SpanImpl.java index aecf06a0d8..d2a66609a7 100644 --- a/impl_core/src/main/java/io/opencensus/trace/SpanImpl.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/SpanImpl.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.impl.trace; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; @@ -19,11 +19,21 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.EvictingQueue; import io.opencensus.common.Clock; -import io.opencensus.internal.TimestampConverter; +import io.opencensus.impl.internal.TimestampConverter; +import io.opencensus.impl.trace.internal.ConcurrentIntrusiveList.Element; +import io.opencensus.trace.Annotation; +import io.opencensus.trace.AttributeValue; +import io.opencensus.trace.EndSpanOptions; +import io.opencensus.trace.Link; +import io.opencensus.trace.NetworkEvent; +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.Status; +import io.opencensus.trace.Tracer; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.export.SpanData; import io.opencensus.trace.export.SpanData.TimedEvent; -import io.opencensus.trace.internal.ConcurrentIntrusiveList.Element; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; diff --git a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java b/impl_core/src/main/java/io/opencensus/impl/trace/StartEndHandlerImpl.java similarity index 93% rename from impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java rename to impl_core/src/main/java/io/opencensus/impl/trace/StartEndHandlerImpl.java index c11cb88991..162871dd2b 100644 --- a/impl_core/src/main/java/io/opencensus/trace/StartEndHandlerImpl.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/StartEndHandlerImpl.java @@ -11,15 +11,15 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.impl.trace; -import io.opencensus.internal.EventQueue; +import io.opencensus.impl.internal.EventQueue; +import io.opencensus.impl.trace.SpanImpl.StartEndHandler; +import io.opencensus.impl.trace.export.RunningSpanStoreImpl; +import io.opencensus.impl.trace.export.SampledSpanStoreImpl; +import io.opencensus.impl.trace.export.SpanExporterImpl; import io.opencensus.trace.Span.Options; -import io.opencensus.trace.SpanImpl.StartEndHandler; -import io.opencensus.trace.export.RunningSpanStoreImpl; -import io.opencensus.trace.export.SampledSpanStoreImpl; import io.opencensus.trace.export.SpanData; -import io.opencensus.trace.export.SpanExporterImpl; import javax.annotation.Nullable; import javax.annotation.concurrent.ThreadSafe; diff --git a/impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java b/impl_core/src/main/java/io/opencensus/impl/trace/TraceComponentImplBase.java similarity index 70% rename from impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java rename to impl_core/src/main/java/io/opencensus/impl/trace/TraceComponentImplBase.java index 6e1db07f20..b4a6c3d360 100644 --- a/impl_core/src/main/java/io/opencensus/trace/TraceComponentImplBase.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/TraceComponentImplBase.java @@ -11,22 +11,24 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.impl.trace; import io.opencensus.common.Clock; -import io.opencensus.internal.EventQueue; -import io.opencensus.internal.SimpleEventQueue; -import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.impl.internal.EventQueue; +import io.opencensus.impl.internal.SimpleEventQueue; +import io.opencensus.impl.trace.SpanImpl.StartEndHandler; +import io.opencensus.impl.trace.config.TraceConfigImpl; +import io.opencensus.impl.trace.export.ExportComponentImpl; +import io.opencensus.impl.trace.internal.RandomHandler; +import io.opencensus.impl.trace.propagation.PropagationComponentImpl; +import io.opencensus.trace.TraceComponent; +import io.opencensus.trace.Tracer; import io.opencensus.trace.config.TraceConfig; -import io.opencensus.trace.config.TraceConfigImpl; import io.opencensus.trace.export.ExportComponent; -import io.opencensus.trace.export.ExportComponentImpl; -import io.opencensus.trace.internal.RandomHandler; import io.opencensus.trace.propagation.PropagationComponent; -import io.opencensus.trace.propagation.PropagationComponentImpl; /** Base implementation of the {@link TraceComponent}. */ -class TraceComponentImplBase extends TraceComponent { +public class TraceComponentImplBase extends TraceComponent { private final ExportComponentImpl exportComponent; private final PropagationComponent propagationComponent = new PropagationComponentImpl(); private final Clock clock; @@ -34,7 +36,14 @@ class TraceComponentImplBase extends TraceComponent { private final TraceConfig traceConfig = new TraceConfigImpl(); private final Tracer tracer; - TraceComponentImplBase(Clock clock, RandomHandler randomHandler, EventQueue eventQueue) { + /** + * Creates a new {@code TraceComponentImplBase}. + * + * @param clock the clock to use throughout tracing. + * @param randomHandler the random number generator for generating trace and span IDs. + * @param eventQueue the queue implementation. + */ + public TraceComponentImplBase(Clock clock, RandomHandler randomHandler, EventQueue eventQueue) { this.clock = clock; // TODO(bdrutu): Add a config/argument for supportInProcessStores. if (eventQueue instanceof SimpleEventQueue) { diff --git a/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java b/impl_core/src/main/java/io/opencensus/impl/trace/TracerImpl.java similarity index 86% rename from impl_core/src/main/java/io/opencensus/trace/TracerImpl.java rename to impl_core/src/main/java/io/opencensus/impl/trace/TracerImpl.java index 0dfdf361cb..735fdca1ac 100644 --- a/impl_core/src/main/java/io/opencensus/trace/TracerImpl.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/TracerImpl.java @@ -11,11 +11,15 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.impl.trace; import io.opencensus.common.Clock; +import io.opencensus.impl.trace.internal.RandomHandler; +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanBuilder; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.Tracer; import io.opencensus.trace.config.TraceConfig; -import io.opencensus.trace.internal.RandomHandler; import javax.annotation.Nullable; /** Implementation of the {@link Tracer}. */ diff --git a/impl_core/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java b/impl_core/src/main/java/io/opencensus/impl/trace/config/TraceConfigImpl.java similarity index 90% rename from impl_core/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java rename to impl_core/src/main/java/io/opencensus/impl/trace/config/TraceConfigImpl.java index 3b42c2b0dd..0973acdc00 100644 --- a/impl_core/src/main/java/io/opencensus/trace/config/TraceConfigImpl.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/config/TraceConfigImpl.java @@ -11,7 +11,10 @@ * limitations under the License. */ -package io.opencensus.trace.config; +package io.opencensus.impl.trace.config; + +import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.config.TraceParams; /** * Global configuration of the trace service. This allows users to change configs for the default diff --git a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java b/impl_core/src/main/java/io/opencensus/impl/trace/export/ExportComponentImpl.java similarity index 92% rename from impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java rename to impl_core/src/main/java/io/opencensus/impl/trace/export/ExportComponentImpl.java index fa968f4e19..826c5a72e0 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/ExportComponentImpl.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/export/ExportComponentImpl.java @@ -11,8 +11,11 @@ * limitations under the License. */ -package io.opencensus.trace.export; +package io.opencensus.impl.trace.export; +import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.export.RunningSpanStore; +import io.opencensus.trace.export.SampledSpanStore; import javax.annotation.Nullable; /** Implementation of the {@link ExportComponent}. */ diff --git a/impl_core/src/main/java/io/opencensus/trace/export/RunningSpanStoreImpl.java b/impl_core/src/main/java/io/opencensus/impl/trace/export/RunningSpanStoreImpl.java similarity index 92% rename from impl_core/src/main/java/io/opencensus/trace/export/RunningSpanStoreImpl.java rename to impl_core/src/main/java/io/opencensus/impl/trace/export/RunningSpanStoreImpl.java index d1053599bd..04628767a0 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/RunningSpanStoreImpl.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/export/RunningSpanStoreImpl.java @@ -11,10 +11,12 @@ * limitations under the License. */ -package io.opencensus.trace.export; +package io.opencensus.impl.trace.export; -import io.opencensus.trace.SpanImpl; -import io.opencensus.trace.internal.ConcurrentIntrusiveList; +import io.opencensus.impl.trace.SpanImpl; +import io.opencensus.impl.trace.internal.ConcurrentIntrusiveList; +import io.opencensus.trace.export.RunningSpanStore; +import io.opencensus.trace.export.SpanData; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; diff --git a/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java b/impl_core/src/main/java/io/opencensus/impl/trace/export/SampledSpanStoreImpl.java similarity index 98% rename from impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java rename to impl_core/src/main/java/io/opencensus/impl/trace/export/SampledSpanStoreImpl.java index 33ec009633..c7532152f2 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/SampledSpanStoreImpl.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/export/SampledSpanStoreImpl.java @@ -11,12 +11,14 @@ * limitations under the License. */ -package io.opencensus.trace.export; +package io.opencensus.impl.trace.export; import com.google.common.collect.EvictingQueue; -import io.opencensus.trace.SpanImpl; +import io.opencensus.impl.trace.SpanImpl; import io.opencensus.trace.Status; import io.opencensus.trace.Status.CanonicalCode; +import io.opencensus.trace.export.SampledSpanStore; +import io.opencensus.trace.export.SpanData; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; diff --git a/impl_core/src/main/java/io/opencensus/trace/export/SpanExporterImpl.java b/impl_core/src/main/java/io/opencensus/impl/trace/export/SpanExporterImpl.java similarity index 96% rename from impl_core/src/main/java/io/opencensus/trace/export/SpanExporterImpl.java rename to impl_core/src/main/java/io/opencensus/impl/trace/export/SpanExporterImpl.java index 643daae38e..90d1134f6b 100644 --- a/impl_core/src/main/java/io/opencensus/trace/export/SpanExporterImpl.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/export/SpanExporterImpl.java @@ -11,10 +11,13 @@ * limitations under the License. */ -package io.opencensus.trace.export; +package io.opencensus.impl.trace.export; import com.google.common.annotations.VisibleForTesting; -import io.opencensus.trace.SpanImpl; +import io.opencensus.impl.trace.SpanImpl; +import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.export.SpanData; +import io.opencensus.trace.export.SpanExporter; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; diff --git a/impl_core/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java b/impl_core/src/main/java/io/opencensus/impl/trace/internal/ConcurrentIntrusiveList.java similarity index 97% rename from impl_core/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java rename to impl_core/src/main/java/io/opencensus/impl/trace/internal/ConcurrentIntrusiveList.java index 5b0bc134eb..09b2463737 100644 --- a/impl_core/src/main/java/io/opencensus/trace/internal/ConcurrentIntrusiveList.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/internal/ConcurrentIntrusiveList.java @@ -11,11 +11,11 @@ * limitations under the License. */ -package io.opencensus.trace.internal; +package io.opencensus.impl.trace.internal; import static com.google.common.base.Preconditions.checkArgument; -import io.opencensus.trace.internal.ConcurrentIntrusiveList.Element; +import io.opencensus.impl.trace.internal.ConcurrentIntrusiveList.Element; import java.util.ArrayList; import java.util.Collection; import java.util.List; diff --git a/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java b/impl_core/src/main/java/io/opencensus/impl/trace/internal/RandomHandler.java similarity index 97% rename from impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java rename to impl_core/src/main/java/io/opencensus/impl/trace/internal/RandomHandler.java index d04d00520d..3ce4502f66 100644 --- a/impl_core/src/main/java/io/opencensus/trace/internal/RandomHandler.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/internal/RandomHandler.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.internal; +package io.opencensus.impl.trace.internal; import java.security.SecureRandom; import java.util.Random; diff --git a/impl_core/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java b/impl_core/src/main/java/io/opencensus/impl/trace/propagation/BinaryFormatImpl.java similarity index 96% rename from impl_core/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java rename to impl_core/src/main/java/io/opencensus/impl/trace/propagation/BinaryFormatImpl.java index a4cb675f70..ecf6969517 100644 --- a/impl_core/src/main/java/io/opencensus/trace/propagation/BinaryFormatImpl.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/propagation/BinaryFormatImpl.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.propagation; +package io.opencensus.impl.trace.propagation; import static com.google.common.base.Preconditions.checkNotNull; @@ -19,6 +19,7 @@ import io.opencensus.trace.SpanId; import io.opencensus.trace.TraceId; import io.opencensus.trace.TraceOptions; +import io.opencensus.trace.propagation.BinaryFormat; import java.text.ParseException; /** @@ -55,7 +56,7 @@ * * */ -final class BinaryFormatImpl extends BinaryFormat { +public final class BinaryFormatImpl extends BinaryFormat { private static final byte VERSION_ID = 0; private static final int VERSION_ID_OFFSET = 0; // The version_id/field_id size in bytes. @@ -72,8 +73,6 @@ final class BinaryFormatImpl extends BinaryFormat { private static final int FORMAT_LENGTH = 4 * ID_SIZE + TraceId.SIZE + SpanId.SIZE + TraceOptions.SIZE; - BinaryFormatImpl() {} - @Override public byte[] toBinaryValue(SpanContext spanContext) { checkNotNull(spanContext, "spanContext"); diff --git a/impl_core/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java b/impl_core/src/main/java/io/opencensus/impl/trace/propagation/PropagationComponentImpl.java similarity index 84% rename from impl_core/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java rename to impl_core/src/main/java/io/opencensus/impl/trace/propagation/PropagationComponentImpl.java index 144a563989..755ba27618 100644 --- a/impl_core/src/main/java/io/opencensus/trace/propagation/PropagationComponentImpl.java +++ b/impl_core/src/main/java/io/opencensus/impl/trace/propagation/PropagationComponentImpl.java @@ -11,7 +11,10 @@ * limitations under the License. */ -package io.opencensus.trace.propagation; +package io.opencensus.impl.trace.propagation; + +import io.opencensus.trace.propagation.BinaryFormat; +import io.opencensus.trace.propagation.PropagationComponent; /** Implementation of the {@link PropagationComponent}. */ public class PropagationComponentImpl extends PropagationComponent { diff --git a/impl_core/src/test/java/io/opencensus/internal/TimestampConverterTest.java b/impl_core/src/test/java/io/opencensus/impl/internal/TimestampConverterTest.java similarity index 94% rename from impl_core/src/test/java/io/opencensus/internal/TimestampConverterTest.java rename to impl_core/src/test/java/io/opencensus/impl/internal/TimestampConverterTest.java index 2fd9612e5d..e87f8cc310 100644 --- a/impl_core/src/test/java/io/opencensus/internal/TimestampConverterTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/internal/TimestampConverterTest.java @@ -11,13 +11,14 @@ * limitations under the License. */ -package io.opencensus.internal; +package io.opencensus.impl.internal; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; import io.opencensus.common.Clock; import io.opencensus.common.Timestamp; +import io.opencensus.impl.internal.TimestampConverter; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/SpanBuilderImplTest.java similarity index 95% rename from impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/SpanBuilderImplTest.java index 158b541a18..7dccf2c7fe 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanBuilderImplTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/SpanBuilderImplTest.java @@ -11,18 +11,23 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.impl.trace; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; +import io.opencensus.impl.trace.SpanImpl.StartEndHandler; +import io.opencensus.impl.trace.internal.RandomHandler; import io.opencensus.testing.common.TestClock; +import io.opencensus.trace.Span; import io.opencensus.trace.Span.Options; -import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.export.SpanData; -import io.opencensus.trace.internal.RandomHandler; import io.opencensus.trace.samplers.Samplers; import java.util.Random; import org.junit.Before; diff --git a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/SpanImplTest.java similarity index 97% rename from impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/SpanImplTest.java index 8651b35af5..92fb62a0ce 100644 --- a/impl_core/src/test/java/io/opencensus/trace/SpanImplTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/SpanImplTest.java @@ -11,16 +11,26 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.impl.trace; import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.Duration; import io.opencensus.common.Timestamp; -import io.opencensus.internal.TimestampConverter; +import io.opencensus.impl.internal.TimestampConverter; +import io.opencensus.impl.trace.SpanImpl.StartEndHandler; import io.opencensus.testing.common.TestClock; +import io.opencensus.trace.Annotation; +import io.opencensus.trace.AttributeValue; +import io.opencensus.trace.EndSpanOptions; +import io.opencensus.trace.Link; +import io.opencensus.trace.NetworkEvent; import io.opencensus.trace.Span.Options; -import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.Status; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.export.SpanData; import java.util.EnumSet; diff --git a/impl_core/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/TraceComponentImplBaseTest.java similarity index 77% rename from impl_core/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/TraceComponentImplBaseTest.java index 9af5591001..6d4f249993 100644 --- a/impl_core/src/test/java/io/opencensus/trace/TraceComponentImplBaseTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/TraceComponentImplBaseTest.java @@ -11,15 +11,18 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.impl.trace; import static com.google.common.truth.Truth.assertThat; -import io.opencensus.common.MillisClock; -import io.opencensus.internal.SimpleEventQueue; -import io.opencensus.trace.export.ExportComponentImpl; -import io.opencensus.trace.internal.RandomHandler.SecureRandomHandler; -import io.opencensus.trace.propagation.PropagationComponentImpl; +import io.opencensus.impl.common.MillisClock; +import io.opencensus.impl.internal.SimpleEventQueue; +import io.opencensus.impl.trace.TraceComponentImplBase; +import io.opencensus.impl.trace.TracerImpl; +import io.opencensus.impl.trace.export.ExportComponentImpl; +import io.opencensus.impl.trace.internal.RandomHandler.SecureRandomHandler; +import io.opencensus.impl.trace.propagation.PropagationComponentImpl; +import io.opencensus.trace.TraceComponent; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/TracerImplTest.java similarity index 86% rename from impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/TracerImplTest.java index 1cb27e20bd..3524e15a6e 100644 --- a/impl_core/src/test/java/io/opencensus/trace/TracerImplTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/TracerImplTest.java @@ -11,14 +11,17 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.impl.trace; import static com.google.common.truth.Truth.assertThat; +import io.opencensus.impl.trace.SpanImpl.StartEndHandler; +import io.opencensus.impl.trace.internal.RandomHandler.SecureRandomHandler; import io.opencensus.testing.common.TestClock; -import io.opencensus.trace.SpanImpl.StartEndHandler; +import io.opencensus.trace.BlankSpan; +import io.opencensus.trace.SpanBuilder; +import io.opencensus.trace.SpanContext; import io.opencensus.trace.config.TraceConfig; -import io.opencensus.trace.internal.RandomHandler.SecureRandomHandler; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/impl_core/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/config/TraceConfigImplTest.java similarity index 92% rename from impl_core/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/config/TraceConfigImplTest.java index a76e180f80..56372985bc 100644 --- a/impl_core/src/test/java/io/opencensus/trace/config/TraceConfigImplTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/config/TraceConfigImplTest.java @@ -11,10 +11,12 @@ * limitations under the License. */ -package io.opencensus.trace.config; +package io.opencensus.impl.trace.config; import static com.google.common.truth.Truth.assertThat; +import io.opencensus.impl.trace.config.TraceConfigImpl; +import io.opencensus.trace.config.TraceParams; import io.opencensus.trace.samplers.Samplers; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/export/ExportComponentImplTest.java similarity index 95% rename from impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/export/ExportComponentImplTest.java index 2cfa52eeb7..01331a4537 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/ExportComponentImplTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/export/ExportComponentImplTest.java @@ -11,10 +11,11 @@ * limitations under the License. */ -package io.opencensus.trace.export; +package io.opencensus.impl.trace.export; import static com.google.common.truth.Truth.assertThat; +import io.opencensus.trace.export.ExportComponent; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreImplTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/export/RunningSpanStoreImplTest.java similarity index 95% rename from impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreImplTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/export/RunningSpanStoreImplTest.java index e3f408ee99..7bae1d4651 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/RunningSpanStoreImplTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/export/RunningSpanStoreImplTest.java @@ -11,18 +11,18 @@ * limitations under the License. */ -package io.opencensus.trace.export; +package io.opencensus.impl.trace.export; import static com.google.common.truth.Truth.assertThat; -import io.opencensus.common.MillisClock; -import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.impl.common.MillisClock; +import io.opencensus.impl.internal.SimpleEventQueue; +import io.opencensus.impl.trace.SpanImpl; +import io.opencensus.impl.trace.SpanImpl.StartEndHandler; +import io.opencensus.impl.trace.StartEndHandlerImpl; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanContext; import io.opencensus.trace.SpanId; -import io.opencensus.trace.SpanImpl; -import io.opencensus.trace.SpanImpl.StartEndHandler; -import io.opencensus.trace.StartEndHandlerImpl; import io.opencensus.trace.TraceId; import io.opencensus.trace.TraceOptions; import io.opencensus.trace.config.TraceParams; diff --git a/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/export/SampledSpanStoreImplTest.java similarity index 98% rename from impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/export/SampledSpanStoreImplTest.java index fc82e61289..41912014f6 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/SampledSpanStoreImplTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/export/SampledSpanStoreImplTest.java @@ -11,20 +11,20 @@ * limitations under the License. */ -package io.opencensus.trace.export; +package io.opencensus.impl.trace.export; import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.Duration; import io.opencensus.common.Timestamp; +import io.opencensus.impl.trace.SpanImpl; +import io.opencensus.impl.trace.SpanImpl.StartEndHandler; import io.opencensus.testing.common.TestClock; import io.opencensus.trace.EndSpanOptions; import io.opencensus.trace.Span; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanContext; import io.opencensus.trace.SpanId; -import io.opencensus.trace.SpanImpl; -import io.opencensus.trace.SpanImpl.StartEndHandler; import io.opencensus.trace.Status; import io.opencensus.trace.Status.CanonicalCode; import io.opencensus.trace.TraceId; @@ -34,6 +34,7 @@ import io.opencensus.trace.export.SampledSpanStore.LatencyBucketBoundaries; import io.opencensus.trace.export.SampledSpanStore.LatencyFilter; import io.opencensus.trace.export.SampledSpanStore.PerSpanNameSummary; +import io.opencensus.trace.export.SpanData; import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; diff --git a/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/export/SpanExporterImplTest.java similarity index 96% rename from impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/export/SpanExporterImplTest.java index d82011462c..1b337ef7e7 100644 --- a/impl_core/src/test/java/io/opencensus/trace/export/SpanExporterImplTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/export/SpanExporterImplTest.java @@ -11,23 +11,24 @@ * limitations under the License. */ -package io.opencensus.trace.export; +package io.opencensus.impl.trace.export; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyListOf; import static org.mockito.Mockito.doThrow; -import io.opencensus.common.MillisClock; -import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.impl.common.MillisClock; +import io.opencensus.impl.internal.SimpleEventQueue; +import io.opencensus.impl.trace.SpanImpl; +import io.opencensus.impl.trace.SpanImpl.StartEndHandler; +import io.opencensus.impl.trace.StartEndHandlerImpl; import io.opencensus.trace.Span.Options; import io.opencensus.trace.SpanContext; import io.opencensus.trace.SpanId; -import io.opencensus.trace.SpanImpl; -import io.opencensus.trace.SpanImpl.StartEndHandler; -import io.opencensus.trace.StartEndHandlerImpl; import io.opencensus.trace.TraceId; import io.opencensus.trace.TraceOptions; import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.export.SpanData; import io.opencensus.trace.export.SpanExporter.Handler; import java.util.ArrayList; import java.util.Collection; diff --git a/impl_core/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/internal/ConcurrentIntrusiveListTest.java similarity index 95% rename from impl_core/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/internal/ConcurrentIntrusiveListTest.java index d1c13ad095..77574e8f0e 100644 --- a/impl_core/src/test/java/io/opencensus/trace/internal/ConcurrentIntrusiveListTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/internal/ConcurrentIntrusiveListTest.java @@ -11,11 +11,12 @@ * limitations under the License. */ -package io.opencensus.trace.internal; +package io.opencensus.impl.trace.internal; import static com.google.common.truth.Truth.assertThat; -import io.opencensus.trace.internal.ConcurrentIntrusiveList.Element; +import io.opencensus.impl.trace.internal.ConcurrentIntrusiveList; +import io.opencensus.impl.trace.internal.ConcurrentIntrusiveList.Element; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; diff --git a/impl_core/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/propagation/BinaryFormatImplTest.java similarity index 98% rename from impl_core/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/propagation/BinaryFormatImplTest.java index b16c453b51..a5e8c745cf 100644 --- a/impl_core/src/test/java/io/opencensus/trace/propagation/BinaryFormatImplTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/propagation/BinaryFormatImplTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.propagation; +package io.opencensus.impl.trace.propagation; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -20,6 +20,7 @@ import io.opencensus.trace.SpanId; import io.opencensus.trace.TraceId; import io.opencensus.trace.TraceOptions; +import io.opencensus.trace.propagation.BinaryFormat; import java.text.ParseException; import org.junit.Rule; import org.junit.Test; diff --git a/impl_core/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java b/impl_core/src/test/java/io/opencensus/impl/trace/propagation/PropagationComponentImplTest.java similarity index 91% rename from impl_core/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java rename to impl_core/src/test/java/io/opencensus/impl/trace/propagation/PropagationComponentImplTest.java index 9c1228ac8b..c8ef0708a5 100644 --- a/impl_core/src/test/java/io/opencensus/trace/propagation/PropagationComponentImplTest.java +++ b/impl_core/src/test/java/io/opencensus/impl/trace/propagation/PropagationComponentImplTest.java @@ -11,10 +11,11 @@ * limitations under the License. */ -package io.opencensus.trace.propagation; +package io.opencensus.impl.trace.propagation; import static com.google.common.truth.Truth.assertThat; +import io.opencensus.trace.propagation.PropagationComponent; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/impl_lite/src/main/java/io/opencensus/impl/trace/TraceComponentImplLite.java b/impl_lite/src/main/java/io/opencensus/impl/trace/TraceComponentImplLite.java new file mode 100644 index 0000000000..7b172279f2 --- /dev/null +++ b/impl_lite/src/main/java/io/opencensus/impl/trace/TraceComponentImplLite.java @@ -0,0 +1,27 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.trace; + +import io.opencensus.impl.common.MillisClock; +import io.opencensus.impl.internal.SimpleEventQueue; +import io.opencensus.impl.trace.internal.RandomHandler.SecureRandomHandler; +import io.opencensus.trace.TraceComponent; + +/** Android-compatible implementation of the {@link TraceComponent}. */ +public final class TraceComponentImplLite extends TraceComponentImplBase { + + public TraceComponentImplLite() { + super(MillisClock.getInstance(), new SecureRandomHandler(), new SimpleEventQueue()); + } +} diff --git a/impl_lite/src/main/java/io/opencensus/trace/TraceComponentImplLite.java b/impl_lite/src/main/java/io/opencensus/trace/TraceComponentImplLite.java index c3d7100b42..38a4992746 100644 --- a/impl_lite/src/main/java/io/opencensus/trace/TraceComponentImplLite.java +++ b/impl_lite/src/main/java/io/opencensus/trace/TraceComponentImplLite.java @@ -13,11 +13,15 @@ package io.opencensus.trace; -import io.opencensus.common.MillisClock; -import io.opencensus.internal.SimpleEventQueue; -import io.opencensus.trace.internal.RandomHandler.SecureRandomHandler; +import io.opencensus.impl.common.MillisClock; +import io.opencensus.impl.internal.SimpleEventQueue; +import io.opencensus.impl.trace.TraceComponentImplBase; +import io.opencensus.impl.trace.internal.RandomHandler.SecureRandomHandler; /** Android-compatible implementation of the {@link TraceComponent}. */ +// TraceComponentImplLite was moved to io.opencensus.impl.trace. This class exists for backwards +// compatibility, so that it can be loaded by opencensus-api O.5. +@Deprecated public final class TraceComponentImplLite extends TraceComponentImplBase { public TraceComponentImplLite() { diff --git a/impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplLiteTest.java b/impl_lite/src/test/java/io/opencensus/impl/trace/TraceComponentImplLiteTest.java similarity index 85% rename from impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplLiteTest.java rename to impl_lite/src/test/java/io/opencensus/impl/trace/TraceComponentImplLiteTest.java index f06c3d4088..c07e06835e 100644 --- a/impl_lite/src/test/java/io/opencensus/trace/TraceComponentImplLiteTest.java +++ b/impl_lite/src/test/java/io/opencensus/impl/trace/TraceComponentImplLiteTest.java @@ -11,13 +11,14 @@ * limitations under the License. */ -package io.opencensus.trace; +package io.opencensus.impl.trace; import static com.google.common.truth.Truth.assertThat; -import io.opencensus.common.MillisClock; -import io.opencensus.trace.export.ExportComponentImpl; -import io.opencensus.trace.propagation.PropagationComponentImpl; +import io.opencensus.impl.common.MillisClock; +import io.opencensus.impl.trace.export.ExportComponentImpl; +import io.opencensus.impl.trace.propagation.PropagationComponentImpl; +import io.opencensus.trace.Tracing; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; From 2e2fb0bfe877d61017eb785fd4030bd787a55432 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 16 Aug 2017 11:29:26 -0700 Subject: [PATCH 0387/1581] Move two more classes into 'impl' packages. --- .../main/java/io/opencensus/impl/trace/TraceComponentImpl.java | 2 +- .../{ => impl}/trace/internal/ThreadLocalRandomHandler.java | 2 +- impl/src/main/java/io/opencensus/trace/TraceComponentImpl.java | 2 +- .../opencensus/{ => impl}/internal/DisruptorEventQueueTest.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename impl/src/main/java/io/opencensus/{ => impl}/trace/internal/ThreadLocalRandomHandler.java (96%) rename impl/src/test/java/io/opencensus/{ => impl}/internal/DisruptorEventQueueTest.java (98%) diff --git a/impl/src/main/java/io/opencensus/impl/trace/TraceComponentImpl.java b/impl/src/main/java/io/opencensus/impl/trace/TraceComponentImpl.java index 639a356008..8457adfcf3 100644 --- a/impl/src/main/java/io/opencensus/impl/trace/TraceComponentImpl.java +++ b/impl/src/main/java/io/opencensus/impl/trace/TraceComponentImpl.java @@ -16,8 +16,8 @@ import io.opencensus.impl.common.MillisClock; import io.opencensus.impl.internal.DisruptorEventQueue; import io.opencensus.impl.trace.TraceComponentImplBase; +import io.opencensus.impl.trace.internal.ThreadLocalRandomHandler; import io.opencensus.trace.TraceComponent; -import io.opencensus.trace.internal.ThreadLocalRandomHandler; /** Java 7 and 8 implementation of the {@link TraceComponent}. */ public final class TraceComponentImpl extends TraceComponentImplBase { diff --git a/impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java b/impl/src/main/java/io/opencensus/impl/trace/internal/ThreadLocalRandomHandler.java similarity index 96% rename from impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java rename to impl/src/main/java/io/opencensus/impl/trace/internal/ThreadLocalRandomHandler.java index 94c5f3899a..6094167ff2 100644 --- a/impl/src/main/java/io/opencensus/trace/internal/ThreadLocalRandomHandler.java +++ b/impl/src/main/java/io/opencensus/impl/trace/internal/ThreadLocalRandomHandler.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.trace.internal; +package io.opencensus.impl.trace.internal; import io.opencensus.impl.trace.internal.RandomHandler; import java.util.Random; diff --git a/impl/src/main/java/io/opencensus/trace/TraceComponentImpl.java b/impl/src/main/java/io/opencensus/trace/TraceComponentImpl.java index 36ab3a140a..211e08d957 100644 --- a/impl/src/main/java/io/opencensus/trace/TraceComponentImpl.java +++ b/impl/src/main/java/io/opencensus/trace/TraceComponentImpl.java @@ -16,7 +16,7 @@ import io.opencensus.impl.common.MillisClock; import io.opencensus.impl.internal.DisruptorEventQueue; import io.opencensus.impl.trace.TraceComponentImplBase; -import io.opencensus.trace.internal.ThreadLocalRandomHandler; +import io.opencensus.impl.trace.internal.ThreadLocalRandomHandler; /** Java 7 and 8 implementation of the {@link TraceComponent}. */ // TraceComponentImpl was moved to io.opencensus.impl.trace. This class exists for backwards diff --git a/impl/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java b/impl/src/test/java/io/opencensus/impl/internal/DisruptorEventQueueTest.java similarity index 98% rename from impl/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java rename to impl/src/test/java/io/opencensus/impl/internal/DisruptorEventQueueTest.java index 162e51eab7..2be9eecbb0 100644 --- a/impl/src/test/java/io/opencensus/internal/DisruptorEventQueueTest.java +++ b/impl/src/test/java/io/opencensus/impl/internal/DisruptorEventQueueTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.internal; +package io.opencensus.impl.internal; import static com.google.common.truth.Truth.assertThat; From 01c99a34cfd914908875eaf59bf61f4a6a63edb1 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 19 Jul 2017 17:55:20 +0200 Subject: [PATCH 0388/1581] Add automatic context propagation to Thread#start. --- .../agent/ThreadInstrumentationTest.java | 87 ++++++++++++++++++ .../contrib/agent/ThreadInstrumentation.java | 91 +++++++++++++++++++ .../agent/bootstrap/ContextManager.java | 21 +++++ .../agent/bootstrap/ContextStrategy.java | 17 ++++ .../instrumentation/ContextStrategyImpl.java | 21 +++++ 5 files changed, 237 insertions(+) create mode 100644 contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java create mode 100644 contrib/agent/src/main/java/io/opencensus/contrib/agent/ThreadInstrumentation.java diff --git a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java new file mode 100644 index 0000000000..52070a0aba --- /dev/null +++ b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent; + +import static com.google.common.truth.Truth.assertThat; + +import io.grpc.Context; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.After; +import org.junit.Test; + +/** + * Integration tests for {@link ThreadInstrumentation}. + * + *

The integration tests are executed in a separate JVM that has the OpenCensus agent enabled + * via the {@code -javaagent} command line option. + */ +public class ThreadInstrumentationTest { + + private static final Context.Key KEY = Context.key("mykey"); + + private Context previousContext; + + @After + public void afterMethod() { + Context.current().detach(previousContext); + } + + @Test(timeout = 5000) + public void start_Runnable() throws Exception { + final Thread callerThread = Thread.currentThread(); + final Context context = Context.current().withValue(KEY, "myvalue"); + previousContext = context.attach(); + + final AtomicBoolean tested = new AtomicBoolean(false); + + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + assertThat(Thread.currentThread()).isNotSameAs(callerThread); + assertThat(Context.current()).isSameAs(context); + assertThat(KEY.get()).isEqualTo("myvalue"); + tested.set(true); + } + }); + + thread.start(); + thread.join(); + + assertThat(tested.get()).isTrue(); + } + + @Test(timeout = 5000) + public void start_Subclass() throws Exception { + final Thread callerThread = Thread.currentThread(); + final Context context = Context.current().withValue(KEY, "myvalue"); + previousContext = context.attach(); + + final AtomicBoolean tested = new AtomicBoolean(false); + + Thread thread = new Thread() { + @Override + public void run() { + assertThat(Thread.currentThread()).isNotSameAs(callerThread); + assertThat(Context.current()).isSameAs(context); + assertThat(KEY.get()).isEqualTo("myvalue"); + tested.set(true); + } + }; + + thread.start(); + thread.join(); + + assertThat(tested.get()).isTrue(); + } +} diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ThreadInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ThreadInstrumentation.java new file mode 100644 index 0000000000..dc572dad56 --- /dev/null +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ThreadInstrumentation.java @@ -0,0 +1,91 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.contrib.agent; + +import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf; +import static net.bytebuddy.matcher.ElementMatchers.named; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import io.opencensus.contrib.agent.bootstrap.ContextManager; +import net.bytebuddy.agent.builder.AgentBuilder; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.dynamic.DynamicType; +import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.utility.JavaModule; + +/** + * Propagates the context of the caller of {@link Thread#start} to the new thread, just like the + * Microsoft .Net Framework propagates the System.Threading.ExecutionContext. + */ +final class ThreadInstrumentation { + + private static class Transformer implements AgentBuilder.Transformer { + + @Override + public DynamicType.Builder transform(DynamicType.Builder builder, + TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) { + return builder + .visit(Advice.to(Start.class).on(named("start"))) + .visit(Advice.to(Run.class).on(named("run"))); + } + } + + static ElementMatcher.Junction createMatcher() { + // TODO(stschmidt): Exclude known call sites that already propagate the context. + + return isSubTypeOf(Thread.class); + } + + static AgentBuilder.Transformer createTransformer() { + return new Transformer(); + } + + private static class Start { + + /** + * Saves the context that is associated with the current scope. + * + *

The context will be attached when entering the thread's {@link Thread#run()} method. + * + *

NB: This method is never called as is. Instead, Byte Buddy copies the method's bytecode + * into Thread#start. + * + * @see Advice + */ + @Advice.OnMethodEnter + @SuppressFBWarnings("UPM_UNCALLED_PRIVATE_METHOD") + private static void enter(@Advice.This Thread thread) { + ContextManager.saveContextForThread(thread); + } + } + + private static class Run { + + /** + * Attaches the context that was previously saved for this thread. + * + *

NB: This method is never called as is. Instead, Byte Buddy copies the method's bytecode + * into Thread#run. + * + * @see Advice + */ + @Advice.OnMethodEnter + @SuppressFBWarnings("UPM_UNCALLED_PRIVATE_METHOD") + private static void enter(@Advice.This Thread thread) { + ContextManager.attachContextForThread(thread); + } + } +} diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java index 89a2f025dd..dccaf35e4f 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextManager.java @@ -70,4 +70,25 @@ public static void setContextStrategy(ContextStrategy contextStrategy) { public static Runnable wrapInCurrentContext(Runnable runnable) { return contextStrategy.wrapInCurrentContext(runnable); } + + /** + * Saves the context that is associated with the current scope. + * + *

The context will be attached when entering the specified thread's {@link Thread#run()} + * method. + * + * @param thread a {@link Thread} object + */ + public static void saveContextForThread(Thread thread) { + contextStrategy.saveContextForThread(thread); + } + + /** + * Attaches the context that was previously saved for the specified thread. + * + * @param thread a {@link Thread} object + */ + public static void attachContextForThread(Thread thread) { + contextStrategy.attachContextForThread(thread); + } } diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextStrategy.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextStrategy.java index 1ab5154c07..1d1cf73891 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextStrategy.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/bootstrap/ContextStrategy.java @@ -26,4 +26,21 @@ public interface ContextStrategy { * @return the wrapped {@link Runnable} object */ Runnable wrapInCurrentContext(Runnable runnable); + + /** + * Saves the context that is associated with the current scope. + * + *

The context will be attached when entering the specified thread's {@link Thread#run()} + * method. + * + * @param thread a {@link Thread} object + */ + void saveContextForThread(Thread thread); + + /** + * Attaches the context that was previously saved for the specified thread. + * + * @param thread a {@link Thread} object + */ + void attachContextForThread(Thread thread); } diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java index 616d3d430a..2124e7004c 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java @@ -13,6 +13,8 @@ package io.opencensus.contrib.agent.instrumentation; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import io.grpc.Context; import io.opencensus.contrib.agent.bootstrap.ContextStrategy; @@ -22,8 +24,27 @@ */ final class ContextStrategyImpl implements ContextStrategy { + private static final Cache SAVED_CONTEXTS + = CacheBuilder.newBuilder().weakKeys().build(); + @Override public Runnable wrapInCurrentContext(Runnable runnable) { return Context.current().wrap(runnable); } + + @Override + public void saveContextForThread(Thread thread) { + SAVED_CONTEXTS.put(thread, Context.current()); + } + + @Override + public void attachContextForThread(Thread thread) { + if (Thread.currentThread() == thread) { + Context context = SAVED_CONTEXTS.getIfPresent(thread); + if (context != null) { + SAVED_CONTEXTS.invalidate(thread); + context.attach(); + } + } + } } From 4dc2f0458bb5f0d0c6dd829c3fe8c35de69859e3 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 19 Jul 2017 18:02:14 +0200 Subject: [PATCH 0389/1581] Mention automatic context propagation for Threads. --- contrib/agent/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/contrib/agent/README.md b/contrib/agent/README.md index ed0824ac7b..35dcc9db41 100644 --- a/contrib/agent/README.md +++ b/contrib/agent/README.md @@ -20,6 +20,12 @@ The context of the caller of [Executor#execute](https://docs.oracle.com/javase/8 is automatically propagated to the submitted Runnable. +### Automatic context propagation for Threads + +The context of the caller of [Thread#start](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#start--) +is automatically propagated to the new thread. + + ## Design Ideas We see tracing as a cross-cutting concern which the *OpenCensus Agent for Java* weaves into From 6c3042f092a683182519a9faa39328d5b3c0cc69 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 19 Jul 2017 18:25:20 +0200 Subject: [PATCH 0390/1581] No need to make the cache a static field. --- .../agent/instrumentation/ContextStrategyImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java index 2124e7004c..4255e1421b 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java @@ -24,7 +24,7 @@ */ final class ContextStrategyImpl implements ContextStrategy { - private static final Cache SAVED_CONTEXTS + private final Cache savedContexts = CacheBuilder.newBuilder().weakKeys().build(); @Override @@ -34,15 +34,15 @@ public Runnable wrapInCurrentContext(Runnable runnable) { @Override public void saveContextForThread(Thread thread) { - SAVED_CONTEXTS.put(thread, Context.current()); + savedContexts.put(thread, Context.current()); } @Override public void attachContextForThread(Thread thread) { if (Thread.currentThread() == thread) { - Context context = SAVED_CONTEXTS.getIfPresent(thread); + Context context = savedContexts.getIfPresent(thread); if (context != null) { - SAVED_CONTEXTS.invalidate(thread); + savedContexts.invalidate(thread); context.attach(); } } From c0f309f985ffdafdf10104fedff1dd4e2df5f5cc Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Sun, 23 Jul 2017 21:34:02 +0200 Subject: [PATCH 0391/1581] Add trivial tests for {save,attach}ContextForThread. --- .../agent/bootstrap/ContextManagerTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java b/contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java index c072392f4b..cdf96b529e 100644 --- a/contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java +++ b/contrib/agent/src/test/java/io/opencensus/contrib/agent/bootstrap/ContextManagerTest.java @@ -42,6 +42,9 @@ public class ContextManagerTest { @Mock private Runnable runnable; + @Mock + private Thread thread; + @Test public void setContextStrategy_already_initialized() { exception.expect(IllegalStateException.class); @@ -55,4 +58,18 @@ public void wrapInCurrentContext() { Mockito.verify(mockContextStrategy).wrapInCurrentContext(runnable); } + + @Test + public void saveContextForThread() { + ContextManager.saveContextForThread(thread); + + Mockito.verify(mockContextStrategy).saveContextForThread(thread); + } + + @Test + public void attachContextForThread() { + ContextManager.attachContextForThread(thread); + + Mockito.verify(mockContextStrategy).attachContextForThread(thread); + } } From 6e34e62c18cfcfa8927f46cd0ee7881f6cfcceb9 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 14 Aug 2017 01:10:37 +0200 Subject: [PATCH 0392/1581] Javadoc for ContextStrategyImpl#savedContexts. --- .../instrumentation/ContextStrategyImpl.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java index 4255e1421b..db1e05c3e7 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java @@ -17,6 +17,7 @@ import com.google.common.cache.CacheBuilder; import io.grpc.Context; import io.opencensus.contrib.agent.bootstrap.ContextStrategy; +import java.lang.ref.WeakReference; /** * Implementation of {@link ContextStrategy} for accessing and manipulating the @@ -24,6 +25,27 @@ */ final class ContextStrategyImpl implements ContextStrategy { + /** + * Thread-safe mapping of {@link Thread}s to {@link Context}s, used for tunneling the caller's + * {@link Context} of {@link Thread#start()} to {@link Thread#run()}. + * + *

A thread is inserted into this map when {@link Thread#start()} is called, and removed when + * {@link Thread#run()} is called. + * + *

NB: {@link Thread#run()} is not guaranteed to be called after {@link Thread#start()}, for + * example when attempting to start a thread a second time. Therefore, threads are wrapped in + * {@link WeakReference}s so that this map does not prevent the garbage collection of otherwise + * unreferenced threads. Unreferenced threads will be automatically removed from the map routine + * cleanup. + * + *

NB: A side-effect of {@link CacheBuilder#weakKeys()} is the use of identity ({@code ==}) + * comparison to determine equality of threads. Identity comparison is required here because + * subclasses of {@link Thread} might override {@link Object#hashCode()} and {@link + * Object#equals(java.lang.Object)} with potentially broken implementations. + * + *

NB: Using thread IDs as keys was considered: It's unclear how to safely detect and cleanup + * otherwise unreferenced threads IDs from the map. + */ private final Cache savedContexts = CacheBuilder.newBuilder().weakKeys().build(); From 9aaa42bdf59ef450f791c187426414a9c02563ef Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 14 Aug 2017 01:27:10 +0200 Subject: [PATCH 0393/1581] Mention InheritableThreadLocal and the difference. --- .../io/opencensus/contrib/agent/ThreadInstrumentation.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ThreadInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ThreadInstrumentation.java index dc572dad56..cd7fd325fd 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ThreadInstrumentation.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/ThreadInstrumentation.java @@ -29,6 +29,10 @@ * Propagates the context of the caller of {@link Thread#start} to the new thread, just like the * Microsoft .Net Framework propagates the System.Threading.ExecutionContext. + * + *

NB: A similar effect could be achieved with {@link InheritableThreadLocal}, but the semantics + * are different: {@link InheritableThreadLocal} inherits values when the thread object is + * initialized as opposed to when {@link Thread#start()} is called. */ final class ThreadInstrumentation { From e10bd13ab27e7a15c003c917f20d6d74d210ba45 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 14 Aug 2017 03:09:54 +0200 Subject: [PATCH 0394/1581] doc fix. --- .../contrib/agent/instrumentation/ContextStrategyImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java index db1e05c3e7..534d0352c1 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ContextStrategyImpl.java @@ -35,8 +35,8 @@ final class ContextStrategyImpl implements ContextStrategy { *

NB: {@link Thread#run()} is not guaranteed to be called after {@link Thread#start()}, for * example when attempting to start a thread a second time. Therefore, threads are wrapped in * {@link WeakReference}s so that this map does not prevent the garbage collection of otherwise - * unreferenced threads. Unreferenced threads will be automatically removed from the map routine - * cleanup. + * unreferenced threads. Unreferenced threads will be automatically removed from the map by the + * routine cleanup of the underlying {@link Cache} implementation. * *

NB: A side-effect of {@link CacheBuilder#weakKeys()} is the use of identity ({@code ==}) * comparison to determine equality of threads. Identity comparison is required here because From 1d12a7921312118436a4005aae1db727e5fd1fd7 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 14 Aug 2017 16:47:04 +0200 Subject: [PATCH 0395/1581] Add a test for mixed Thread/Executor context propagation and assert that the Runnable is executed with the expected context. --- .../agent/ThreadInstrumentationTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java index 52070a0aba..fd3cc8d169 100644 --- a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java +++ b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java @@ -16,7 +16,10 @@ import static com.google.common.truth.Truth.assertThat; import io.grpc.Context; +import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; import org.junit.After; import org.junit.Test; @@ -84,4 +87,45 @@ public void run() { assertThat(tested.get()).isTrue(); } + + @Test(timeout = 5000) + public void start_wrappedRunnable() throws Exception { + final Thread callerThread = Thread.currentThread(); + final Context context = Context.current().withValue(KEY, "myvalue"); + previousContext = context.attach(); + + final AtomicBoolean tested = new AtomicBoolean(false); + + Executor newThreadExecutor = new Executor() { + @Override + public void execute(Runnable command) { + // Attach a new context before starting a new thread. This new context will be propagated to + // the new thread as in #start_Runnable. However, since the Runnable has been wrapped in a + // different context (by automatic instrumentation of Executor#execute), that context will + // be attached when executing the Runnable. + Context context2 = Context.current().withValue(KEY, "wrong context"); + context2.attach(); + Thread thread = new Thread(command); + thread.start(); + try { + thread.join(); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + context2.detach(context); + } + }; + + newThreadExecutor.execute(new Runnable() { + @Override + public void run() { + assertThat(Thread.currentThread()).isNotSameAs(callerThread); + assertThat(Context.current()).isSameAs(context); + assertThat(KEY.get()).isEqualTo("myvalue"); + tested.set(true); + } + }); + + assertThat(tested.get()).isTrue(); + } } From b04e1f76b62fb13d5f7c0d0a78e7f256c9438da7 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 14 Aug 2017 22:07:05 +0200 Subject: [PATCH 0396/1581] Removed unneeded import. --- .../io/opencensus/contrib/agent/ThreadInstrumentationTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java index fd3cc8d169..ae780c644f 100644 --- a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java +++ b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java @@ -18,8 +18,6 @@ import io.grpc.Context; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Level; -import java.util.logging.Logger; import org.junit.After; import org.junit.Test; From a9cf2e5d3e7196d584c49c1fa0150482eb281d64 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 15 Aug 2017 14:17:23 +0200 Subject: [PATCH 0397/1581] Addressed review comments: - Removed some sanity checks that don't add enough value. - Renamed a start_wrappedRunnable and added comment. - Prefer named subclass over anonymous subclass. --- .../agent/ThreadInstrumentationTest.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java index ae780c644f..120a7d1992 100644 --- a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java +++ b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java @@ -40,7 +40,6 @@ public void afterMethod() { @Test(timeout = 5000) public void start_Runnable() throws Exception { - final Thread callerThread = Thread.currentThread(); final Context context = Context.current().withValue(KEY, "myvalue"); previousContext = context.attach(); @@ -49,7 +48,6 @@ public void start_Runnable() throws Exception { Thread thread = new Thread(new Runnable() { @Override public void run() { - assertThat(Thread.currentThread()).isNotSameAs(callerThread); assertThat(Context.current()).isSameAs(context); assertThat(KEY.get()).isEqualTo("myvalue"); tested.set(true); @@ -64,21 +62,22 @@ public void run() { @Test(timeout = 5000) public void start_Subclass() throws Exception { - final Thread callerThread = Thread.currentThread(); final Context context = Context.current().withValue(KEY, "myvalue"); previousContext = context.attach(); final AtomicBoolean tested = new AtomicBoolean(false); - Thread thread = new Thread() { + class MyThread extends Thread { + @Override public void run() { - assertThat(Thread.currentThread()).isNotSameAs(callerThread); assertThat(Context.current()).isSameAs(context); assertThat(KEY.get()).isEqualTo("myvalue"); tested.set(true); } - }; + } + + Thread thread = new MyThread(); thread.start(); thread.join(); @@ -86,9 +85,12 @@ public void run() { assertThat(tested.get()).isTrue(); } + /** + * Tests that the automatic context propagation added by {@link ThreadInstrumentation} does not + * interfere with the automatically propagated context from Executor#execute. + */ @Test(timeout = 5000) - public void start_wrappedRunnable() throws Exception { - final Thread callerThread = Thread.currentThread(); + public void start_automaticallyWrappedRunnable() throws Exception { final Context context = Context.current().withValue(KEY, "myvalue"); previousContext = context.attach(); @@ -117,7 +119,6 @@ public void execute(Runnable command) { newThreadExecutor.execute(new Runnable() { @Override public void run() { - assertThat(Thread.currentThread()).isNotSameAs(callerThread); assertThat(Context.current()).isSameAs(context); assertThat(KEY.get()).isEqualTo("myvalue"); tested.set(true); From 276d27e990f9396b7d5174f24c46e650c67cef7c Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 15 Aug 2017 14:55:19 +0200 Subject: [PATCH 0398/1581] More comments. --- .../io/opencensus/contrib/agent/ThreadInstrumentationTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java index 120a7d1992..67286b0df3 100644 --- a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java +++ b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java @@ -119,6 +119,8 @@ public void execute(Runnable command) { newThreadExecutor.execute(new Runnable() { @Override public void run() { + // Assert that the automatic context propagation added by ThreadInstrumentation did not + // interfere with the automatically propagated context from Executor#execute. assertThat(Context.current()).isSameAs(context); assertThat(KEY.get()).isEqualTo("myvalue"); tested.set(true); From d6a3c285712554d89c69568392e965004b459708 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 16 Aug 2017 23:20:52 +0200 Subject: [PATCH 0399/1581] Rebased after merging #506 and turned ThreadInstrumentation into a plugin. --- .../ThreadInstrumentationTest.java | 2 +- .../ThreadInstrumentation.java | 20 +++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) rename contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/{ => instrumentation}/ThreadInstrumentationTest.java (98%) rename contrib/agent/src/main/java/io/opencensus/contrib/agent/{ => instrumentation}/ThreadInstrumentation.java (83%) diff --git a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/instrumentation/ThreadInstrumentationTest.java similarity index 98% rename from contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java rename to contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/instrumentation/ThreadInstrumentationTest.java index 67286b0df3..f0d105ac46 100644 --- a/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/ThreadInstrumentationTest.java +++ b/contrib/agent/src/integration-test/java/io/opencensus/contrib/agent/instrumentation/ThreadInstrumentationTest.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.contrib.agent; +package io.opencensus.contrib.agent.instrumentation; import static com.google.common.truth.Truth.assertThat; diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ThreadInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ThreadInstrumentation.java similarity index 83% rename from contrib/agent/src/main/java/io/opencensus/contrib/agent/ThreadInstrumentation.java rename to contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ThreadInstrumentation.java index cd7fd325fd..0b6b70abce 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/ThreadInstrumentation.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ThreadInstrumentation.java @@ -11,11 +11,13 @@ * limitations under the License. */ -package io.opencensus.contrib.agent; +package io.opencensus.contrib.agent.instrumentation; +import static com.google.common.base.Preconditions.checkNotNull; import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf; import static net.bytebuddy.matcher.ElementMatchers.named; +import com.google.auto.service.AutoService; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.opencensus.contrib.agent.bootstrap.ContextManager; import net.bytebuddy.agent.builder.AgentBuilder; @@ -34,7 +36,17 @@ * are different: {@link InheritableThreadLocal} inherits values when the thread object is * initialized as opposed to when {@link Thread#start()} is called. */ -final class ThreadInstrumentation { +@AutoService(Instrumenter.class) +public final class ThreadInstrumentation implements Instrumenter { + + @Override + public AgentBuilder instrument(AgentBuilder agentBuilder) { + checkNotNull(agentBuilder, "agentBuilder"); + + return agentBuilder + .type(createMatcher()) + .transform(createTransformer()); + } private static class Transformer implements AgentBuilder.Transformer { @@ -47,13 +59,13 @@ public DynamicType.Builder transform(DynamicType.Builder builder, } } - static ElementMatcher.Junction createMatcher() { + private static ElementMatcher.Junction createMatcher() { // TODO(stschmidt): Exclude known call sites that already propagate the context. return isSubTypeOf(Thread.class); } - static AgentBuilder.Transformer createTransformer() { + private static AgentBuilder.Transformer createTransformer() { return new Transformer(); } From f418803aa3e1c764a33307a9338b1a9c6cc2c4b8 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Aug 2017 02:32:45 +0200 Subject: [PATCH 0400/1581] Inline trivial methods, remove an inapplicable TODO (I'm currently not aware of such call sites). --- .../instrumentation/ExecutorInstrumentation.java | 6 +----- .../instrumentation/ThreadInstrumentation.java | 15 ++------------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentation.java index ccdd6e6347..48675886c5 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentation.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ExecutorInstrumentation.java @@ -51,7 +51,7 @@ public AgentBuilder instrument(AgentBuilder agentBuilder) { return agentBuilder .type(createMatcher()) - .transform(createTransformer()); + .transform(new Transformer()); } private static class Transformer implements AgentBuilder.Transformer { @@ -77,10 +77,6 @@ private static ElementMatcher.Junction createMatcher() { .or(nameEndsWith("FixedContextExecutor"))))); } - private static AgentBuilder.Transformer createTransformer() { - return new Transformer(); - } - private static class Execute { /** diff --git a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ThreadInstrumentation.java b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ThreadInstrumentation.java index 0b6b70abce..070e737ac0 100644 --- a/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ThreadInstrumentation.java +++ b/contrib/agent/src/main/java/io/opencensus/contrib/agent/instrumentation/ThreadInstrumentation.java @@ -24,7 +24,6 @@ import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.DynamicType; -import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.utility.JavaModule; /** @@ -44,8 +43,8 @@ public AgentBuilder instrument(AgentBuilder agentBuilder) { checkNotNull(agentBuilder, "agentBuilder"); return agentBuilder - .type(createMatcher()) - .transform(createTransformer()); + .type(isSubTypeOf(Thread.class)) + .transform(new Transformer()); } private static class Transformer implements AgentBuilder.Transformer { @@ -59,16 +58,6 @@ public DynamicType.Builder transform(DynamicType.Builder builder, } } - private static ElementMatcher.Junction createMatcher() { - // TODO(stschmidt): Exclude known call sites that already propagate the context. - - return isSubTypeOf(Thread.class); - } - - private static AgentBuilder.Transformer createTransformer() { - return new Transformer(); - } - private static class Start { /** From a77f1b63f3229caa850d17758dfe67c662538c9b Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 16 Aug 2017 18:56:27 -0700 Subject: [PATCH 0401/1581] Add initial implementation of the tracez page. (#517) * Add initial implementation of the tracez page. * Fix HTML when premature return. Add DOCTYPE and charset. * URLEncode the given spanName. * Build zpages only for java8. * Move Tester->ZPagesTester, add tests for query parsing. * Fix more comments. --- contrib/zpages/README.md | 12 + contrib/zpages/build.gradle | 14 + .../opencensus/zpages/TracezHttpHandler.java | 115 +++ .../zpages/TracezPageFormatter.java | 659 ++++++++++++++++++ .../zpages/TracezHttpHandlerTest.java | 39 ++ .../zpages/TracezPageFormatterTest.java | 144 ++++ examples/build.gradle | 11 +- .../examples/zpages/ZPagesTester.java | 35 + settings.gradle | 8 +- 9 files changed, 1032 insertions(+), 5 deletions(-) create mode 100644 contrib/zpages/README.md create mode 100644 contrib/zpages/build.gradle create mode 100644 contrib/zpages/src/main/java/io/opencensus/zpages/TracezHttpHandler.java create mode 100644 contrib/zpages/src/main/java/io/opencensus/zpages/TracezPageFormatter.java create mode 100644 contrib/zpages/src/test/java/io/opencensus/zpages/TracezHttpHandlerTest.java create mode 100644 contrib/zpages/src/test/java/io/opencensus/zpages/TracezPageFormatterTest.java create mode 100644 examples/src/main/java/io/opencensus/examples/zpages/ZPagesTester.java diff --git a/contrib/zpages/README.md b/contrib/zpages/README.md new file mode 100644 index 0000000000..8dd4c3354f --- /dev/null +++ b/contrib/zpages/README.md @@ -0,0 +1,12 @@ +# OpenCensus Z-Pages +[![Build Status][travis-image]][travis-url] [![Build status][appveyor-image]][appveyor-url] [![Maven Central][maven-image]][maven-url] + +The *OpenCensus Z-Pages for Java* is a collection of HTML pages to display stats and trace data and +allows library configuration control. + +[travis-image]: https://travis-ci.org/census-instrumentation/opencensus-java.svg?branch=master +[travis-url]: https://travis-ci.org/census-instrumentation/opencensus-java +[appveyor-image]: https://ci.appveyor.com/api/projects/status/hxthmpkxar4jq4be/branch/master?svg=true +[appveyor-url]: https://ci.appveyor.com/project/instrumentationjavateam/opencensus-java/branch/master +[maven-image]: https://maven-badges.herokuapp.com/maven-central/io.opencensus/opencensus-zpages/badge.svg +[maven-url]: https://maven-badges.herokuapp.com/maven-central/io.opencensus/opencensus-zpages \ No newline at end of file diff --git a/contrib/zpages/build.gradle b/contrib/zpages/build.gradle new file mode 100644 index 0000000000..1fdc18e3fa --- /dev/null +++ b/contrib/zpages/build.gradle @@ -0,0 +1,14 @@ +description = 'OpenCensus Z-Pages' + +apply plugin: 'java' + +[compileJava, compileTestJava].each() { + it.sourceCompatibility = 1.8 + it.targetCompatibility = 1.8 +} + +dependencies { + compile project(':opencensus-api') + + signature "org.codehaus.mojo.signature:java18:+@signature" +} diff --git a/contrib/zpages/src/main/java/io/opencensus/zpages/TracezHttpHandler.java b/contrib/zpages/src/main/java/io/opencensus/zpages/TracezHttpHandler.java new file mode 100644 index 0000000000..30ff64687d --- /dev/null +++ b/contrib/zpages/src/main/java/io/opencensus/zpages/TracezHttpHandler.java @@ -0,0 +1,115 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.zpages; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableMap; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import io.opencensus.common.Scope; +import io.opencensus.trace.AttributeValue; +import io.opencensus.trace.Tracer; +import io.opencensus.trace.Tracing; +import io.opencensus.trace.export.ExportComponent; +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * An {@link HttpHandler} that displays information about active and sampled spans recorded using + * the OpenCensus library. + * + *

Example usage with {@link HttpServer}: + * + *

{@code
+ * public class Main {
+ *   public static void main(String[] args) throws Exception {
+ *     HttpServer server = HttpServer.create(new InetSocketAddress(8000), 10);
+ *     TracezHttpHandler.register(server);
+ *     server.start();
+ *   }
+ * }
+ * }
+ */ +public final class TracezHttpHandler implements HttpHandler { + private static final Tracer tracer = Tracing.getTracer(); + private static final String TRACEZ_URL = "/tracez"; + private static final String HTTP_SERVER_SPAN_NAME = "HttpServer/tracez"; + private final TracezPageFormatter pageFormatter; + + /** Constructs a new {@code TracezHttpHandler}. */ + private TracezHttpHandler() { + ExportComponent exportComponent = Tracing.getExportComponent(); + this.pageFormatter = + TracezPageFormatter.create( + exportComponent.getRunningSpanStore(), exportComponent.getSampledSpanStore()); + Tracing.getExportComponent() + .getSampledSpanStore() + .registerSpanNamesForCollection(Arrays.asList(HTTP_SERVER_SPAN_NAME)); + } + + /** + * Registers the tracez {@code HttpHandler} to the given {@code HttpServer}. + * + * @param server the server that exports the tracez page. + */ + public static void register(HttpServer server) { + server.createContext(TRACEZ_URL, new TracezHttpHandler()); + } + + @Override + public final void handle(HttpExchange httpExchange) throws IOException { + try (Scope ss = + tracer + .spanBuilderWithExplicitParent(HTTP_SERVER_SPAN_NAME, null) + .setRecordEvents(true) + .startScopedSpan()) { + tracer + .getCurrentSpan() + .addAttributes( + ImmutableMap.builder() + .put( + "RequestMethod", + AttributeValue.stringAttributeValue(httpExchange.getRequestMethod())) + .build()); + httpExchange.sendResponseHeaders(200, 0); + pageFormatter.emitHtml( + uriQueryToMap(httpExchange.getRequestURI()), httpExchange.getResponseBody()); + } finally { + httpExchange.close(); + } + } + + @VisibleForTesting + static Map uriQueryToMap(URI uri) { + String query = uri.getQuery(); + if (query == null) { + return Collections.emptyMap(); + } + Map result = new HashMap(); + for (String param : query.split("&")) { + String[] pair = param.split("="); + if (pair.length > 1) { + result.put(pair[0], pair[1]); + } else { + result.put(pair[0], ""); + } + } + return result; + } +} diff --git a/contrib/zpages/src/main/java/io/opencensus/zpages/TracezPageFormatter.java b/contrib/zpages/src/main/java/io/opencensus/zpages/TracezPageFormatter.java new file mode 100644 index 0000000000..c1114a9527 --- /dev/null +++ b/contrib/zpages/src/main/java/io/opencensus/zpages/TracezPageFormatter.java @@ -0,0 +1,659 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.zpages; + +import static com.google.common.html.HtmlEscapers.htmlEscaper; + +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableMap; +import com.google.common.io.BaseEncoding; +import io.opencensus.common.Duration; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.common.Timestamp; +import io.opencensus.trace.Annotation; +import io.opencensus.trace.AttributeValue; +import io.opencensus.trace.NetworkEvent; +import io.opencensus.trace.NetworkEvent.Type; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.Status; +import io.opencensus.trace.Status.CanonicalCode; +import io.opencensus.trace.Tracer; +import io.opencensus.trace.Tracing; +import io.opencensus.trace.export.RunningSpanStore; +import io.opencensus.trace.export.SampledSpanStore; +import io.opencensus.trace.export.SampledSpanStore.ErrorFilter; +import io.opencensus.trace.export.SampledSpanStore.LatencyBucketBoundaries; +import io.opencensus.trace.export.SampledSpanStore.LatencyFilter; +import io.opencensus.trace.export.SpanData; +import io.opencensus.trace.export.SpanData.TimedEvent; +import io.opencensus.trace.export.SpanData.TimedEvents; +import java.io.BufferedWriter; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Formatter; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; + +/** + * HTML page formatter for tracing debug. The page displays information about all active spans and + * all sampled spans based on latency and errors. + * + *

It prints a summary table which contains one row for each span name and data about number of + * active and sampled spans. + * + *

See {@link TracezHttpHandler} for how to use the formatter with private HTTP server + * implementations or how to use with {@link com.sun.net.httpserver.HttpServer}. + */ +public final class TracezPageFormatter { + + private enum RequestType { + RUNNING(0), + FINISHED(1), + FAILED(2), + UNKNOWN(-1); + + private final int value; + + RequestType(int value) { + this.value = value; + } + + static RequestType fromString(String str) { + int value = Integer.parseInt(str); + switch (value) { + case 0: + return RUNNING; + case 1: + return FINISHED; + case 2: + return FAILED; + default: + return UNKNOWN; + } + } + + int getValue() { + return value; + } + } + + private static final Tracer tracer = Tracing.getTracer(); + // Color to use for zebra-striping. + private static final String ZEBRA_STRIPE_COLOR = "#eee"; + // The header for span name. + private static final String HEADER_SPAN_NAME = "zspanname"; + // The header for type (running = 0, latency = 1, error = 2) to display. + private static final String HEADER_SAMPLES_TYPE = "ztype"; + // The header for sub-type: + // * for latency based samples [0, 8] representing the latency buckets, where 0 is the first one; + // * for error based samples [0, 15], 0 - means all, otherwise the error code; + private static final String HEADER_SAMPLES_SUB_TYPE = "zsubtype"; + // Map from LatencyBucketBoundaries to the human string displayed on the UI for each bucket. + private static final Map LATENCY_BUCKET_BOUNDARIES_STRING_MAP = + buildLatencyBucketBoundariesStringMap(); + private final RunningSpanStore runningSpanStore; + private final SampledSpanStore sampledSpanStore; + + private TracezPageFormatter( + @Nullable RunningSpanStore runningSpanStore, @Nullable SampledSpanStore sampledSpanStore) { + this.runningSpanStore = runningSpanStore; + this.sampledSpanStore = sampledSpanStore; + } + + /** + * Constructs a new {@code TracezPageFormatter}. + * + * @param runningSpanStore the instance of the {@code RunningSpanStore} to be used. + * @param sampledSpanStore the instance of the {@code SampledSpanStore} to be used. + * @return a new {@code TracezPageFormatter}. + */ + public static TracezPageFormatter create( + @Nullable RunningSpanStore runningSpanStore, @Nullable SampledSpanStore sampledSpanStore) { + return new TracezPageFormatter(runningSpanStore, sampledSpanStore); + } + + /** + * Emits the HTML generated page to the {@code outputStream}. + * + * @param queryMap the query components map. + * @param outputStream the output {@code OutputStream}. + */ + public void emitHtml(Map queryMap, OutputStream outputStream) { + PrintWriter out = + new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream, Charsets.UTF_8))); + out.write("\n"); + out.write("\n"); + out.write("\n"); + out.write("TraceZ\n"); + out.write("\n"); + out.write("\n"); + out.write("\n"); + try { + emitHtmlBody(queryMap, out); + } catch (Throwable t) { + out.write("Errors while generate the HTML page " + t); + } + out.write("\n"); + out.write("\n"); + out.close(); + } + + private void emitHtmlBody(Map queryMap, PrintWriter out) + throws UnsupportedEncodingException { + if (runningSpanStore == null || sampledSpanStore == null) { + out.write("OpenCensus implementation not available."); + return; + } + Formatter formatter = new Formatter(out, Locale.US); + emitSummaryTable(out, formatter); + String spanName = queryMap.get(HEADER_SPAN_NAME); + if (spanName != null) { + tracer + .getCurrentSpan() + .addAnnotation( + "Render spans.", + ImmutableMap.builder() + .put("SpanName", AttributeValue.stringAttributeValue(spanName)) + .build()); + String typeStr = queryMap.get(HEADER_SAMPLES_TYPE); + if (typeStr != null) { + List spans = null; + RequestType type = RequestType.fromString(typeStr); + if (type == RequestType.UNKNOWN) { + return; + } + if (type == RequestType.RUNNING) { + // Display running. + spans = + new ArrayList<>( + runningSpanStore.getRunningSpans(RunningSpanStore.Filter.create(spanName, 0))); + // Sort active spans incremental. + Collections.sort(spans, new SpanDataComparator(true)); + } else { + String subtypeStr = queryMap.get(HEADER_SAMPLES_SUB_TYPE); + if (subtypeStr != null) { + int subtype = Integer.parseInt(subtypeStr); + if (type == RequestType.FAILED) { + if (subtype < 0 || subtype >= CanonicalCode.values().length) { + return; + } + // Display errors. subtype 0 means all. + CanonicalCode code = subtype == 0 ? null : CanonicalCode.values()[subtype]; + spans = + new ArrayList<>( + sampledSpanStore.getErrorSampledSpans(ErrorFilter.create(spanName, code, 0))); + } else { + if (subtype < 0 || subtype >= LatencyBucketBoundaries.values().length) { + return; + } + // Display latency. + LatencyBucketBoundaries latencyBucketBoundaries = + LatencyBucketBoundaries.values()[subtype]; + spans = + new ArrayList<>( + sampledSpanStore.getLatencySampledSpans( + LatencyFilter.create( + spanName, + latencyBucketBoundaries.getLatencyLowerNs(), + latencyBucketBoundaries.getLatencyUpperNs(), + 0))); + // Sort sampled spans decremental. + Collections.sort(spans, new SpanDataComparator(false)); + } + } + } + emitSpanNameAndCountPages(formatter, spanName, spans == null ? 0 : spans.size(), type); + + if (spans != null) { + emitSpans(out, formatter, spans); + } + } + } + } + + private static void emitSpanNameAndCountPages( + Formatter formatter, String spanName, int returnedNum, RequestType type) { + formatter.format("

Span Name: %s

%n", htmlEscaper().escape(spanName)); + formatter.format( + "%s Requests %d

%n", + type == RequestType.RUNNING + ? "Running" + : type == RequestType.FINISHED ? "Finished" : "Failed", + returnedNum); + } + + /** Emits the list of SampledRequets with a header. */ + private static void emitSpans(PrintWriter out, Formatter formatter, Collection spans) { + out.write("
\n");
+    formatter.format("%-23s %18s%n", "When", "Elapsed(s)");
+    out.write("-------------------------------------------\n");
+    for (SpanData span : spans) {
+      tracer
+          .getCurrentSpan()
+          .addAnnotation(
+              "Render span.",
+              ImmutableMap.builder()
+                  .put(
+                      "SpanId",
+                      AttributeValue.stringAttributeValue(
+                          BaseEncoding.base16()
+                              .lowerCase()
+                              .encode(span.getContext().getSpanId().getBytes())))
+                  .build());
+
+      emitSingleSpan(out, formatter, span);
+    }
+    out.write("
\n"); + } + + // Emits the internal html for a single {@link SpanData}. + private static void emitSingleSpan(PrintWriter out, Formatter formatter, SpanData span) { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(TimeUnit.SECONDS.toMillis(span.getStartTimestamp().getSeconds())); + long microsField = TimeUnit.NANOSECONDS.toMicros(span.getStartTimestamp().getNanos()); + String elapsedSecondsStr = + span.getEndTimestamp() != null + ? String.format( + "%13.6f", + durationToNanos(span.getEndTimestamp().subtractTimestamp(span.getStartTimestamp())) + * 1.0e-9) + : String.format("%13s", " "); + + formatter.format( + "%04d/%02d/%02d-%02d:%02d:%02d.%06d %s TraceId: %s SpanId: %s " + + "ParentSpanId: %s%n", + calendar.get(Calendar.YEAR), + calendar.get(Calendar.MONTH) + 1, + calendar.get(Calendar.DAY_OF_MONTH), + calendar.get(Calendar.HOUR_OF_DAY), + calendar.get(Calendar.MINUTE), + calendar.get(Calendar.SECOND), + microsField, + elapsedSecondsStr, + BaseEncoding.base16().lowerCase().encode(span.getContext().getTraceId().getBytes()), + BaseEncoding.base16().lowerCase().encode(span.getContext().getSpanId().getBytes()), + BaseEncoding.base16() + .lowerCase() + .encode( + span.getParentSpanId() == null + ? SpanId.INVALID.getBytes() + : span.getParentSpanId().getBytes())); + + int lastEntryDayOfYear = calendar.get(Calendar.DAY_OF_YEAR); + + Timestamp lastTimestampNanos = span.getStartTimestamp(); + TimedEvents annotations = span.getAnnotations(); + TimedEvents networkEvents = span.getNetworkEvents(); + List> timedEvents = new ArrayList>(annotations.getEvents()); + timedEvents.addAll(networkEvents.getEvents()); + Collections.sort(timedEvents, new TimedEventComparator()); + for (TimedEvent event : timedEvents) { + // Special printing so that durations smaller than one second + // are left padded with blanks instead of '0' characters. + // E.g., + // Number Printout + // --------------------------------- + // 0.000534 . 534 + // 1.000534 1.000534 + long deltaMicros = + TimeUnit.NANOSECONDS.toMicros( + durationToNanos(event.getTimestamp().subtractTimestamp(lastTimestampNanos))); + String deltaString; + if (deltaMicros >= 1000000) { + deltaString = String.format("%.6f", (deltaMicros / 1000000.0)); + } else { + deltaString = String.format(".%6d", deltaMicros); + } + + calendar.setTimeInMillis( + TimeUnit.SECONDS.toMillis(event.getTimestamp().getSeconds()) + + TimeUnit.NANOSECONDS.toMillis(event.getTimestamp().getNanos())); + microsField = TimeUnit.NANOSECONDS.toMicros(event.getTimestamp().getNanos()); + + int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR); + if (dayOfYear == lastEntryDayOfYear) { + formatter.format("%11s", ""); + } else { + formatter.format( + "%04d/%02d/%02d-", + calendar.get(Calendar.YEAR), + calendar.get(Calendar.MONTH) + 1, + calendar.get(Calendar.DAY_OF_MONTH)); + lastEntryDayOfYear = dayOfYear; + } + + formatter.format( + "%02d:%02d:%02d.%06d %13s ... %s%n", + calendar.get(Calendar.HOUR_OF_DAY), + calendar.get(Calendar.MINUTE), + calendar.get(Calendar.SECOND), + microsField, + deltaString, + htmlEscaper() + .escape( + event.getEvent() instanceof Annotation + ? renderAnnotation((Annotation) event.getEvent()) + : renderNetworkEvents((NetworkEvent) event.getEvent()))); + + lastTimestampNanos = event.getTimestamp(); + } + if (span.getStatus() != null) { + formatter.format("%44s %s%n", "", htmlEscaper().escape(renderStatus(span.getStatus()))); + } + formatter.format( + "%44s %s%n", + "", htmlEscaper().escape(renderAttributes(span.getAttributes().getAttributeMap()))); + } + + // Emits the summary table with links to all samples. + private void emitSummaryTable(PrintWriter out, Formatter formatter) + throws UnsupportedEncodingException { + RunningSpanStore.Summary runningSpanStoreSummary = runningSpanStore.getSummary(); + SampledSpanStore.Summary sampledSpanStoreSummary = sampledSpanStore.getSummary(); + + out.write("\n"); + emitSummaryTableHeader(out, formatter); + + Set spanNames = new TreeSet<>(runningSpanStoreSummary.getPerSpanNameSummary().keySet()); + spanNames.addAll(sampledSpanStoreSummary.getPerSpanNameSummary().keySet()); + boolean zebraColor = true; + for (String spanName : spanNames) { + out.write("\n"); + if (!zebraColor) { + out.write("\n"); + } else { + formatter.format("%n", ZEBRA_STRIPE_COLOR); + } + zebraColor = !zebraColor; + formatter.format("%n", htmlEscaper().escape(spanName)); + + // Running + out.write(""); + RunningSpanStore.PerSpanNameSummary runningSpanStorePerSpanNameSummary = + runningSpanStoreSummary.getPerSpanNameSummary().get(spanName); + + // subtype ignored for running requests. + emitSingleCell( + out, + formatter, + spanName, + runningSpanStorePerSpanNameSummary == null + ? 0 + : runningSpanStorePerSpanNameSummary.getNumRunningSpans(), + RequestType.RUNNING, + 0); + + SampledSpanStore.PerSpanNameSummary sampledSpanStorePerSpanNameSummary = + sampledSpanStoreSummary.getPerSpanNameSummary().get(spanName); + + // Latency based samples + out.write(""); + Map latencyBucketsSummaries = + sampledSpanStorePerSpanNameSummary != null + ? sampledSpanStorePerSpanNameSummary.getNumbersOfLatencySampledSpans() + : null; + int subtype = 0; + for (LatencyBucketBoundaries latencyBucketsBoundaries : LatencyBucketBoundaries.values()) { + if (latencyBucketsSummaries != null) { + int numSamples = + latencyBucketsSummaries.containsKey(latencyBucketsBoundaries) + ? latencyBucketsSummaries.get(latencyBucketsBoundaries) + : 0; + emitSingleCell(out, formatter, spanName, numSamples, RequestType.FINISHED, subtype++); + } else { + // numSamples < -1 means "Not Available". + emitSingleCell(out, formatter, spanName, -1, RequestType.FINISHED, subtype++); + } + } + + // Error based samples. + out.write(""); + if (sampledSpanStorePerSpanNameSummary != null) { + Map errorBucketsSummaries = + sampledSpanStorePerSpanNameSummary.getNumbersOfErrorSampledSpans(); + int numErrorSamples = 0; + for (Map.Entry it : errorBucketsSummaries.entrySet()) { + numErrorSamples += it.getValue(); + } + // subtype 0 means all; + emitSingleCell(out, formatter, spanName, numErrorSamples, RequestType.FAILED, 0); + } else { + // numSamples < -1 means "Not Available". + emitSingleCell(out, formatter, spanName, -1, RequestType.FAILED, 0); + } + + out.write("\n"); + } + out.write("
%s  |    |    |  
"); + } + + private static void emitSummaryTableHeader(PrintWriter out, Formatter formatter) { + out.write( + "TraceZ " + + "Summary\n"); + // First line. + out.write("\n"); + out.write("Span Name\n"); + out.write("  |  "); + out.write("Running\n"); + out.write("  |  "); + out.write("Latency Samples\n"); + out.write("  |  "); + out.write("Error Samples\n"); + out.write("\n"); + // Second line. + out.write("\n"); + out.write("\n"); + out.write("  |  "); + out.write("\n"); + out.write("  |  "); + for (LatencyBucketBoundaries latencyBucketsBoundaries : LatencyBucketBoundaries.values()) { + formatter.format( + "[%s]%n", + LATENCY_BUCKET_BOUNDARIES_STRING_MAP.get(latencyBucketsBoundaries)); + } + out.write("  |  "); + out.write("\n"); + out.write("\n"); + } + + // If numSamples is greater than 0 then emit a link to see span data, if the numSamples is + // negative then print "N/A", otherwise print the text "0". + private static void emitSingleCell( + PrintWriter out, + Formatter formatter, + String spanName, + int numSamples, + RequestType type, + int subtype) + throws UnsupportedEncodingException { + if (numSamples > 0) { + formatter.format( + "%d%n", + HEADER_SPAN_NAME, + URLEncoder.encode(spanName, "UTF-8"), + HEADER_SAMPLES_TYPE, + type.getValue(), + HEADER_SAMPLES_SUB_TYPE, + subtype, + numSamples); + } else if (numSamples < 0) { + out.write("N/A\n"); + } else { + out.write("0\n"); + } + } + + private static Map buildLatencyBucketBoundariesStringMap() { + Map ret = new HashMap<>(); + for (LatencyBucketBoundaries latencyBucketBoundaries : LatencyBucketBoundaries.values()) { + ret.put(latencyBucketBoundaries, latencyBucketBoundariesToString(latencyBucketBoundaries)); + } + return Collections.unmodifiableMap(ret); + } + + private static long durationToNanos(Duration duration) { + return TimeUnit.SECONDS.toNanos(duration.getSeconds()) + duration.getNanos(); + } + + private static String latencyBucketBoundariesToString( + LatencyBucketBoundaries latencyBucketBoundaries) { + switch (latencyBucketBoundaries) { + case ZERO_MICROSx10: + return ">0us"; + case MICROSx10_MICROSx100: + return ">10us"; + case MICROSx100_MILLIx1: + return ">100us"; + case MILLIx1_MILLIx10: + return ">1ms"; + case MILLIx10_MILLIx100: + return ">10ms"; + case MILLIx100_SECONDx1: + return ">100ms"; + case SECONDx1_SECONDx10: + return ">1s"; + case SECONDx10_SECONDx100: + return ">10s"; + case SECONDx100_MAX: + return ">100s"; + } + throw new IllegalArgumentException("No value string available for: " + latencyBucketBoundaries); + } + + private static String renderNetworkEvents(NetworkEvent networkEvent) { + StringBuilder stringBuilder = new StringBuilder(); + if (networkEvent.getType() == Type.RECV) { + stringBuilder.append("Received"); + } else if (networkEvent.getType() == Type.SENT) { + stringBuilder.append("Sent"); + } else { + stringBuilder.append("Unknown"); + } + stringBuilder.append(" message_id="); + stringBuilder.append(networkEvent.getMessageId()); + stringBuilder.append(" message_size="); + stringBuilder.append(networkEvent.getMessageSize()); + if (networkEvent.getKernelTimestamp() != null) { + stringBuilder.append(" kernel_timestamp="); + stringBuilder.append(networkEvent.getKernelTimestamp().toString()); + } + return stringBuilder.toString(); + } + + private static String renderAnnotation(Annotation annotation) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(annotation.getDescription()); + if (!annotation.getAttributes().isEmpty()) { + stringBuilder.append(" "); + stringBuilder.append(renderAttributes(annotation.getAttributes())); + } + return stringBuilder.toString(); + } + + private static String renderStatus(Status status) { + return status.toString(); + } + + private static String renderAttributes(Map attributes) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("Attributes:{"); + boolean first = true; + for (Map.Entry entry : attributes.entrySet()) { + if (first) { + first = false; + stringBuilder.append(entry.getKey()); + stringBuilder.append("="); + stringBuilder.append(attributeValueToString(entry.getValue())); + } else { + stringBuilder.append(", "); + stringBuilder.append(entry.getKey()); + stringBuilder.append("="); + stringBuilder.append(attributeValueToString(entry.getValue())); + } + } + stringBuilder.append("}"); + return stringBuilder.toString(); + } + + private static String attributeValueToString(AttributeValue attributeValue) { + return attributeValue.match( + new Function() { + @Override + public String apply(String stringValue) { + return stringValue; + } + }, + new Function() { + @Override + public String apply(Boolean booleanValue) { + return booleanValue.toString(); + } + }, + new Function() { + @Override + public String apply(Long longValue) { + return longValue.toString(); + } + }, + Functions.returnNull()); + } + + private static final class TimedEventComparator + implements Comparator>, Serializable { + private static final long serialVersionUID = 0; + + @Override + public int compare(TimedEvent o1, TimedEvent o2) { + return o1.getTimestamp().compareTo(o2.getTimestamp()); + } + } + + private static final class SpanDataComparator implements Comparator, Serializable { + private static final long serialVersionUID = 0; + private final boolean incremental; + + /** + * Returns a new {@code SpanDataComparator}. + * + * @param incremental {@code true} if sorted incremental. + */ + private SpanDataComparator(boolean incremental) { + this.incremental = incremental; + } + + @Override + public int compare(SpanData o1, SpanData o2) { + return incremental + ? o1.getStartTimestamp().compareTo(o2.getStartTimestamp()) + : o2.getStartTimestamp().compareTo(o1.getStartTimestamp()); + } + } +} diff --git a/contrib/zpages/src/test/java/io/opencensus/zpages/TracezHttpHandlerTest.java b/contrib/zpages/src/test/java/io/opencensus/zpages/TracezHttpHandlerTest.java new file mode 100644 index 0000000000..1988d1ee27 --- /dev/null +++ b/contrib/zpages/src/test/java/io/opencensus/zpages/TracezHttpHandlerTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.zpages; + +import static com.google.common.truth.Truth.assertThat; + +import java.net.URI; +import java.net.URISyntaxException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TracezHttpHandler}. */ +@RunWith(JUnit4.class) +public class TracezHttpHandlerTest { + @Test + public void parseUndefinedQuery() throws URISyntaxException { + URI uri = new URI("http://localhost:8000/tracez"); + assertThat(TracezHttpHandler.uriQueryToMap(uri)).isEmpty(); + } + + @Test + public void parseQuery() throws URISyntaxException { + URI uri = new URI("http://localhost:8000/tracez?ztype=1&zsubtype&zname=Test"); + assertThat(TracezHttpHandler.uriQueryToMap(uri)) + .containsExactly("ztype", "1", "zsubtype", "", "zname", "Test"); + } +} diff --git a/contrib/zpages/src/test/java/io/opencensus/zpages/TracezPageFormatterTest.java b/contrib/zpages/src/test/java/io/opencensus/zpages/TracezPageFormatterTest.java new file mode 100644 index 0000000000..00770cd8a6 --- /dev/null +++ b/contrib/zpages/src/test/java/io/opencensus/zpages/TracezPageFormatterTest.java @@ -0,0 +1,144 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.zpages; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; + +import io.opencensus.trace.Status.CanonicalCode; +import io.opencensus.trace.export.RunningSpanStore; +import io.opencensus.trace.export.SampledSpanStore; +import io.opencensus.trace.export.SampledSpanStore.LatencyBucketBoundaries; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link TracezPageFormatter}. */ +@RunWith(JUnit4.class) +public class TracezPageFormatterTest { + private static final String ACTIVE_SPAN_NAME = "TestActiveSpan"; + private static final String SAMPLED_SPAN_NAME = "TestSampledSpan"; + private static final String ACTIVE_SAMPLED_SPAN_NAME = "TestActiveAndSampledSpan"; + @Mock private RunningSpanStore runningSpanStore; + @Mock private SampledSpanStore sampledSpanStore; + RunningSpanStore.Summary runningSpanStoreSummary; + SampledSpanStore.Summary sampledSpanStoreSummary; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + Map runningSummaryMap = new HashMap<>(); + runningSummaryMap.put(ACTIVE_SPAN_NAME, RunningSpanStore.PerSpanNameSummary.create(3)); + runningSummaryMap.put(ACTIVE_SAMPLED_SPAN_NAME, RunningSpanStore.PerSpanNameSummary.create(5)); + runningSpanStoreSummary = RunningSpanStore.Summary.create(runningSummaryMap); + Map numbersOfLatencySampledSpans = new HashMap<>(); + numbersOfLatencySampledSpans.put(LatencyBucketBoundaries.MILLIx1_MILLIx10, 3); + numbersOfLatencySampledSpans.put(LatencyBucketBoundaries.MICROSx10_MICROSx100, 7); + Map numbersOfErrorSampledSpans = new HashMap<>(); + numbersOfErrorSampledSpans.put(CanonicalCode.CANCELLED, 2); + numbersOfErrorSampledSpans.put(CanonicalCode.DEADLINE_EXCEEDED, 5); + Map sampledSummaryMap = new HashMap<>(); + sampledSummaryMap.put( + SAMPLED_SPAN_NAME, + SampledSpanStore.PerSpanNameSummary.create( + numbersOfLatencySampledSpans, numbersOfErrorSampledSpans)); + sampledSummaryMap.put( + ACTIVE_SAMPLED_SPAN_NAME, + SampledSpanStore.PerSpanNameSummary.create( + numbersOfLatencySampledSpans, numbersOfErrorSampledSpans)); + sampledSpanStoreSummary = SampledSpanStore.Summary.create(sampledSummaryMap); + } + + @Test + public void emitSummaryTableForEachSpan() { + OutputStream output = new ByteArrayOutputStream(); + TracezPageFormatter tracezPageFormatter = + TracezPageFormatter.create(runningSpanStore, sampledSpanStore); + when(runningSpanStore.getSummary()).thenReturn(runningSpanStoreSummary); + when(sampledSpanStore.getSummary()).thenReturn(sampledSpanStoreSummary); + tracezPageFormatter.emitHtml(Collections.emptyMap(), output); + assertThat(output.toString()).contains(ACTIVE_SPAN_NAME); + assertThat(output.toString()).contains(SAMPLED_SPAN_NAME); + assertThat(output.toString()).contains(ACTIVE_SAMPLED_SPAN_NAME); + } + + @Test + public void linksForActiveRequests_InSummaryTable() { + OutputStream output = new ByteArrayOutputStream(); + TracezPageFormatter tracezPageFormatter = + TracezPageFormatter.create(runningSpanStore, sampledSpanStore); + when(runningSpanStore.getSummary()).thenReturn(runningSpanStoreSummary); + when(sampledSpanStore.getSummary()).thenReturn(sampledSpanStoreSummary); + tracezPageFormatter.emitHtml(Collections.emptyMap(), output); + // 3 active requests + assertThat(output.toString()).contains("href='?zspanname=TestActiveSpan&ztype=0&zsubtype=0'>3"); + // No active links + assertThat(output.toString()) + .doesNotContain("href='?zspanname=TestSampledSpan&ztype=0&zsubtype=0'"); + // 5 active requests + assertThat(output.toString()) + .contains("href='?zspanname=TestActiveAndSampledSpan&ztype=0&zsubtype=0'>5"); + } + + @Test + public void linksForSampledRequests_InSummaryTable() { + OutputStream output = new ByteArrayOutputStream(); + TracezPageFormatter tracezPageFormatter = + TracezPageFormatter.create(runningSpanStore, sampledSpanStore); + when(runningSpanStore.getSummary()).thenReturn(runningSpanStoreSummary); + when(sampledSpanStore.getSummary()).thenReturn(sampledSpanStoreSummary); + tracezPageFormatter.emitHtml(Collections.emptyMap(), output); + // No sampled links (ztype=1); + assertThat(output.toString()).doesNotContain("href=\"?zspanname=TestActiveSpan&ztype=1"); + // Links for 7 samples [10us, 100us) and 3 samples [1ms, 10ms); + assertThat(output.toString()) + .contains("href='?zspanname=TestSampledSpan&ztype=1&zsubtype=1'>7"); + assertThat(output.toString()) + .contains("href='?zspanname=TestSampledSpan&ztype=1&zsubtype=3'>3"); + // Links for 7 samples [10us, 100us) and 3 samples [1ms, 10ms); + assertThat(output.toString()) + .contains("href='?zspanname=TestActiveAndSampledSpan&ztype=1&zsubtype=1'>7"); + assertThat(output.toString()) + .contains("href='?zspanname=TestActiveAndSampledSpan&ztype=1&zsubtype=3'>3"); + } + + @Test + public void linksForFailedRequests_InSummaryTable() { + OutputStream output = new ByteArrayOutputStream(); + TracezPageFormatter tracezPageFormatter = + TracezPageFormatter.create(runningSpanStore, sampledSpanStore); + when(runningSpanStore.getSummary()).thenReturn(runningSpanStoreSummary); + when(sampledSpanStore.getSummary()).thenReturn(sampledSpanStoreSummary); + tracezPageFormatter.emitHtml(Collections.emptyMap(), output); + // No sampled links (ztype=1); + assertThat(output.toString()).doesNotContain("href=\"?zspanname=TestActiveSpan&ztype=2"); + // Links for 7 errors 2 CANCELLED + 5 DEADLINE_EXCEEDED; + assertThat(output.toString()) + .contains("href='?zspanname=TestSampledSpan&ztype=2&zsubtype=0'>7"); + // Links for 7 errors 2 CANCELLED + 5 DEADLINE_EXCEEDED; + assertThat(output.toString()) + .contains("href='?zspanname=TestActiveAndSampledSpan&ztype=2&zsubtype=0'>7"); + } + + // TODO(bdrutu): Add tests for latency. + // TODO(bdrutu): Add tests for samples/running/errors. +} diff --git a/examples/build.gradle b/examples/build.gradle index 5e45e8464d..2e31a14557 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -8,7 +8,8 @@ tasks.withType(JavaCompile) { dependencies { compile project(':core'), project(':opencensus-api'), - project(':opencensus-trace-logging-exporter') + project(':opencensus-trace-logging-exporter'), + project(':opencensus-zpages') runtime project(':core_impl_java'), project(':opencensus-impl') @@ -47,10 +48,18 @@ task multiSpansContextTracing(type: CreateStartScripts) { classpath = jar.outputs.files + project.configurations.runtime } +task zPagesTester(type: CreateStartScripts) { + mainClassName = 'io.opencensus.examples.zpages.ZPagesTester' + applicationName = 'ZPagesTester' + outputDir = new File(project.buildDir, 'tmp') + classpath = jar.outputs.files + project.configurations.runtime +} + applicationDistribution.into('bin') { from(multiSpansTracing) from(multiSpansScopedTracing) from(multiSpansContextTracing) from(statsRunner) + from(zPagesTester) fileMode = 0755 } \ No newline at end of file diff --git a/examples/src/main/java/io/opencensus/examples/zpages/ZPagesTester.java b/examples/src/main/java/io/opencensus/examples/zpages/ZPagesTester.java new file mode 100644 index 0000000000..1d59e3b4ac --- /dev/null +++ b/examples/src/main/java/io/opencensus/examples/zpages/ZPagesTester.java @@ -0,0 +1,35 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.examples.zpages; + +import com.sun.net.httpserver.HttpServer; +import io.opencensus.zpages.TracezHttpHandler; +import java.net.InetSocketAddress; +import java.util.logging.Logger; + +/** + * Testing only class for the UI. + */ +public class ZPagesTester { + private static final Logger logger = Logger.getLogger(ZPagesTester.class.getName()); + + /** Main method. */ + public static void main(String[] args) throws Exception { + HttpServer server = HttpServer.create(new InetSocketAddress(8000), 10); + TracezHttpHandler.register(server); + server.start(); + logger.info(server.getAddress().toString()); + } + +} diff --git a/settings.gradle b/settings.gradle index 09a752878b..454a57d5cf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,5 @@ rootProject.name = "opencensus-java" -include ":opencensus-agent" include ":opencensus-api" include ":opencensus-impl-core" include ":opencensus-impl-lite" @@ -12,20 +11,21 @@ include ":core" include ":core_impl" include ":core_impl_java" include ":core_impl_android" +include ":opencensus-agent" -project(':opencensus-agent').projectDir = "$rootDir/contrib/agent" as File project(':opencensus-api').projectDir = "$rootDir/api" as File project(':opencensus-impl-core').projectDir = "$rootDir/impl_core" as File project(':opencensus-impl-lite').projectDir = "$rootDir/impl_lite" as File project(':opencensus-impl').projectDir = "$rootDir/impl" as File project(':opencensus-testing').projectDir = "$rootDir/testing" as File project(':opencensus-trace-logging-exporter').projectDir = "$rootDir/exporters/trace_logging" as File +project(':opencensus-agent').projectDir = "$rootDir/contrib/agent" as File // Java8 projects only if (JavaVersion.current().isJava8Compatible()) { include ":examples" include ":benchmarks" + include ":opencensus-zpages" - project(':examples').projectDir = "$rootDir/examples" as File - project(':benchmarks').projectDir = "$rootDir/benchmarks" as File + project(':opencensus-zpages').projectDir = "$rootDir/contrib/zpages" as File } From 31b3fdd1cd6576b401e5b68a6cc3189a3cf5f267 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 16 Aug 2017 18:57:26 -0700 Subject: [PATCH 0402/1581] Update to newer versions of errorprone and animalsniffer. (#521) --- build.gradle | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/build.gradle b/build.gradle index b20f20e377..a0b2e11aee 100644 --- a/build.gradle +++ b/build.gradle @@ -7,8 +7,8 @@ buildscript { } } dependencies { - classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.3.0' - classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.10' + classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.4.0' + classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.11' classpath "net.ltgt.gradle:gradle-apt-plugin:0.10" } } @@ -104,21 +104,21 @@ subprojects { guavaVersion = '19.0' libraries = [ - auto_value : "com.google.auto.value:auto-value:${autoValueVersion}", - auto_service : 'com.google.auto.service:auto-service:1.0-rc3', - byte_buddy : 'net.bytebuddy:byte-buddy:1.7.1', - disruptor : 'com.lmax:disruptor:3.3.6', - errorprone : 'com.google.errorprone:error_prone_annotations:2.0.11', - findbugs_annotations : "com.google.code.findbugs:annotations:${findBugsVersion}", - grpc_context : "io.grpc:grpc-context:${grpcContextVersion}", - guava : "com.google.guava:guava:${guavaVersion}", - jsr305 : "com.google.code.findbugs:jsr305:${findBugsVersion}", + auto_value: "com.google.auto.value:auto-value:${autoValueVersion}", + auto_service: 'com.google.auto.service:auto-service:1.0-rc3', + byte_buddy: 'net.bytebuddy:byte-buddy:1.7.1', + disruptor: 'com.lmax:disruptor:3.3.6', + errorprone: 'com.google.errorprone:error_prone_annotations:2.0.19', + findbugs_annotations: "com.google.code.findbugs:annotations:${findBugsVersion}", + grpc_context: "io.grpc:grpc-context:${grpcContextVersion}", + guava: "com.google.guava:guava:${guavaVersion}", + jsr305: "com.google.code.findbugs:jsr305:${findBugsVersion}", // Test dependencies. - guava_testlib : "com.google.guava:guava-testlib:${guavaVersion}", - junit : 'junit:junit:4.11', - mockito : 'org.mockito:mockito-core:1.9.5', - truth : 'com.google.truth:truth:0.30', + guava_testlib: "com.google.guava:guava-testlib:${guavaVersion}", + junit: 'junit:junit:4.11', + mockito: 'org.mockito:mockito-core:1.9.5', + truth: 'com.google.truth:truth:0.30', ] } From 56436cff37d774295e1a66945884651041235651 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Wed, 16 Aug 2017 19:23:28 -0700 Subject: [PATCH 0403/1581] Move stats to impl.stats, change some visibility. (#510) --- .../java/io/opencensus/stats/Aggregation.java | 6 +-- .../io/opencensus/stats/AggregationData.java | 53 ++++++++++++++++--- .../java/io/opencensus/stats/MeasureMap.java | 2 +- .../main/java/io/opencensus/stats/Stats.java | 4 +- .../io/opencensus/stats/StatsRecorder.java | 4 +- .../{ => impl}/stats/MeasureToViewMap.java | 6 ++- .../{ => impl}/stats/MutableAggregation.java | 4 +- .../{ => impl}/stats/MutableViewData.java | 18 ++++--- .../stats/StatsComponentImplBase.java | 3 +- .../{ => impl}/stats/StatsManager.java | 5 +- .../{ => impl}/stats/StatsRecorderImpl.java | 6 ++- .../{ => impl}/stats/ViewManagerImpl.java | 6 ++- .../stats/MeasureToViewMapTest.java | 14 +++-- .../stats/MutableAggregationTest.java | 17 +++--- .../{ => impl}/stats/MutableViewDataTest.java | 32 ++++++----- .../{ => impl}/stats/StatsTestUtil.java | 4 +- .../{ => impl}/stats/ViewManagerImplTest.java | 50 +++++++++-------- .../stats/UnreleasedApiAccessor.java | 38 +++++++++++++ .../stats/StatsComponentImplLite.java | 3 +- .../{ => impl}/stats/StatsTest.java | 4 +- .../{ => impl}/stats/StatsComponentImpl.java | 3 +- .../{ => impl}/stats/StatsTest.java | 4 +- 22 files changed, 204 insertions(+), 82 deletions(-) rename core_impl/src/main/java/io/opencensus/{ => impl}/stats/MeasureToViewMap.java (96%) rename core_impl/src/main/java/io/opencensus/{ => impl}/stats/MutableAggregation.java (98%) rename core_impl/src/main/java/io/opencensus/{ => impl}/stats/MutableViewData.java (95%) rename core_impl/src/main/java/io/opencensus/{ => impl}/stats/StatsComponentImplBase.java (94%) rename core_impl/src/main/java/io/opencensus/{ => impl}/stats/StatsManager.java (94%) rename core_impl/src/main/java/io/opencensus/{ => impl}/stats/StatsRecorderImpl.java (83%) rename core_impl/src/main/java/io/opencensus/{ => impl}/stats/ViewManagerImpl.java (89%) rename core_impl/src/test/java/io/opencensus/{ => impl}/stats/MeasureToViewMapTest.java (81%) rename core_impl/src/test/java/io/opencensus/{ => impl}/stats/MutableAggregationTest.java (91%) rename core_impl/src/test/java/io/opencensus/{ => impl}/stats/MutableViewDataTest.java (81%) rename core_impl/src/test/java/io/opencensus/{ => impl}/stats/StatsTestUtil.java (98%) rename core_impl/src/test/java/io/opencensus/{ => impl}/stats/ViewManagerImplTest.java (91%) create mode 100644 core_impl/src/test/java/io/opencensus/stats/UnreleasedApiAccessor.java rename core_impl_android/src/main/java/io/opencensus/{ => impl}/stats/StatsComponentImplLite.java (92%) rename core_impl_android/src/test/java/io/opencensus/{ => impl}/stats/StatsTest.java (91%) rename core_impl_java/src/main/java/io/opencensus/{ => impl}/stats/StatsComponentImpl.java (92%) rename core_impl_java/src/test/java/io/opencensus/{ => impl}/stats/StatsTest.java (91%) diff --git a/core/src/main/java/io/opencensus/stats/Aggregation.java b/core/src/main/java/io/opencensus/stats/Aggregation.java index 4d36aee7b1..bc4eae2c8d 100644 --- a/core/src/main/java/io/opencensus/stats/Aggregation.java +++ b/core/src/main/java/io/opencensus/stats/Aggregation.java @@ -127,8 +127,7 @@ public abstract static class Histogram extends Aggregation { * * @return a new {@code Histogram}. */ - // TODO(songya): not v0.1, expose factory method later. - static Histogram create(BucketBoundaries bucketBoundaries) { + public static Histogram create(BucketBoundaries bucketBoundaries) { checkNotNull(bucketBoundaries, "bucketBoundaries should not be null."); return new AutoValue_Aggregation_Histogram(bucketBoundaries); } @@ -161,7 +160,8 @@ public abstract static class Range extends Aggregation { * * @return a new {@code Range}. */ - public static Range create() { + // TODO(songya): not v0.1, expose factory method later. + static Range create() { return new AutoValue_Aggregation_Range(); } diff --git a/core/src/main/java/io/opencensus/stats/AggregationData.java b/core/src/main/java/io/opencensus/stats/AggregationData.java index dcf8e50b35..f16a9dee04 100644 --- a/core/src/main/java/io/opencensus/stats/AggregationData.java +++ b/core/src/main/java/io/opencensus/stats/AggregationData.java @@ -66,7 +66,13 @@ public abstract static class SumData extends AggregationData { SumData() { } - static SumData create(double sum) { + /** + * Creates a {@code SumData}. + * + * @param sum the aggregated sum. + * @return a {@code SumData}. + */ + public static SumData create(double sum) { return new AutoValue_AggregationData_SumData(sum); } @@ -98,7 +104,13 @@ public abstract static class CountData extends AggregationData { CountData() { } - static CountData create(long count) { + /** + * Creates a {@code CountData}. + * + * @param count the aggregated count. + * @return a {@code CountData}. + */ + public static CountData create(long count) { return new AutoValue_AggregationData_CountData(count); } @@ -130,10 +142,16 @@ public abstract static class HistogramData extends AggregationData { HistogramData() { } - static HistogramData create(long... bucketCountDatas) { - checkNotNull(bucketCountDatas, "bucket counts should not be null."); + /** + * Creates a {@code HistogramData}. + * + * @param bucketCounts bucket counts. + * @return a {@code HistogramData}. + */ + public static HistogramData create(long... bucketCounts) { + checkNotNull(bucketCounts, "bucket counts should not be null."); List boxedBucketCountDatas = new ArrayList(); - for (long bucketCountData : bucketCountDatas) { + for (long bucketCountData : bucketCounts) { boxedBucketCountDatas.add(bucketCountData); } return new AutoValue_AggregationData_HistogramData( @@ -169,7 +187,14 @@ public abstract static class RangeData extends AggregationData { RangeData() { } - static RangeData create(double min, double max) { + /** + * Creates a {@code RangeData}. + * + * @param min the minimum value + * @param max the maximum value + * @return a {@code RangeData}. + */ + public static RangeData create(double min, double max) { if (min != Double.POSITIVE_INFINITY || max != Double.NEGATIVE_INFINITY) { checkArgument(min <= max, "max should be greater or equal to min."); } @@ -211,7 +236,13 @@ public abstract static class MeanData extends AggregationData { MeanData() { } - static MeanData create(double mean) { + /** + * Creates a {@code MeanData}. + * + * @param mean the aggregated mean. + * @return a {@code MeanData}. + */ + public static MeanData create(double mean) { return new AutoValue_AggregationData_MeanData(mean); } @@ -243,7 +274,13 @@ public abstract static class StdDevData extends AggregationData { StdDevData() { } - static StdDevData create(double stdDev) { + /** + * Creates a {@code StdDevData}. + * + * @param stdDev the aggregated standard deviation. + * @return a {@code StdDevData}. + */ + public static StdDevData create(double stdDev) { return new AutoValue_AggregationData_StdDevData(stdDev); } diff --git a/core/src/main/java/io/opencensus/stats/MeasureMap.java b/core/src/main/java/io/opencensus/stats/MeasureMap.java index a84f4a48fc..c6b262b9bc 100644 --- a/core/src/main/java/io/opencensus/stats/MeasureMap.java +++ b/core/src/main/java/io/opencensus/stats/MeasureMap.java @@ -35,7 +35,7 @@ public static Builder builder() { * Returns an {@link Iterator} over the measure/value mappings in this {@link MeasureMap}. * The {@code Iterator} does not support {@link Iterator#remove()}. */ - Iterator iterator() { + public Iterator iterator() { return new MeasureMapIterator(); } diff --git a/core/src/main/java/io/opencensus/stats/Stats.java b/core/src/main/java/io/opencensus/stats/Stats.java index f8cbce0958..9d9437587b 100644 --- a/core/src/main/java/io/opencensus/stats/Stats.java +++ b/core/src/main/java/io/opencensus/stats/Stats.java @@ -44,7 +44,7 @@ static StatsComponent loadStatsComponent(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. return Provider.createInstance( - Class.forName("io.opencensus.stats.StatsComponentImpl", true, classLoader), + Class.forName("io.opencensus.impl.stats.StatsComponentImpl", true, classLoader), StatsComponent.class); } catch (ClassNotFoundException e) { logger.log( @@ -56,7 +56,7 @@ static StatsComponent loadStatsComponent(ClassLoader classLoader) { try { // Call Class.forName with literal string name of the class to help shading tools. return Provider.createInstance( - Class.forName("io.opencensus.stats.StatsComponentImplLite", true, classLoader), + Class.forName("io.opencensus.impl.stats.StatsComponentImplLite", true, classLoader), StatsComponent.class); } catch (ClassNotFoundException e) { logger.log( diff --git a/core/src/main/java/io/opencensus/stats/StatsRecorder.java b/core/src/main/java/io/opencensus/stats/StatsRecorder.java index ebef1f180b..6f6488c0dd 100644 --- a/core/src/main/java/io/opencensus/stats/StatsRecorder.java +++ b/core/src/main/java/io/opencensus/stats/StatsRecorder.java @@ -33,7 +33,7 @@ public abstract class StatsRecorder { * @param tags the tags associated with the measurements. * @param measurementValues the measurements to record. */ - abstract void record(TagContext tags, MeasureMap measurementValues); + public abstract void record(TagContext tags, MeasureMap measurementValues); /** * Returns a {@code StatsRecorder} that does not record any data. @@ -48,7 +48,7 @@ static StatsRecorder getNoopStatsRecorder() { private static final class NoopStatsRecorder extends StatsRecorder { @Override - void record(TagContext tags, MeasureMap measurementValues) { + public void record(TagContext tags, MeasureMap measurementValues) { Preconditions.checkNotNull(tags); Preconditions.checkNotNull(measurementValues); } diff --git a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java b/core_impl/src/main/java/io/opencensus/impl/stats/MeasureToViewMap.java similarity index 96% rename from core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java rename to core_impl/src/main/java/io/opencensus/impl/stats/MeasureToViewMap.java index 4c99377afb..9162ad6844 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MeasureToViewMap.java +++ b/core_impl/src/main/java/io/opencensus/impl/stats/MeasureToViewMap.java @@ -11,14 +11,18 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import io.opencensus.common.Clock; import io.opencensus.common.Function; +import io.opencensus.stats.MeasureMap; +import io.opencensus.stats.Measurement; import io.opencensus.stats.Measurement.MeasurementDouble; import io.opencensus.stats.Measurement.MeasurementLong; +import io.opencensus.stats.View; +import io.opencensus.stats.ViewData; import io.opencensus.tags.TagContext; import java.util.Collection; import java.util.HashMap; diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableAggregation.java b/core_impl/src/main/java/io/opencensus/impl/stats/MutableAggregation.java similarity index 98% rename from core_impl/src/main/java/io/opencensus/stats/MutableAggregation.java rename to core_impl/src/main/java/io/opencensus/impl/stats/MutableAggregation.java index 538a262dcd..e5666c8047 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableAggregation.java +++ b/core_impl/src/main/java/io/opencensus/impl/stats/MutableAggregation.java @@ -11,12 +11,14 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import static com.google.common.base.Preconditions.checkNotNull; import io.opencensus.common.Function; +import io.opencensus.stats.Aggregation; +import io.opencensus.stats.BucketBoundaries; import java.util.Arrays; /** Mutable version of {@link Aggregation} that supports adding values. */ diff --git a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java b/core_impl/src/main/java/io/opencensus/impl/stats/MutableViewData.java similarity index 95% rename from core_impl/src/main/java/io/opencensus/stats/MutableViewData.java rename to core_impl/src/main/java/io/opencensus/impl/stats/MutableViewData.java index f605853ba5..73bd5231d5 100644 --- a/core_impl/src/main/java/io/opencensus/stats/MutableViewData.java +++ b/core_impl/src/main/java/io/opencensus/impl/stats/MutableViewData.java @@ -11,7 +11,7 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; @@ -20,27 +20,31 @@ import io.opencensus.common.Function; import io.opencensus.common.Functions; import io.opencensus.common.Timestamp; +import io.opencensus.impl.stats.MutableAggregation.MutableCount; +import io.opencensus.impl.stats.MutableAggregation.MutableHistogram; +import io.opencensus.impl.stats.MutableAggregation.MutableMean; +import io.opencensus.impl.stats.MutableAggregation.MutableRange; +import io.opencensus.impl.stats.MutableAggregation.MutableStdDev; +import io.opencensus.impl.stats.MutableAggregation.MutableSum; import io.opencensus.impl.tags.TagContextImpl; +import io.opencensus.stats.Aggregation; import io.opencensus.stats.Aggregation.Count; import io.opencensus.stats.Aggregation.Histogram; import io.opencensus.stats.Aggregation.Mean; import io.opencensus.stats.Aggregation.Range; import io.opencensus.stats.Aggregation.StdDev; import io.opencensus.stats.Aggregation.Sum; +import io.opencensus.stats.AggregationData; import io.opencensus.stats.AggregationData.CountData; import io.opencensus.stats.AggregationData.HistogramData; import io.opencensus.stats.AggregationData.MeanData; import io.opencensus.stats.AggregationData.RangeData; import io.opencensus.stats.AggregationData.StdDevData; import io.opencensus.stats.AggregationData.SumData; -import io.opencensus.stats.MutableAggregation.MutableCount; -import io.opencensus.stats.MutableAggregation.MutableHistogram; -import io.opencensus.stats.MutableAggregation.MutableMean; -import io.opencensus.stats.MutableAggregation.MutableRange; -import io.opencensus.stats.MutableAggregation.MutableStdDev; -import io.opencensus.stats.MutableAggregation.MutableSum; +import io.opencensus.stats.View; import io.opencensus.stats.View.Window.Cumulative; import io.opencensus.stats.View.Window.Interval; +import io.opencensus.stats.ViewData; import io.opencensus.stats.ViewData.WindowData.CumulativeData; import io.opencensus.tags.Tag; import io.opencensus.tags.Tag.TagBoolean; diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java b/core_impl/src/main/java/io/opencensus/impl/stats/StatsComponentImplBase.java similarity index 94% rename from core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java rename to core_impl/src/main/java/io/opencensus/impl/stats/StatsComponentImplBase.java index 3f65918bb2..d0f9d86938 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/impl/stats/StatsComponentImplBase.java @@ -11,10 +11,11 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import io.opencensus.common.Clock; import io.opencensus.impl.internal.EventQueue; +import io.opencensus.stats.StatsComponent; /** Base implementation of {@link StatsComponent}. */ class StatsComponentImplBase extends StatsComponent { diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java b/core_impl/src/main/java/io/opencensus/impl/stats/StatsManager.java similarity index 94% rename from core_impl/src/main/java/io/opencensus/stats/StatsManager.java rename to core_impl/src/main/java/io/opencensus/impl/stats/StatsManager.java index dea81b0d11..4094f49501 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsManager.java +++ b/core_impl/src/main/java/io/opencensus/impl/stats/StatsManager.java @@ -11,10 +11,13 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import io.opencensus.common.Clock; import io.opencensus.impl.internal.EventQueue; +import io.opencensus.stats.MeasureMap; +import io.opencensus.stats.View; +import io.opencensus.stats.ViewData; import io.opencensus.tags.TagContext; /** Object that stores all views and stats. */ diff --git a/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java b/core_impl/src/main/java/io/opencensus/impl/stats/StatsRecorderImpl.java similarity index 83% rename from core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java rename to core_impl/src/main/java/io/opencensus/impl/stats/StatsRecorderImpl.java index ff9eadde34..d7e9b084f9 100644 --- a/core_impl/src/main/java/io/opencensus/stats/StatsRecorderImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/stats/StatsRecorderImpl.java @@ -11,8 +11,10 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; +import io.opencensus.stats.MeasureMap; +import io.opencensus.stats.StatsRecorder; import io.opencensus.tags.TagContext; /** Implementation of {@link StatsRecorder}. */ @@ -24,7 +26,7 @@ final class StatsRecorderImpl extends StatsRecorder { } @Override - void record(TagContext tags, MeasureMap measurementValues) { + public void record(TagContext tags, MeasureMap measurementValues) { statsManager.record(tags, measurementValues); } } diff --git a/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java b/core_impl/src/main/java/io/opencensus/impl/stats/ViewManagerImpl.java similarity index 89% rename from core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java rename to core_impl/src/main/java/io/opencensus/impl/stats/ViewManagerImpl.java index 708f35ee5e..60292611a8 100644 --- a/core_impl/src/main/java/io/opencensus/stats/ViewManagerImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/stats/ViewManagerImpl.java @@ -11,7 +11,11 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; + +import io.opencensus.stats.View; +import io.opencensus.stats.ViewData; +import io.opencensus.stats.ViewManager; /** Implementation of {@link ViewManager}. */ final class ViewManagerImpl extends ViewManager { diff --git a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java b/core_impl/src/test/java/io/opencensus/impl/stats/MeasureToViewMapTest.java similarity index 81% rename from core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java rename to core_impl/src/test/java/io/opencensus/impl/stats/MeasureToViewMapTest.java index 47b71faee1..91031cbb2b 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MeasureToViewMapTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/stats/MeasureToViewMapTest.java @@ -11,11 +11,17 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.Timestamp; +import io.opencensus.stats.Aggregation; +import io.opencensus.stats.Measure; +import io.opencensus.stats.UnreleasedApiAccessor; +import io.opencensus.stats.View; +import io.opencensus.stats.View.Name; +import io.opencensus.stats.ViewData; import io.opencensus.stats.ViewData.WindowData.CumulativeData; import io.opencensus.tags.TagKey.TagKeyString; import io.opencensus.testing.common.TestClock; @@ -35,11 +41,11 @@ public class MeasureToViewMapTest { "measurement description", "By"); - private static final View.Name VIEW_NAME = View.Name.create("my view"); + private static final Name VIEW_NAME = View.Name.create("my view"); private static final List AGGREGATIONS_NO_HISTOGRAM = Arrays.asList( - Aggregation.Sum.create(), Aggregation.Count.create(), Aggregation.Range.create(), - Aggregation.Mean.create(), Aggregation.StdDev.create()); + Aggregation.Sum.create(), Aggregation.Count.create(), UnreleasedApiAccessor.createRange(), + UnreleasedApiAccessor.createMean(), UnreleasedApiAccessor.createStdDev()); private static final View.Window.Cumulative CUMULATIVE = View.Window.Cumulative.create(); diff --git a/core_impl/src/test/java/io/opencensus/stats/MutableAggregationTest.java b/core_impl/src/test/java/io/opencensus/impl/stats/MutableAggregationTest.java similarity index 91% rename from core_impl/src/test/java/io/opencensus/stats/MutableAggregationTest.java rename to core_impl/src/test/java/io/opencensus/impl/stats/MutableAggregationTest.java index 960f9f1089..2d642fb862 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MutableAggregationTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/stats/MutableAggregationTest.java @@ -11,17 +11,18 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import static com.google.common.truth.Truth.assertThat; import io.opencensus.common.Function; -import io.opencensus.stats.MutableAggregation.MutableCount; -import io.opencensus.stats.MutableAggregation.MutableHistogram; -import io.opencensus.stats.MutableAggregation.MutableMean; -import io.opencensus.stats.MutableAggregation.MutableRange; -import io.opencensus.stats.MutableAggregation.MutableStdDev; -import io.opencensus.stats.MutableAggregation.MutableSum; +import io.opencensus.impl.stats.MutableAggregation.MutableCount; +import io.opencensus.impl.stats.MutableAggregation.MutableHistogram; +import io.opencensus.impl.stats.MutableAggregation.MutableMean; +import io.opencensus.impl.stats.MutableAggregation.MutableRange; +import io.opencensus.impl.stats.MutableAggregation.MutableStdDev; +import io.opencensus.impl.stats.MutableAggregation.MutableSum; +import io.opencensus.stats.BucketBoundaries; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -31,7 +32,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@link io.opencensus.stats.MutableAggregation}. */ +/** Unit tests for {@link io.opencensus.impl.stats.MutableAggregation}. */ @RunWith(JUnit4.class) public class MutableAggregationTest { diff --git a/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java b/core_impl/src/test/java/io/opencensus/impl/stats/MutableViewDataTest.java similarity index 81% rename from core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java rename to core_impl/src/test/java/io/opencensus/impl/stats/MutableViewDataTest.java index 3b5368ed7f..1de2867e93 100644 --- a/core_impl/src/test/java/io/opencensus/stats/MutableViewDataTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/stats/MutableViewDataTest.java @@ -11,29 +11,29 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableMap; +import io.opencensus.impl.stats.MutableAggregation.MutableCount; +import io.opencensus.impl.stats.MutableAggregation.MutableHistogram; +import io.opencensus.impl.stats.MutableAggregation.MutableMean; +import io.opencensus.impl.stats.MutableAggregation.MutableRange; +import io.opencensus.impl.stats.MutableAggregation.MutableStdDev; +import io.opencensus.impl.stats.MutableAggregation.MutableSum; import io.opencensus.stats.Aggregation.Count; import io.opencensus.stats.Aggregation.Histogram; -import io.opencensus.stats.Aggregation.Mean; -import io.opencensus.stats.Aggregation.Range; -import io.opencensus.stats.Aggregation.StdDev; import io.opencensus.stats.Aggregation.Sum; +import io.opencensus.stats.AggregationData; import io.opencensus.stats.AggregationData.CountData; import io.opencensus.stats.AggregationData.HistogramData; import io.opencensus.stats.AggregationData.MeanData; import io.opencensus.stats.AggregationData.RangeData; import io.opencensus.stats.AggregationData.StdDevData; import io.opencensus.stats.AggregationData.SumData; -import io.opencensus.stats.MutableAggregation.MutableCount; -import io.opencensus.stats.MutableAggregation.MutableHistogram; -import io.opencensus.stats.MutableAggregation.MutableMean; -import io.opencensus.stats.MutableAggregation.MutableRange; -import io.opencensus.stats.MutableAggregation.MutableStdDev; -import io.opencensus.stats.MutableAggregation.MutableSum; +import io.opencensus.stats.BucketBoundaries; +import io.opencensus.stats.UnreleasedApiAccessor; import io.opencensus.tags.TagKey.TagKeyString; import io.opencensus.tags.TagValueString; import java.util.ArrayList; @@ -87,16 +87,20 @@ public void createMutableAggregation() { Histogram.create(bucketBoundaries))).getBucketCounts()) .isEqualTo(new long[]{0, 0, 0, 0}); assertThat( - ((MutableRange) MutableViewData.createMutableAggregation(Range.create())).getMin()) + ((MutableRange) MutableViewData + .createMutableAggregation(UnreleasedApiAccessor.createRange())).getMin()) .isPositiveInfinity(); assertThat( - ((MutableRange) MutableViewData.createMutableAggregation(Range.create())).getMax()) + ((MutableRange) MutableViewData + .createMutableAggregation(UnreleasedApiAccessor.createRange())).getMax()) .isNegativeInfinity(); assertThat( - ((MutableMean) MutableViewData.createMutableAggregation(Mean.create())).getMean()) + ((MutableMean) MutableViewData.createMutableAggregation(UnreleasedApiAccessor.createMean())) + .getMean()) .isWithin(EPSILON).of(0D); assertThat( - ((MutableStdDev) MutableViewData.createMutableAggregation(StdDev.create())).getStdDev()) + ((MutableStdDev) MutableViewData + .createMutableAggregation(UnreleasedApiAccessor.createStdDev())).getStdDev()) .isWithin(EPSILON).of(0D); } diff --git a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java b/core_impl/src/test/java/io/opencensus/impl/stats/StatsTestUtil.java similarity index 98% rename from core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java rename to core_impl/src/test/java/io/opencensus/impl/stats/StatsTestUtil.java index f744771084..128fb49f39 100644 --- a/core_impl/src/test/java/io/opencensus/stats/StatsTestUtil.java +++ b/core_impl/src/test/java/io/opencensus/impl/stats/StatsTestUtil.java @@ -11,13 +11,15 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.Iterables; import io.opencensus.common.Function; import io.opencensus.common.Functions; +import io.opencensus.stats.Aggregation; +import io.opencensus.stats.AggregationData; import io.opencensus.stats.AggregationData.CountData; import io.opencensus.stats.AggregationData.HistogramData; import io.opencensus.stats.AggregationData.MeanData; diff --git a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java b/core_impl/src/test/java/io/opencensus/impl/stats/ViewManagerImplTest.java similarity index 91% rename from core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java rename to core_impl/src/test/java/io/opencensus/impl/stats/ViewManagerImplTest.java index b920c94b02..184ff22ba5 100644 --- a/core_impl/src/test/java/io/opencensus/stats/ViewManagerImplTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/stats/ViewManagerImplTest.java @@ -11,24 +11,31 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import static com.google.common.truth.Truth.assertThat; +import static io.opencensus.impl.stats.StatsTestUtil.assertAggregationMapEquals; +import static io.opencensus.impl.stats.StatsTestUtil.createAggregationData; import com.google.common.collect.ImmutableMap; import io.opencensus.common.Duration; import io.opencensus.common.Timestamp; import io.opencensus.impl.internal.SimpleEventQueue; import io.opencensus.impl.tags.TagContextsImpl; +import io.opencensus.stats.Aggregation; import io.opencensus.stats.Aggregation.Count; import io.opencensus.stats.Aggregation.Histogram; -import io.opencensus.stats.Aggregation.Mean; -import io.opencensus.stats.Aggregation.Range; -import io.opencensus.stats.Aggregation.StdDev; import io.opencensus.stats.Aggregation.Sum; +import io.opencensus.stats.BucketBoundaries; +import io.opencensus.stats.Measure; import io.opencensus.stats.Measure.MeasureDouble; +import io.opencensus.stats.MeasureMap; +import io.opencensus.stats.UnreleasedApiAccessor; +import io.opencensus.stats.View; +import io.opencensus.stats.View.Name; import io.opencensus.stats.View.Window.Cumulative; import io.opencensus.stats.View.Window.Interval; +import io.opencensus.stats.ViewData; import io.opencensus.stats.ViewData.WindowData.CumulativeData; import io.opencensus.tags.TagContext; import io.opencensus.tags.TagContexts; @@ -66,8 +73,8 @@ public class ViewManagerImplTest { private static final MeasureDouble MEASURE = Measure.MeasureDouble.create(MEASURE_NAME, MEASURE_DESCRIPTION, MEASURE_UNIT); - private static final View.Name VIEW_NAME = View.Name.create("my view"); - private static final View.Name VIEW_NAME_2 = View.Name.create("my view 2"); + private static final Name VIEW_NAME = Name.create("my view"); + private static final Name VIEW_NAME_2 = Name.create("my view 2"); private static final String VIEW_DESCRIPTION = "view description"; @@ -85,10 +92,10 @@ public class ViewManagerImplTest { Arrays.asList( Sum.create(), Count.create(), - Range.create(), + UnreleasedApiAccessor.createRange(), Histogram.create(BUCKET_BOUNDARIES), - Mean.create(), - StdDev.create())); + UnreleasedApiAccessor.createMean(), + UnreleasedApiAccessor.createStdDev())); private final TestClock clock = TestClock.create(); @@ -97,7 +104,7 @@ public class ViewManagerImplTest { private final TagContexts tagContexts = new TagContextsImpl(); private final ViewManagerImpl viewManager = statsComponent.getViewManager(); - private final StatsRecorder statsRecorder = statsComponent.getStatsRecorder(); + private final StatsRecorderImpl statsRecorder = statsComponent.getStatsRecorder(); private static View createCumulativeView() { return createCumulativeView(VIEW_NAME, MEASURE, AGGREGATIONS, Arrays.asList(KEY)); @@ -234,13 +241,13 @@ public void testRecordMultipleTagValues() { tagContexts.emptyBuilder().set(KEY, VALUE_2).build(), MeasureMap.builder().set(MEASURE, 50.0).build()); ViewData viewData = viewManager.getView(VIEW_NAME); - StatsTestUtil.assertAggregationMapEquals( + assertAggregationMapEquals( viewData.getAggregationMap(), ImmutableMap.of( Arrays.asList(VALUE), - StatsTestUtil.createAggregationData(AGGREGATIONS, 10.0), + createAggregationData(AGGREGATIONS, 10.0), Arrays.asList(VALUE_2), - StatsTestUtil.createAggregationData(AGGREGATIONS, 30.0, 50.0)), + createAggregationData(AGGREGATIONS, 30.0, 50.0)), EPSILON); } @@ -260,14 +267,14 @@ public void testRecordWithEmptyStatsContext() { // DEFAULT doesn't have tags, but the view has tag key "KEY". statsRecorder.record(tagContexts.empty(), MeasureMap.builder().set(MEASURE, 10.0).build()); ViewData viewData = viewManager.getView(VIEW_NAME); - StatsTestUtil.assertAggregationMapEquals( + assertAggregationMapEquals( viewData.getAggregationMap(), ImmutableMap.of( // Tag is missing for associated measureValues, should use default tag value // "unknown/not set". Arrays.asList(MutableViewData.UNKNOWN_TAG_VALUE), // Should record stats with default tag value: "KEY" : "unknown/not set". - StatsTestUtil.createAggregationData(AGGREGATIONS, 10.0)), + createAggregationData(AGGREGATIONS, 10.0)), EPSILON); } @@ -298,14 +305,14 @@ public void testRecordWithTagsThatDoNotMatchViewData() { tagContexts.emptyBuilder().set(TagKeyString.create("another wrong key"), VALUE).build(), MeasureMap.builder().set(MEASURE, 50.0).build()); ViewData viewData = viewManager.getView(VIEW_NAME); - StatsTestUtil.assertAggregationMapEquals( + assertAggregationMapEquals( viewData.getAggregationMap(), ImmutableMap.of( // Won't record the unregistered tag key, for missing registered keys will use default // tag value : "unknown/not set". Arrays.asList(MutableViewData.UNKNOWN_TAG_VALUE), // Should record stats with default tag value: "KEY" : "unknown/not set". - StatsTestUtil.createAggregationData(AGGREGATIONS, 10.0, 50.0)), + createAggregationData(AGGREGATIONS, 10.0, 50.0)), EPSILON); } @@ -344,7 +351,7 @@ public void testViewDataWithMultipleTagKeys() { .build(), MeasureMap.builder().set(MEASURE, 4.4).build()); ViewData viewData = viewManager.getView(VIEW_NAME); - StatsTestUtil.assertAggregationMapEquals( + assertAggregationMapEquals( viewData.getAggregationMap(), ImmutableMap.of( Arrays.asList(TagValueString.create("v1"), TagValueString.create("v10")), @@ -425,8 +432,9 @@ public void testMultipleViewsDifferentMeasures() { @Test public void testGetCumulativeViewDataWithoutBucketBoundaries() { - List aggregationsNoHistogram = - Arrays.asList(Sum.create(), Count.create(), Mean.create(), Range.create(), StdDev.create()); + List aggregationsNoHistogram = Arrays.asList( + Sum.create(), Count.create(), UnreleasedApiAccessor.createMean(), + UnreleasedApiAccessor.createRange(), UnreleasedApiAccessor.createStdDev()); View view = createCumulativeView(VIEW_NAME, MEASURE, aggregationsNoHistogram, Arrays.asList(KEY)); clock.setTime(Timestamp.create(1, 0)); @@ -442,7 +450,7 @@ public void testGetCumulativeViewDataWithoutBucketBoundaries() { viewData.getAggregationMap(), ImmutableMap.of( Arrays.asList(VALUE), - StatsTestUtil.createAggregationData(aggregationsNoHistogram, 1.1)), + createAggregationData(aggregationsNoHistogram, 1.1)), EPSILON); } } diff --git a/core_impl/src/test/java/io/opencensus/stats/UnreleasedApiAccessor.java b/core_impl/src/test/java/io/opencensus/stats/UnreleasedApiAccessor.java new file mode 100644 index 0000000000..7ec3063792 --- /dev/null +++ b/core_impl/src/test/java/io/opencensus/stats/UnreleasedApiAccessor.java @@ -0,0 +1,38 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.stats; + +import io.opencensus.stats.Aggregation.Mean; +import io.opencensus.stats.Aggregation.Range; +import io.opencensus.stats.Aggregation.StdDev; + +/** + * Class for accessing methods in the {@code io.opencensus.stats} package that haven't been made + * public yet. + */ +public final class UnreleasedApiAccessor { + private UnreleasedApiAccessor() {} + + public static Range createRange() { + return Range.create(); + } + + public static Mean createMean() { + return Mean.create(); + } + + public static StdDev createStdDev() { + return StdDev.create(); + } +} \ No newline at end of file diff --git a/core_impl_android/src/main/java/io/opencensus/stats/StatsComponentImplLite.java b/core_impl_android/src/main/java/io/opencensus/impl/stats/StatsComponentImplLite.java similarity index 92% rename from core_impl_android/src/main/java/io/opencensus/stats/StatsComponentImplLite.java rename to core_impl_android/src/main/java/io/opencensus/impl/stats/StatsComponentImplLite.java index 1d7b453200..f0641719d5 100644 --- a/core_impl_android/src/main/java/io/opencensus/stats/StatsComponentImplLite.java +++ b/core_impl_android/src/main/java/io/opencensus/impl/stats/StatsComponentImplLite.java @@ -11,10 +11,11 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import io.opencensus.impl.common.MillisClock; import io.opencensus.impl.internal.SimpleEventQueue; +import io.opencensus.stats.StatsComponent; /** * Android-compatible implementation of {@link StatsComponent}. diff --git a/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java b/core_impl_android/src/test/java/io/opencensus/impl/stats/StatsTest.java similarity index 91% rename from core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java rename to core_impl_android/src/test/java/io/opencensus/impl/stats/StatsTest.java index af932ea79a..e637b805a8 100644 --- a/core_impl_android/src/test/java/io/opencensus/stats/StatsTest.java +++ b/core_impl_android/src/test/java/io/opencensus/impl/stats/StatsTest.java @@ -11,10 +11,12 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import static com.google.common.truth.Truth.assertThat; +import io.opencensus.stats.Stats; +import io.opencensus.stats.StatsComponent; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core_impl_java/src/main/java/io/opencensus/stats/StatsComponentImpl.java b/core_impl_java/src/main/java/io/opencensus/impl/stats/StatsComponentImpl.java similarity index 92% rename from core_impl_java/src/main/java/io/opencensus/stats/StatsComponentImpl.java rename to core_impl_java/src/main/java/io/opencensus/impl/stats/StatsComponentImpl.java index 610fd2692d..461a6a2bef 100644 --- a/core_impl_java/src/main/java/io/opencensus/stats/StatsComponentImpl.java +++ b/core_impl_java/src/main/java/io/opencensus/impl/stats/StatsComponentImpl.java @@ -11,10 +11,11 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import io.opencensus.impl.common.MillisClock; import io.opencensus.impl.internal.DisruptorEventQueue; +import io.opencensus.stats.StatsComponent; /** Java 7 and 8 implementation of {@link StatsComponent}. */ public final class StatsComponentImpl extends StatsComponentImplBase { diff --git a/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java b/core_impl_java/src/test/java/io/opencensus/impl/stats/StatsTest.java similarity index 91% rename from core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java rename to core_impl_java/src/test/java/io/opencensus/impl/stats/StatsTest.java index 28752964d1..36ff3e79e6 100644 --- a/core_impl_java/src/test/java/io/opencensus/stats/StatsTest.java +++ b/core_impl_java/src/test/java/io/opencensus/impl/stats/StatsTest.java @@ -11,10 +11,12 @@ * limitations under the License. */ -package io.opencensus.stats; +package io.opencensus.impl.stats; import static com.google.common.truth.Truth.assertThat; +import io.opencensus.stats.Stats; +import io.opencensus.stats.StatsComponent; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; From 88246a4c6de8c3c080a18107141f9b5beaf30ff9 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 11 Aug 2017 13:20:45 -0700 Subject: [PATCH 0404/1581] Copy i/o/stats/StatsSerializer.java to i/o/impl/tags/SerializationUtils.java. --- .../impl/tags/SerializationUtils.java | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java b/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java new file mode 100644 index 0000000000..2437dc43bc --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java @@ -0,0 +1,155 @@ +/* + * Copyright 2016, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.tags; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.io.ByteStreams; +import io.opencensus.internal.VarInt; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map.Entry; +import java.util.Set; + +/** + * Native implementation {@link StatsContext} serialization. + * + *

Encoding of stats context information (tags) for passing across RPC's:

+ * + *
    + *
  • Tags are encoded in single byte sequence. The version 0 format is: + *
  • {@code } + *
  • {@code == a single byte, value 0} + *
  • {@code == ()*} + *
      + *
    • {@code } == a single byte, value 0 (string tag), 1 (int tag), + * 2 (true bool tag), 3 (false bool tag) + *
    • {@code }: + *
        + *
      • {@code (tag_field_id == 0) == } + *
          + *
        • {@code } == varint encoded integer + *
        • {@code } == tag_key_len bytes comprising tag key name + *
        • {@code } == varint encoded integer + *
        • {@code } == tag_val_len bytes comprising UTF-8 string + *
        + *
      • {@code (tag_field_id == 1) == } + *
          + *
        • {@code } == varint encoded integer + *
        • {@code } == tag_key_len bytes comprising tag key name + *
        • {@code } == 8 bytes, little-endian integer + *
        + *
      • {@code (tag_field_id == 2 || tag_field_id == 3) == } + *
          + *
        • {@code } == varint encoded integer + *
        • {@code } == tag_key_len bytes comprising tag key name + *
        + *
      + *
    + *
+ */ +final class SerializationUtils { + + // TODO(songya): Currently we only support encoding on string type. + @VisibleForTesting static final int VERSION_ID = 0; + @VisibleForTesting static final int VALUE_TYPE_STRING = 0; + @VisibleForTesting static final int VALUE_TYPE_INTEGER = 1; + @VisibleForTesting static final int VALUE_TYPE_TRUE = 2; + @VisibleForTesting static final int VALUE_TYPE_FALSE = 3; + + + // Serializes a StatsContext to the on-the-wire format. + // Encoded tags are of the form: + static void serialize(StatsContextImpl context, OutputStream output) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byteArrayOutputStream.write(VERSION_ID); + + // TODO(songya): add support for value types integer and boolean + Set> tags = context.tags.entrySet(); + for (Entry tag : tags) { + encodeStringTag(tag.getKey(), tag.getValue(), byteArrayOutputStream); + } + byteArrayOutputStream.writeTo(output); + } + + // Deserializes input to StatsContext based on the binary format standard. + // The encoded tags are of the form: + static StatsContextImpl deserialize(StatsRecorderImpl statsRecorder, InputStream input) + throws IOException { + try { + byte[] bytes = ByteStreams.toByteArray(input); + HashMap tags = new HashMap(); + if (bytes.length == 0) { + // Does not allow empty byte array. + throw new IOException("Input byte stream can not be empty."); + } + + ByteBuffer buffer = ByteBuffer.wrap(bytes).asReadOnlyBuffer(); + int versionId = buffer.get(); + if (versionId != VERSION_ID) { + throw new IOException( + "Wrong Version ID: " + versionId + ". Currently supported version is: " + VERSION_ID); + } + + int limit = buffer.limit(); + while (buffer.position() < limit) { + int type = buffer.get(); + switch (type) { + case VALUE_TYPE_STRING: + TagKey key = TagKey.create(decodeString(buffer)); + TagValue val = TagValue.create(decodeString(buffer)); + tags.put(key, val); + break; + case VALUE_TYPE_INTEGER: + case VALUE_TYPE_TRUE: + case VALUE_TYPE_FALSE: + default: + // TODO(songya): add support for value types integer and boolean + throw new IOException("Unsupported tag value type."); + } + } + return new StatsContextImpl(statsRecorder, tags); + } catch (BufferUnderflowException exn) { + throw new IOException(exn.toString()); // byte array format error. + } + } + + // TODO(songya): Currently we only support encoding on string type. + private static final void encodeStringTag( + TagKey key, TagValue value, ByteArrayOutputStream byteArrayOutputStream) + throws IOException { + byteArrayOutputStream.write(VALUE_TYPE_STRING); + encodeString(key.asString(), byteArrayOutputStream); + encodeString(value.asString(), byteArrayOutputStream); + } + + private static final void encodeString(String input, ByteArrayOutputStream byteArrayOutputStream) + throws IOException { + VarInt.putVarInt(input.length(), byteArrayOutputStream); + byteArrayOutputStream.write(input.getBytes("UTF-8")); + } + + private static final String decodeString(ByteBuffer buffer) { + int length = VarInt.getVarInt(buffer); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < length; i++) { + builder.append((char) buffer.get()); + } + return builder.toString(); + } +} \ No newline at end of file From 8ffe239bff4937d937427b243f2c2988c9184f68 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 11 Aug 2017 13:23:38 -0700 Subject: [PATCH 0405/1581] Run google-java-format on SerializationUtils.java. --- .../impl/tags/SerializationUtils.java | 56 +++++++++---------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java b/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java index 2437dc43bc..94b783a056 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java @@ -29,7 +29,7 @@ /** * Native implementation {@link StatsContext} serialization. * - *

Encoding of stats context information (tags) for passing across RPC's:

+ *

Encoding of stats context information (tags) for passing across RPC's: * *

    *
  • Tags are encoded in single byte sequence. The version 0 format is: @@ -37,29 +37,29 @@ *
  • {@code == a single byte, value 0} *
  • {@code == ()*} *
      - *
    • {@code } == a single byte, value 0 (string tag), 1 (int tag), - * 2 (true bool tag), 3 (false bool tag) - *
    • {@code }: - *
        - *
      • {@code (tag_field_id == 0) == } - *
          - *
        • {@code } == varint encoded integer - *
        • {@code } == tag_key_len bytes comprising tag key name - *
        • {@code } == varint encoded integer - *
        • {@code } == tag_val_len bytes comprising UTF-8 string - *
        - *
      • {@code (tag_field_id == 1) == } - *
          - *
        • {@code } == varint encoded integer - *
        • {@code } == tag_key_len bytes comprising tag key name - *
        • {@code } == 8 bytes, little-endian integer - *
        - *
      • {@code (tag_field_id == 2 || tag_field_id == 3) == } - *
          - *
        • {@code } == varint encoded integer - *
        • {@code } == tag_key_len bytes comprising tag key name - *
        - *
      + *
    • {@code } == a single byte, value 0 (string tag), 1 (int tag), 2 (true + * bool tag), 3 (false bool tag) + *
    • {@code }: + *
        + *
      • {@code (tag_field_id == 0) == } + *
          + *
        • {@code } == varint encoded integer + *
        • {@code } == tag_key_len bytes comprising tag key name + *
        • {@code } == varint encoded integer + *
        • {@code } == tag_val_len bytes comprising UTF-8 string + *
        + *
      • {@code (tag_field_id == 1) == } + *
          + *
        • {@code } == varint encoded integer + *
        • {@code } == tag_key_len bytes comprising tag key name + *
        • {@code } == 8 bytes, little-endian integer + *
        + *
      • {@code (tag_field_id == 2 || tag_field_id == 3) == } + *
          + *
        • {@code } == varint encoded integer + *
        • {@code } == tag_key_len bytes comprising tag key name + *
        + *
      *
    *
*/ @@ -72,7 +72,6 @@ final class SerializationUtils { @VisibleForTesting static final int VALUE_TYPE_TRUE = 2; @VisibleForTesting static final int VALUE_TYPE_FALSE = 3; - // Serializes a StatsContext to the on-the-wire format. // Encoded tags are of the form: static void serialize(StatsContextImpl context, OutputStream output) throws IOException { @@ -125,14 +124,13 @@ static StatsContextImpl deserialize(StatsRecorderImpl statsRecorder, InputStream } return new StatsContextImpl(statsRecorder, tags); } catch (BufferUnderflowException exn) { - throw new IOException(exn.toString()); // byte array format error. + throw new IOException(exn.toString()); // byte array format error. } } // TODO(songya): Currently we only support encoding on string type. private static final void encodeStringTag( - TagKey key, TagValue value, ByteArrayOutputStream byteArrayOutputStream) - throws IOException { + TagKey key, TagValue value, ByteArrayOutputStream byteArrayOutputStream) throws IOException { byteArrayOutputStream.write(VALUE_TYPE_STRING); encodeString(key.asString(), byteArrayOutputStream); encodeString(value.asString(), byteArrayOutputStream); @@ -152,4 +150,4 @@ private static final String decodeString(ByteBuffer buffer) { } return builder.toString(); } -} \ No newline at end of file +} From 617c9cbd4a83ea3fa44d6334539f669c4c865bb4 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 11 Aug 2017 15:36:01 -0700 Subject: [PATCH 0406/1581] Copy StatsContext serialization tests to tags package. This commit copies StatsContextTest.java to TagContextSerializationTest.java and copies StatsContextFactoryTest.java to TagContextDeserializationTest.java. --- .../tags/TagContextDeserializationTest.java | 273 ++++++++++++++++++ .../tags/TagContextSerializationTest.java | 254 ++++++++++++++++ 2 files changed, 527 insertions(+) create mode 100644 core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java create mode 100644 core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java new file mode 100644 index 0000000000..9accf4a464 --- /dev/null +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java @@ -0,0 +1,273 @@ +/* + * Copyright 2016, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.tags; + +import static com.google.common.truth.Truth.assertThat; + +import io.grpc.Context; +import io.opencensus.common.Scope; +import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.internal.VarInt; +import io.opencensus.testing.common.TestClock; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for {@link StatsContextFactory}. + */ +@RunWith(JUnit4.class) +public class TagContextDeserializationTest { + + private static final String KEY = "Key"; + private static final String VALUE_STRING = "String"; + private static final int VALUE_INT = 10; + + private final StatsComponentImplBase statsComponent = + new StatsComponentImplBase(new SimpleEventQueue(), TestClock.create()); + private final StatsContextFactory factory = statsComponent.getStatsContextFactory(); + private final StatsRecorderImpl statsRecorder = statsComponent.getStatsRecorder(); + private final HashMap sampleTags = new HashMap(); + private final StatsContext defaultCtx = factory.getDefault(); + private final StatsContext statsContext = factory.getDefault() + .with(TagKey.create(KEY), TagValue.create(VALUE_STRING)); + + public TagContextDeserializationTest() { + sampleTags.put( + TagKey.create(KEY + StatsSerializer.VALUE_TYPE_STRING), TagValue.create(VALUE_STRING)); + } + + @Test + public void testVersionAndValueTypeConstants() { + // Refer to the JavaDoc on StatsSerializer for the definitions on these constants. + assertThat(StatsSerializer.VERSION_ID).isEqualTo(0); + assertThat(StatsSerializer.VALUE_TYPE_STRING).isEqualTo(0); + assertThat(StatsSerializer.VALUE_TYPE_INTEGER).isEqualTo(1); + assertThat(StatsSerializer.VALUE_TYPE_TRUE).isEqualTo(2); + assertThat(StatsSerializer.VALUE_TYPE_FALSE).isEqualTo(3); + } + + @Test + public void testDeserializeNoTags() throws Exception { + StatsContext expected = factory.getDefault(); + StatsContext actual = testDeserialize( + new ByteArrayInputStream( + new byte[]{StatsSerializer.VERSION_ID})); // One byte that represents Version ID. + assertThat(actual).isEqualTo(expected); + } + + @Test(expected = IOException.class) + public void testDeserializeEmptyByteArrayThrowException() throws Exception { + testDeserialize(new ByteArrayInputStream(new byte[0])); + } + + @Test + public void testDeserializeValueTypeString() throws Exception { + StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); + StatsContext actual = testDeserialize( + constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_STRING)); + assertThat(actual).isEqualTo(expected); + } + + @Test + public void testDeserializeMultipleString() throws Exception { + sampleTags.put(TagKey.create("Key2"), TagValue.create("String2")); + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byteArrayOutputStream.write(StatsSerializer.VERSION_ID); + encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_STRING, byteArrayOutputStream); + byteArrayOutputStream.write(StatsSerializer.VALUE_TYPE_STRING); + encodeString("Key2", byteArrayOutputStream); + encodeString("String2", byteArrayOutputStream); + StatsContext actual = testDeserialize( + new ByteArrayInputStream(byteArrayOutputStream.toByteArray())); + + StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); + assertThat(actual).isEqualTo(expected); + } + + @Test(expected = IOException.class) + public void testDeserializeValueTypeInteger() throws Exception { + // TODO(songya): test should pass after we add support for type integer + testDeserialize(constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_INTEGER)); + } + + @Test(expected = IOException.class) + public void testDeserializeValueTypeTrue() throws Exception { + // TODO(songya): test should pass after we add support for type boolean + testDeserialize(constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_TRUE)); + } + + @Test(expected = IOException.class) + public void testDeserializeValueTypeFalse() throws Exception { + // TODO(songya): test should pass after we add support for type boolean + testDeserialize(constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_FALSE)); + } + + @Test(expected = IOException.class) + public void testDeserializeMultipleValueType() throws Exception { + // TODO(songya): test should pass after we add support for type integer and boolean + testDeserialize(constructMultiTypeTagInputStream()); + } + + @Test(expected = IOException.class) + public void testDeserializeWrongFormat() throws Exception { + // encoded tags should follow the format ()* + testDeserialize(new ByteArrayInputStream(new byte[3])); + } + + @Test(expected = IOException.class) + public void testDeserializeWrongVersionId() throws Exception { + testDeserialize(new ByteArrayInputStream(new byte[]{(byte) (StatsSerializer.VERSION_ID + 1)})); + } + + @Test + public void testGetDefaultForCurrentStatsContextWhenNotSet() { + assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); + } + + @Test + public void testGetCurrentStatsContext() { + assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); + Context origContext = Context.current().withValue( + CurrentStatsContextUtils.STATS_CONTEXT_KEY, statsContext) + .attach(); + // Make sure context is detached even if test fails. + try { + assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); + } finally { + Context.current().detach(origContext); + } + assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); + } + + @Test(expected = NullPointerException.class) + public void testWithNullStatsContext() { + factory.withStatsContext(null); + } + + @Test + public void testWithStatsContext() { + assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); + Scope scopedStatsCtx = factory.withStatsContext(statsContext); + try { + assertThat(factory.getCurrentStatsContext()).isEqualTo(statsContext); + } finally { + scopedStatsCtx.close(); + } + assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); + } + + @Test + public void testWithStatsContextUsingWrap() { + Runnable runnable; + Scope scopedStatsCtx = factory.withStatsContext(statsContext); + try { + assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); + runnable = Context.current().wrap( + new Runnable() { + @Override + public void run() { + assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); + } + }); + } finally { + scopedStatsCtx.close(); + } + assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); + // When we run the runnable we will have the statsContext in the current Context. + runnable.run(); + } + + private StatsContext testDeserialize(InputStream inputStream) + throws IOException { + return factory.deserialize(inputStream); + } + + /* + * Construct an InputStream with the given type of tag. + * The input format is: + * , and == ()* + * TODO(songya): after supporting serialize integer and boolean, + * remove this method and use StatsContext.serialize() instead. + * Currently StatsContext.serialize() can only serialize strings. + */ + private static InputStream constructSingleTypeTagInputStream(int valueType) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byteArrayOutputStream.write(StatsSerializer.VERSION_ID); + encodeSingleTypeTagToOutputStream(valueType, byteArrayOutputStream); + return new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); + } + + // Construct an InputStream with all 4 types of tags. + private static InputStream constructMultiTypeTagInputStream() throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byteArrayOutputStream.write(StatsSerializer.VERSION_ID); + encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_STRING, byteArrayOutputStream); + encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_INTEGER, byteArrayOutputStream); + encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_TRUE, byteArrayOutputStream); + encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_FALSE, byteArrayOutputStream); + return new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); + } + + private static void encodeSingleTypeTagToOutputStream( + int valueType, ByteArrayOutputStream byteArrayOutputStream) throws IOException { + byteArrayOutputStream.write(valueType); + + // encode , tag key is a string "KEY" appended by the field id here. + encodeString(KEY + valueType, byteArrayOutputStream); + switch (valueType) { + case StatsSerializer.VALUE_TYPE_STRING: + // String encoded format: . + encodeString(VALUE_STRING, byteArrayOutputStream); + break; + case StatsSerializer.VALUE_TYPE_INTEGER: + // Integer encoded format: . + encodeInteger(VALUE_INT, byteArrayOutputStream); + break; + case StatsSerializer.VALUE_TYPE_TRUE: + case StatsSerializer.VALUE_TYPE_FALSE: + // Boolean encoded format: . No tag_value is needed + break; + default: + return; + } + } + + // (tag_field_id == 0) == + // + // == varint encoded integer + // == tag_key_len bytes comprising tag key name + // == varint encoded integer + // == tag_val_len bytes comprising UTF-8 string + private static void encodeString(String input, ByteArrayOutputStream byteArrayOutputStream) + throws IOException { + VarInt.putVarInt(input.length(), byteArrayOutputStream); + byteArrayOutputStream.write(input.getBytes("UTF-8")); + } + + // (tag_field_id == 1) == + // + // == varint encoded integer + // == tag_key_len bytes comprising tag key name + // == 8 bytes, little-endian integer + private static void encodeInteger(int input, ByteArrayOutputStream byteArrayOutputStream) { + byteArrayOutputStream.write((byte) input); + } +} diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java new file mode 100644 index 0000000000..9d27221d18 --- /dev/null +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java @@ -0,0 +1,254 @@ +/* + * Copyright 2016, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Collections2; +import com.google.common.testing.EqualsTester; +import io.opencensus.internal.SimpleEventQueue; +import io.opencensus.internal.VarInt; +import io.opencensus.stats.Measure.MeasureLong; +import io.opencensus.testing.common.TestClock; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link StatsContext}. */ +@RunWith(JUnit4.class) +public class TagContextSerializationTest { + + @Rule + public final ExpectedException thrown = ExpectedException.none(); + + private static final double TOLERANCE = 1e-6; + + private final StatsComponentImplBase statsComponent = + new StatsComponentImplBase(new SimpleEventQueue(), TestClock.create()); + private final ViewManager viewManager = statsComponent.getViewManager(); + private final StatsContextFactory factory = statsComponent.getStatsContextFactory(); + private final StatsContext defaultStatsContext = factory.getDefault(); + + private static final int VERSION_ID = 0; + private static final int VALUE_TYPE_STRING = 0; + + private static final TagKey K_EMPTY = TagKey.create(""); + private static final TagKey K1 = TagKey.create("k1"); + private static final TagKey K2 = TagKey.create("k2"); + private static final TagKey K3 = TagKey.create("k3"); + private static final TagKey K4 = TagKey.create("k4"); + private static final TagKey K10 = TagKey.create("k10"); + + private static final TagValue V_EMPTY = TagValue.create(""); + private static final TagValue V1 = TagValue.create("v1"); + private static final TagValue V2 = TagValue.create("v2"); + private static final TagValue V3 = TagValue.create("v3"); + private static final TagValue V4 = TagValue.create("v4"); + private static final TagValue V10 = TagValue.create("v10"); + private static final TagValue V20 = TagValue.create("v20"); + private static final TagValue V30 = TagValue.create("v30"); + private static final TagValue V100 = TagValue.create("v100"); + + private static final Tag T1 = Tag.create(K1, V1); + private static final Tag T2 = Tag.create(K2, V2); + private static final Tag T3 = Tag.create(K3, V3); + private static final Tag T4 = Tag.create(K4, V4); + + private static final List AGGREGATIONS_NO_HISTOGRAM = Arrays.asList( + Aggregation.Sum.create(), Aggregation.Count.create(), Aggregation.Range.create(), + Aggregation.Mean.create(), Aggregation.StdDev.create()); + + private static final View.Window.Cumulative CUMULATIVE = View.Window.Cumulative.create(); + + @Test + public void testWith() { + assertThat(defaultStatsContext.builder().set(K1, V1).build()) + .isEqualTo(defaultStatsContext.with(K1, V1)); + + assertThat(defaultStatsContext.builder().set(K1, V1).set(K2, V2).build()) + .isEqualTo(defaultStatsContext.with(K1, V1, K2, V2)); + + assertThat(defaultStatsContext.builder().set(K1, V1).set(K2, V2).set(K3, V3).build()) + .isEqualTo(defaultStatsContext.with(K1, V1, K2, V2, K3, V3)); + } + + @Test + public void testWithComposed() { + StatsContext context1 = defaultStatsContext.with(K1, V1); + assertThat(defaultStatsContext.builder().set(K1, V1).build()).isEqualTo(context1); + + StatsContext context2 = context1.with(K1, V10, K2, V2); + assertThat(defaultStatsContext.with(K1, V10, K2, V2)).isEqualTo(context2); + + StatsContext context3 = context2.with(K1, V100, K2, V20, K3, V3); + assertThat(defaultStatsContext.with(K1, V100, K2, V20, K3, V3)).isEqualTo(context3); + + StatsContext context4 = context3.with(K3, V30, K4, V4); + assertThat( + defaultStatsContext + .builder() + .set(K1, V100) + .set(K2, V20) + .set(K3, V30) + .set(K4, V4) + .build()) + .isEqualTo(context4); + } + + // The main tests for stats recording are in ViewManagerImplTest. + @Test + public void testRecordDouble() { + viewManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + ViewData beforeViewData = + viewManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + assertThat(beforeViewData.getAggregationMap()).isEmpty(); + StatsContext context = + defaultStatsContext.with( + RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); + MeasureMap measurements = + MeasureMap.builder() + .set(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); + context.record(measurements); + ViewData afterViewData = + viewManager.getView( + RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + assertThat(afterViewData.getAggregationMap()).hasSize(1); + for (Entry, List> entry : + afterViewData.getAggregationMap().entrySet()) { + assertThat(entry.getKey()).containsExactly(TagValue.create("myMethod")); + assertThat(entry.getValue()).hasSize(3); + StatsTestUtil.assertAggregationDataListEquals( + Arrays.asList( + AggregationData.SumData.create(5.1), + AggregationData.CountData.create(1), + AggregationData.HistogramData.create(0, 0, 0, 0, 0, 0, 1)), + entry.getValue(), + TOLERANCE); + } + } + + @Test + public void testRecordLong() { + MeasureLong measure = MeasureLong.create("long measure", "description", "1"); + viewManager.registerView(View.create( + View.Name.create("name"), "description", measure, AGGREGATIONS_NO_HISTOGRAM, + Arrays.asList(K1), CUMULATIVE)); + MeasureMap measureMap = MeasureMap.builder().set(measure, 1L).build(); + StatsContext context = defaultStatsContext.with(K1, V1); + thrown.expect(UnsupportedOperationException.class); + context.record(measureMap); + } + + @Test + public void testSerializeDefault() throws Exception { + testSerialize(); + } + + @Test + public void testSerializeWithOneStringTag() throws Exception { + testSerialize(T1); + } + + @Test + public void testSerializeWithMultiStringTags() throws Exception { + testSerialize(T1, T2, T3, T4); + } + + @Test + public void testRoundtripSerialization() throws Exception { + testRoundtripSerialization(defaultStatsContext.builder().build()); + testRoundtripSerialization(defaultStatsContext.with(K1, V1)); + testRoundtripSerialization(defaultStatsContext.with(K1, V1, K2, V2, K3, V3)); + testRoundtripSerialization(defaultStatsContext.with(K1, V_EMPTY)); + testRoundtripSerialization(defaultStatsContext.with(K_EMPTY, V1)); + testRoundtripSerialization(defaultStatsContext.with(K_EMPTY, V_EMPTY)); + } + + private void testRoundtripSerialization(StatsContext expected) throws Exception { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + expected.serialize(output); + ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); + StatsContext actual = factory.deserialize(input); + assertThat(actual).isEqualTo(expected); + } + + // Tests for Object overrides. + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup(defaultStatsContext, defaultStatsContext) + .addEqualityGroup(defaultStatsContext.with(K1, V1), defaultStatsContext.with(K1, V1)) + .addEqualityGroup( + defaultStatsContext.with(K1, V1, K2, V2), + defaultStatsContext.with(K1, V1, K2, V2), + defaultStatsContext.with(K2, V2, K1, V1)) + .addEqualityGroup(defaultStatsContext.with(K10, V1)) + .addEqualityGroup(defaultStatsContext.with(K1, V10)) + .addEqualityGroup("foo") + .testEquals(); + } + + @Test + public void testToString() { + assertThat(defaultStatsContext.with(K1, V1).toString()) + .isEqualTo(defaultStatsContext.with(K1, V1).toString()); + assertThat(defaultStatsContext.with(K10, V1).toString()) + .isNotEqualTo(defaultStatsContext.with(K1, V1).toString()); + assertThat(defaultStatsContext.with(K1, V10).toString()) + .isNotEqualTo(defaultStatsContext.with(K1, V1).toString()); + } + + private void testSerialize(Tag... tags) throws IOException { + StatsContext.Builder builder = defaultStatsContext.builder(); + for (Tag tag : tags) { + builder.set(tag.getKey(), tag.getValue()); + } + + ByteArrayOutputStream actual = new ByteArrayOutputStream(); + builder.build().serialize(actual); + + Collection> tagPermutation = Collections2.permutations(Arrays.asList(tags)); + Set possibleOutputs = new HashSet(); + for (List list : tagPermutation) { + ByteArrayOutputStream expected = new ByteArrayOutputStream(); + expected.write(VERSION_ID); + for (Tag tag : list) { + expected.write(VALUE_TYPE_STRING); + encodeString(tag.getKey().asString(), expected); + encodeString(tag.getValue().asString(), expected); + } + possibleOutputs.add(expected.toString()); + } + + assertThat(possibleOutputs).contains(actual.toString()); + } + + private static final void encodeString(String input, ByteArrayOutputStream byteArrayOutputStream) + throws IOException { + VarInt.putVarInt(input.length(), byteArrayOutputStream); + byteArrayOutputStream.write(input.getBytes("UTF-8")); + } +} From 920f53e15dfe8bc2a66871f17a9dc836e5a8c51f Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 11 Aug 2017 16:41:52 -0700 Subject: [PATCH 0407/1581] Run google-java-format on serialization tests. --- .../tags/TagContextDeserializationTest.java | 51 ++++++++++--------- .../tags/TagContextSerializationTest.java | 44 +++++++++------- 2 files changed, 51 insertions(+), 44 deletions(-) diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java index 9accf4a464..d9b473b6cf 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java @@ -29,9 +29,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for {@link StatsContextFactory}. - */ +/** Tests for {@link StatsContextFactory}. */ @RunWith(JUnit4.class) public class TagContextDeserializationTest { @@ -45,8 +43,8 @@ public class TagContextDeserializationTest { private final StatsRecorderImpl statsRecorder = statsComponent.getStatsRecorder(); private final HashMap sampleTags = new HashMap(); private final StatsContext defaultCtx = factory.getDefault(); - private final StatsContext statsContext = factory.getDefault() - .with(TagKey.create(KEY), TagValue.create(VALUE_STRING)); + private final StatsContext statsContext = + factory.getDefault().with(TagKey.create(KEY), TagValue.create(VALUE_STRING)); public TagContextDeserializationTest() { sampleTags.put( @@ -66,9 +64,10 @@ public void testVersionAndValueTypeConstants() { @Test public void testDeserializeNoTags() throws Exception { StatsContext expected = factory.getDefault(); - StatsContext actual = testDeserialize( - new ByteArrayInputStream( - new byte[]{StatsSerializer.VERSION_ID})); // One byte that represents Version ID. + StatsContext actual = + testDeserialize( + new ByteArrayInputStream( + new byte[] {StatsSerializer.VERSION_ID})); // One byte that represents Version ID. assertThat(actual).isEqualTo(expected); } @@ -80,8 +79,8 @@ public void testDeserializeEmptyByteArrayThrowException() throws Exception { @Test public void testDeserializeValueTypeString() throws Exception { StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); - StatsContext actual = testDeserialize( - constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_STRING)); + StatsContext actual = + testDeserialize(constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_STRING)); assertThat(actual).isEqualTo(expected); } @@ -95,8 +94,8 @@ public void testDeserializeMultipleString() throws Exception { byteArrayOutputStream.write(StatsSerializer.VALUE_TYPE_STRING); encodeString("Key2", byteArrayOutputStream); encodeString("String2", byteArrayOutputStream); - StatsContext actual = testDeserialize( - new ByteArrayInputStream(byteArrayOutputStream.toByteArray())); + StatsContext actual = + testDeserialize(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())); StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); assertThat(actual).isEqualTo(expected); @@ -134,7 +133,7 @@ public void testDeserializeWrongFormat() throws Exception { @Test(expected = IOException.class) public void testDeserializeWrongVersionId() throws Exception { - testDeserialize(new ByteArrayInputStream(new byte[]{(byte) (StatsSerializer.VERSION_ID + 1)})); + testDeserialize(new ByteArrayInputStream(new byte[] {(byte) (StatsSerializer.VERSION_ID + 1)})); } @Test @@ -145,9 +144,10 @@ public void testGetDefaultForCurrentStatsContextWhenNotSet() { @Test public void testGetCurrentStatsContext() { assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - Context origContext = Context.current().withValue( - CurrentStatsContextUtils.STATS_CONTEXT_KEY, statsContext) - .attach(); + Context origContext = + Context.current() + .withValue(CurrentStatsContextUtils.STATS_CONTEXT_KEY, statsContext) + .attach(); // Make sure context is detached even if test fails. try { assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); @@ -180,13 +180,15 @@ public void testWithStatsContextUsingWrap() { Scope scopedStatsCtx = factory.withStatsContext(statsContext); try { assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); - runnable = Context.current().wrap( - new Runnable() { - @Override - public void run() { - assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); - } - }); + runnable = + Context.current() + .wrap( + new Runnable() { + @Override + public void run() { + assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); + } + }); } finally { scopedStatsCtx.close(); } @@ -195,8 +197,7 @@ public void run() { runnable.run(); } - private StatsContext testDeserialize(InputStream inputStream) - throws IOException { + private StatsContext testDeserialize(InputStream inputStream) throws IOException { return factory.deserialize(inputStream); } diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java index 9d27221d18..664076b6c2 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java @@ -40,8 +40,7 @@ @RunWith(JUnit4.class) public class TagContextSerializationTest { - @Rule - public final ExpectedException thrown = ExpectedException.none(); + @Rule public final ExpectedException thrown = ExpectedException.none(); private static final double TOLERANCE = 1e-6; @@ -76,9 +75,13 @@ public class TagContextSerializationTest { private static final Tag T3 = Tag.create(K3, V3); private static final Tag T4 = Tag.create(K4, V4); - private static final List AGGREGATIONS_NO_HISTOGRAM = Arrays.asList( - Aggregation.Sum.create(), Aggregation.Count.create(), Aggregation.Range.create(), - Aggregation.Mean.create(), Aggregation.StdDev.create()); + private static final List AGGREGATIONS_NO_HISTOGRAM = + Arrays.asList( + Aggregation.Sum.create(), + Aggregation.Count.create(), + Aggregation.Range.create(), + Aggregation.Mean.create(), + Aggregation.StdDev.create()); private static final View.Window.Cumulative CUMULATIVE = View.Window.Cumulative.create(); @@ -107,13 +110,13 @@ public void testWithComposed() { StatsContext context4 = context3.with(K3, V30, K4, V4); assertThat( - defaultStatsContext - .builder() - .set(K1, V100) - .set(K2, V20) - .set(K3, V30) - .set(K4, V4) - .build()) + defaultStatsContext + .builder() + .set(K1, V100) + .set(K2, V20) + .set(K3, V30) + .set(K4, V4) + .build()) .isEqualTo(context4); } @@ -128,12 +131,10 @@ public void testRecordDouble() { defaultStatsContext.with( RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); MeasureMap measurements = - MeasureMap.builder() - .set(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); + MeasureMap.builder().set(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); context.record(measurements); ViewData afterViewData = - viewManager.getView( - RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); + viewManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); assertThat(afterViewData.getAggregationMap()).hasSize(1); for (Entry, List> entry : afterViewData.getAggregationMap().entrySet()) { @@ -152,9 +153,14 @@ public void testRecordDouble() { @Test public void testRecordLong() { MeasureLong measure = MeasureLong.create("long measure", "description", "1"); - viewManager.registerView(View.create( - View.Name.create("name"), "description", measure, AGGREGATIONS_NO_HISTOGRAM, - Arrays.asList(K1), CUMULATIVE)); + viewManager.registerView( + View.create( + View.Name.create("name"), + "description", + measure, + AGGREGATIONS_NO_HISTOGRAM, + Arrays.asList(K1), + CUMULATIVE)); MeasureMap measureMap = MeasureMap.builder().set(measure, 1L).build(); StatsContext context = defaultStatsContext.with(K1, V1); thrown.expect(UnsupportedOperationException.class); From 32fafe9426215151e1fb7d70d90d4e2d2e8fd5d0 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Fri, 11 Aug 2017 16:06:58 -0700 Subject: [PATCH 0408/1581] Add TagContext serialization. This commit adds a class for serializing and deserializing TagContexts, TagContextSerializer, to the TagsComponent. TagContext serialization is very similar to the existing StatsContext serialization, and it currently only supports String tag values. --- .../java/io/opencensus/tags/TagContext.java | 1 + .../opencensus/tags/TagContextSerializer.java | 65 ++++++ .../main/java/io/opencensus/tags/TagKey.java | 1 + .../io/opencensus/tags/TagValueString.java | 1 + .../main/java/io/opencensus/tags/Tags.java | 9 + .../io/opencensus/tags/TagsComponent.java | 8 + .../java/io/opencensus/tags/TagsTest.java | 6 + .../impl/tags/SerializationUtils.java | 79 +++++-- .../impl/tags/TagContextSerializerImpl.java | 34 +++ .../impl/tags/TagsComponentImplBase.java | 7 + .../tags/TagContextDeserializationTest.java | 187 ++++++--------- .../impl/tags/TagContextRoundtripTest.java | 65 ++++++ .../tags/TagContextSerializationTest.java | 214 +++--------------- .../io/opencensus/impl/tags/TagsTest.java | 6 + .../io/opencensus/impl/tags/TagsTest.java | 6 + 15 files changed, 367 insertions(+), 322 deletions(-) create mode 100644 core/src/main/java/io/opencensus/tags/TagContextSerializer.java create mode 100644 core_impl/src/main/java/io/opencensus/impl/tags/TagContextSerializerImpl.java create mode 100644 core_impl/src/test/java/io/opencensus/impl/tags/TagContextRoundtripTest.java diff --git a/core/src/main/java/io/opencensus/tags/TagContext.java b/core/src/main/java/io/opencensus/tags/TagContext.java index a2f3867a81..21d92b6332 100644 --- a/core/src/main/java/io/opencensus/tags/TagContext.java +++ b/core/src/main/java/io/opencensus/tags/TagContext.java @@ -27,6 +27,7 @@ *

Keys have type {@link TagKey}. Values have type {@link TagValueString}, though the library * will support more types in the future, including {@code long} and {@code boolean}. */ +// TODO(sebright): Implement equals and hashCode. @Immutable public abstract class TagContext { private static final TagContext NOOP_TAG_CONTEXT = new NoopTagContext(); diff --git a/core/src/main/java/io/opencensus/tags/TagContextSerializer.java b/core/src/main/java/io/opencensus/tags/TagContextSerializer.java new file mode 100644 index 0000000000..ced91881df --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/TagContextSerializer.java @@ -0,0 +1,65 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import javax.annotation.concurrent.Immutable; + +/** Object for serializing and deserializing {@link TagContext}s. */ +public abstract class TagContextSerializer { + private static final TagContextSerializer NOOP_TAG_CONTEXT_SERIALIZER = + new NoopTagContextSerializer(); + + /** + * Serializes the {@code TagContext} into the on-the-wire representation. + * + *

This method should be the inverse of {@link #deserialize}. + * + * @param tags the {@code TagContext} to serialize. + * @param output the {@link OutputStream} to write the serialized tags to. + */ + public abstract void serialize(TagContext tags, OutputStream output) throws IOException; + + /** + * Creates a {@code TagContext} from the given on-the-wire encoded representation. + * + *

This method should be the inverse of {@link #serialize}. + * + * @param input on-the-wire representation of a {@code TagContext}. + * @return a {@code TagContext} deserialized from {@code input}. + */ + public abstract TagContext deserialize(InputStream input) throws IOException; + + /** + * Returns a {@code TagContextSerializer} that serializes all {@code TagContext}s to zero bytes + * and deserializes all inputs to empty {@code TagContext}s. + */ + static TagContextSerializer getNoopTagContextSerializer() { + return NOOP_TAG_CONTEXT_SERIALIZER; + } + + @Immutable + private static final class NoopTagContextSerializer extends TagContextSerializer { + + @Override + public void serialize(TagContext tags, OutputStream output) throws IOException {} + + @Override + public TagContext deserialize(InputStream input) throws IOException { + return TagContext.getNoopTagContext(); + } + } +} diff --git a/core/src/main/java/io/opencensus/tags/TagKey.java b/core/src/main/java/io/opencensus/tags/TagKey.java index aadfcc85d2..12f22fc8f9 100644 --- a/core/src/main/java/io/opencensus/tags/TagKey.java +++ b/core/src/main/java/io/opencensus/tags/TagKey.java @@ -143,6 +143,7 @@ public abstract static class TagKeyString extends TagKey { * @throws IllegalArgumentException if the name is not valid. */ public static TagKeyString create(String name) { + // TODO(sebright): Should we disallow an empty name? checkArgument(isValid(name)); return new AutoValue_TagKey_TagKeyString(name); } diff --git a/core/src/main/java/io/opencensus/tags/TagValueString.java b/core/src/main/java/io/opencensus/tags/TagValueString.java index 316755866f..741daebc4a 100644 --- a/core/src/main/java/io/opencensus/tags/TagValueString.java +++ b/core/src/main/java/io/opencensus/tags/TagValueString.java @@ -46,6 +46,7 @@ public abstract class TagValueString { * @throws IllegalArgumentException if the {@code String} is not valid. */ public static TagValueString create(String value) { + // TODO(sebright): Should we disallow empty? Preconditions.checkArgument(isValid(value)); return new AutoValue_TagValueString(value); } diff --git a/core/src/main/java/io/opencensus/tags/Tags.java b/core/src/main/java/io/opencensus/tags/Tags.java index 4f68c1fd2e..86e06af9a7 100644 --- a/core/src/main/java/io/opencensus/tags/Tags.java +++ b/core/src/main/java/io/opencensus/tags/Tags.java @@ -36,6 +36,15 @@ public static TagContexts getTagContexts() { return tagsComponent.getTagContexts(); } + /** + * Returns the default {@code TagContextSerializer}. + * + * @return the default {@code TagContextSerializer}. + */ + public static TagContextSerializer getTagContextSerializer() { + return tagsComponent.getTagContextSerializer(); + } + // Any provider that may be used for TagsComponent can be added here. @VisibleForTesting static TagsComponent loadTagsComponent(ClassLoader classLoader) { diff --git a/core/src/main/java/io/opencensus/tags/TagsComponent.java b/core/src/main/java/io/opencensus/tags/TagsComponent.java index 0629f916e9..ff9e4b6e53 100644 --- a/core/src/main/java/io/opencensus/tags/TagsComponent.java +++ b/core/src/main/java/io/opencensus/tags/TagsComponent.java @@ -26,6 +26,9 @@ public abstract class TagsComponent { /** Returns the {@link TagContexts} for this implementation. */ public abstract TagContexts getTagContexts(); + /** Returns the {@link TagContextSerializer} for this implementation. */ + public abstract TagContextSerializer getTagContextSerializer(); + /** * Returns a {@code TagsComponent} that has a no-op implementation for the {@link TagContexts}. * @@ -42,5 +45,10 @@ private static final class NoopTagsComponent extends TagsComponent { public TagContexts getTagContexts() { return TagContexts.getNoopTagContexts(); } + + @Override + public TagContextSerializer getTagContextSerializer() { + return TagContextSerializer.getNoopTagContextSerializer(); + } } } diff --git a/core/src/test/java/io/opencensus/tags/TagsTest.java b/core/src/test/java/io/opencensus/tags/TagsTest.java index 1a66253896..fd54f38735 100644 --- a/core/src/test/java/io/opencensus/tags/TagsTest.java +++ b/core/src/test/java/io/opencensus/tags/TagsTest.java @@ -57,4 +57,10 @@ public Class loadClass(String name) throws ClassNotFoundException { public void defaultTagContexts() { assertThat(Tags.getTagContexts()).isEqualTo(TagContexts.getNoopTagContexts()); } + + @Test + public void defaultTagContextSerializer() { + assertThat(Tags.getTagContextSerializer()) + .isEqualTo(TagContextSerializer.getNoopTagContextSerializer()); + } } diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java b/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java index 94b783a056..a8417879c9 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java @@ -15,7 +15,17 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.io.ByteStreams; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; import io.opencensus.internal.VarInt; +import io.opencensus.tags.Tag; +import io.opencensus.tags.Tag.TagBoolean; +import io.opencensus.tags.Tag.TagLong; +import io.opencensus.tags.Tag.TagString; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -23,13 +33,12 @@ import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.util.HashMap; -import java.util.Map.Entry; -import java.util.Set; +import java.util.Iterator; /** - * Native implementation {@link StatsContext} serialization. + * {@link TagContext} serialization. * - *

Encoding of stats context information (tags) for passing across RPC's: + *

Encoding of tag context information for passing across RPC's: * *

    *
  • Tags are encoded in single byte sequence. The version 0 format is: @@ -64,6 +73,7 @@ *
*/ final class SerializationUtils { + private SerializationUtils() {} // TODO(songya): Currently we only support encoding on string type. @VisibleForTesting static final int VERSION_ID = 0; @@ -72,27 +82,56 @@ final class SerializationUtils { @VisibleForTesting static final int VALUE_TYPE_TRUE = 2; @VisibleForTesting static final int VALUE_TYPE_FALSE = 3; - // Serializes a StatsContext to the on-the-wire format. + // Serializes a TagContext to the on-the-wire format. // Encoded tags are of the form: - static void serialize(StatsContextImpl context, OutputStream output) throws IOException { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + static void serialize(TagContext tags, OutputStream output) throws IOException { + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byteArrayOutputStream.write(VERSION_ID); // TODO(songya): add support for value types integer and boolean - Set> tags = context.tags.entrySet(); - for (Entry tag : tags) { - encodeStringTag(tag.getKey(), tag.getValue(), byteArrayOutputStream); + for (Iterator i = tags.unsafeGetIterator(); i.hasNext(); ) { + Tag tag = i.next(); + + // TODO(sebright): Is there a better way to handle checked exceptions in function objects? + IOException ex = + tag.match( + new Function() { + @Override + public IOException apply(TagString arg) { + try { + encodeStringTag(arg, byteArrayOutputStream); + return null; + } catch (IOException e) { + return e; + } + } + }, + new Function() { + @Override + public IOException apply(TagLong arg) { + throw new IllegalArgumentException("long tags are not supported."); + } + }, + new Function() { + @Override + public IOException apply(TagBoolean arg) { + throw new IllegalArgumentException("boolean tags are not supported."); + } + }, + Functions.throwAssertionError()); + if (ex != null) { + throw ex; + } } byteArrayOutputStream.writeTo(output); } - // Deserializes input to StatsContext based on the binary format standard. + // Deserializes input to TagContext based on the binary format standard. // The encoded tags are of the form: - static StatsContextImpl deserialize(StatsRecorderImpl statsRecorder, InputStream input) - throws IOException { + static TagContextImpl deserialize(InputStream input) throws IOException { try { byte[] bytes = ByteStreams.toByteArray(input); - HashMap tags = new HashMap(); + HashMap tags = new HashMap(); if (bytes.length == 0) { // Does not allow empty byte array. throw new IOException("Input byte stream can not be empty."); @@ -110,8 +149,8 @@ static StatsContextImpl deserialize(StatsRecorderImpl statsRecorder, InputStream int type = buffer.get(); switch (type) { case VALUE_TYPE_STRING: - TagKey key = TagKey.create(decodeString(buffer)); - TagValue val = TagValue.create(decodeString(buffer)); + TagKeyString key = TagKeyString.create(decodeString(buffer)); + TagValueString val = TagValueString.create(decodeString(buffer)); tags.put(key, val); break; case VALUE_TYPE_INTEGER: @@ -122,7 +161,7 @@ static StatsContextImpl deserialize(StatsRecorderImpl statsRecorder, InputStream throw new IOException("Unsupported tag value type."); } } - return new StatsContextImpl(statsRecorder, tags); + return new TagContextImpl(tags); } catch (BufferUnderflowException exn) { throw new IOException(exn.toString()); // byte array format error. } @@ -130,10 +169,10 @@ static StatsContextImpl deserialize(StatsRecorderImpl statsRecorder, InputStream // TODO(songya): Currently we only support encoding on string type. private static final void encodeStringTag( - TagKey key, TagValue value, ByteArrayOutputStream byteArrayOutputStream) throws IOException { + TagString tag, ByteArrayOutputStream byteArrayOutputStream) throws IOException { byteArrayOutputStream.write(VALUE_TYPE_STRING); - encodeString(key.asString(), byteArrayOutputStream); - encodeString(value.asString(), byteArrayOutputStream); + encodeString(tag.getKey().getName(), byteArrayOutputStream); + encodeString(tag.getValue().asString(), byteArrayOutputStream); } private static final void encodeString(String input, ByteArrayOutputStream byteArrayOutputStream) diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextSerializerImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextSerializerImpl.java new file mode 100644 index 0000000000..7b2cefa202 --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextSerializerImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.tags; + +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContextSerializer; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +final class TagContextSerializerImpl extends TagContextSerializer { + TagContextSerializerImpl() {} + + @Override + public void serialize(TagContext tags, OutputStream output) throws IOException { + SerializationUtils.serialize(tags, output); + } + + @Override + public TagContext deserialize(InputStream input) throws IOException { + return SerializationUtils.deserialize(input); + } +} diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java index 9fed97e85b..c1b41fc69c 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java @@ -13,15 +13,22 @@ package io.opencensus.impl.tags; +import io.opencensus.tags.TagContextSerializer; import io.opencensus.tags.TagContexts; import io.opencensus.tags.TagsComponent; /** Base implementation of {@link TagsComponent}. */ public abstract class TagsComponentImplBase extends TagsComponent { private final TagContexts tagContexts = new TagContextsImpl(); + private final TagContextSerializer tagContextSerializer = new TagContextSerializerImpl(); @Override public TagContexts getTagContexts() { return tagContexts; } + + @Override + public TagContextSerializer getTagContextSerializer() { + return tagContextSerializer; + } } diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java index d9b473b6cf..4495ec1c57 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java @@ -15,21 +15,24 @@ import static com.google.common.truth.Truth.assertThat; -import io.grpc.Context; -import io.opencensus.common.Scope; -import io.opencensus.internal.SimpleEventQueue; +import com.google.common.collect.Lists; import io.opencensus.internal.VarInt; -import io.opencensus.testing.common.TestClock; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContexts; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link StatsContextFactory}. */ +/** + * Tests for deserializing tags with {@link SerializationUtils} and {@link + * TagContextSerializerImpl}. + */ @RunWith(JUnit4.class) public class TagContextDeserializationTest { @@ -37,38 +40,29 @@ public class TagContextDeserializationTest { private static final String VALUE_STRING = "String"; private static final int VALUE_INT = 10; - private final StatsComponentImplBase statsComponent = - new StatsComponentImplBase(new SimpleEventQueue(), TestClock.create()); - private final StatsContextFactory factory = statsComponent.getStatsContextFactory(); - private final StatsRecorderImpl statsRecorder = statsComponent.getStatsRecorder(); - private final HashMap sampleTags = new HashMap(); - private final StatsContext defaultCtx = factory.getDefault(); - private final StatsContext statsContext = - factory.getDefault().with(TagKey.create(KEY), TagValue.create(VALUE_STRING)); - - public TagContextDeserializationTest() { - sampleTags.put( - TagKey.create(KEY + StatsSerializer.VALUE_TYPE_STRING), TagValue.create(VALUE_STRING)); - } + private final TagContextSerializerImpl serializer = new TagContextSerializerImpl(); + private final TagContexts tagContexts = new TagContextsImpl(); @Test public void testVersionAndValueTypeConstants() { - // Refer to the JavaDoc on StatsSerializer for the definitions on these constants. - assertThat(StatsSerializer.VERSION_ID).isEqualTo(0); - assertThat(StatsSerializer.VALUE_TYPE_STRING).isEqualTo(0); - assertThat(StatsSerializer.VALUE_TYPE_INTEGER).isEqualTo(1); - assertThat(StatsSerializer.VALUE_TYPE_TRUE).isEqualTo(2); - assertThat(StatsSerializer.VALUE_TYPE_FALSE).isEqualTo(3); + // Refer to the JavaDoc on SerializationUtils for the definitions on these constants. + assertThat(SerializationUtils.VERSION_ID).isEqualTo(0); + assertThat(SerializationUtils.VALUE_TYPE_STRING).isEqualTo(0); + assertThat(SerializationUtils.VALUE_TYPE_INTEGER).isEqualTo(1); + assertThat(SerializationUtils.VALUE_TYPE_TRUE).isEqualTo(2); + assertThat(SerializationUtils.VALUE_TYPE_FALSE).isEqualTo(3); } @Test public void testDeserializeNoTags() throws Exception { - StatsContext expected = factory.getDefault(); - StatsContext actual = + TagContext expected = tagContexts.empty(); + TagContext actual = testDeserialize( new ByteArrayInputStream( - new byte[] {StatsSerializer.VERSION_ID})); // One byte that represents Version ID. - assertThat(actual).isEqualTo(expected); + new byte[] { + SerializationUtils.VERSION_ID + })); // One byte that represents Version ID. + assertTagContextsEqual(actual, expected); } @Test(expected = IOException.class) @@ -78,45 +72,55 @@ public void testDeserializeEmptyByteArrayThrowException() throws Exception { @Test public void testDeserializeValueTypeString() throws Exception { - StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); - StatsContext actual = - testDeserialize(constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_STRING)); - assertThat(actual).isEqualTo(expected); + TagContext actual = + testDeserialize(constructSingleTypeTagInputStream(SerializationUtils.VALUE_TYPE_STRING)); + TagContext expected = + tagContexts + .emptyBuilder() + .set( + TagKeyString.create(KEY + SerializationUtils.VALUE_TYPE_STRING), + TagValueString.create(VALUE_STRING)) + .build(); + assertTagContextsEqual(actual, expected); } @Test public void testDeserializeMultipleString() throws Exception { - sampleTags.put(TagKey.create("Key2"), TagValue.create("String2")); - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - byteArrayOutputStream.write(StatsSerializer.VERSION_ID); - encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_STRING, byteArrayOutputStream); - byteArrayOutputStream.write(StatsSerializer.VALUE_TYPE_STRING); + byteArrayOutputStream.write(SerializationUtils.VERSION_ID); + encodeSingleTypeTagToOutputStream(SerializationUtils.VALUE_TYPE_STRING, byteArrayOutputStream); + byteArrayOutputStream.write(SerializationUtils.VALUE_TYPE_STRING); encodeString("Key2", byteArrayOutputStream); encodeString("String2", byteArrayOutputStream); - StatsContext actual = + TagContext actual = testDeserialize(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())); - - StatsContext expected = new StatsContextImpl(statsRecorder, sampleTags); - assertThat(actual).isEqualTo(expected); + TagContext expected = + tagContexts + .emptyBuilder() + .set( + TagKeyString.create(KEY + SerializationUtils.VALUE_TYPE_STRING), + TagValueString.create(VALUE_STRING)) + .set(TagKeyString.create("Key2"), TagValueString.create("String2")) + .build(); + assertTagContextsEqual(actual, expected); } @Test(expected = IOException.class) public void testDeserializeValueTypeInteger() throws Exception { // TODO(songya): test should pass after we add support for type integer - testDeserialize(constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_INTEGER)); + testDeserialize(constructSingleTypeTagInputStream(SerializationUtils.VALUE_TYPE_INTEGER)); } @Test(expected = IOException.class) public void testDeserializeValueTypeTrue() throws Exception { // TODO(songya): test should pass after we add support for type boolean - testDeserialize(constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_TRUE)); + testDeserialize(constructSingleTypeTagInputStream(SerializationUtils.VALUE_TYPE_TRUE)); } @Test(expected = IOException.class) public void testDeserializeValueTypeFalse() throws Exception { // TODO(songya): test should pass after we add support for type boolean - testDeserialize(constructSingleTypeTagInputStream(StatsSerializer.VALUE_TYPE_FALSE)); + testDeserialize(constructSingleTypeTagInputStream(SerializationUtils.VALUE_TYPE_FALSE)); } @Test(expected = IOException.class) @@ -133,72 +137,12 @@ public void testDeserializeWrongFormat() throws Exception { @Test(expected = IOException.class) public void testDeserializeWrongVersionId() throws Exception { - testDeserialize(new ByteArrayInputStream(new byte[] {(byte) (StatsSerializer.VERSION_ID + 1)})); - } - - @Test - public void testGetDefaultForCurrentStatsContextWhenNotSet() { - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - } - - @Test - public void testGetCurrentStatsContext() { - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - Context origContext = - Context.current() - .withValue(CurrentStatsContextUtils.STATS_CONTEXT_KEY, statsContext) - .attach(); - // Make sure context is detached even if test fails. - try { - assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); - } finally { - Context.current().detach(origContext); - } - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); + testDeserialize( + new ByteArrayInputStream(new byte[] {(byte) (SerializationUtils.VERSION_ID + 1)})); } - @Test(expected = NullPointerException.class) - public void testWithNullStatsContext() { - factory.withStatsContext(null); - } - - @Test - public void testWithStatsContext() { - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - Scope scopedStatsCtx = factory.withStatsContext(statsContext); - try { - assertThat(factory.getCurrentStatsContext()).isEqualTo(statsContext); - } finally { - scopedStatsCtx.close(); - } - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - } - - @Test - public void testWithStatsContextUsingWrap() { - Runnable runnable; - Scope scopedStatsCtx = factory.withStatsContext(statsContext); - try { - assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); - runnable = - Context.current() - .wrap( - new Runnable() { - @Override - public void run() { - assertThat(factory.getCurrentStatsContext()).isSameAs(statsContext); - } - }); - } finally { - scopedStatsCtx.close(); - } - assertThat(factory.getCurrentStatsContext()).isEqualTo(defaultCtx); - // When we run the runnable we will have the statsContext in the current Context. - runnable.run(); - } - - private StatsContext testDeserialize(InputStream inputStream) throws IOException { - return factory.deserialize(inputStream); + private TagContext testDeserialize(InputStream inputStream) throws IOException { + return serializer.deserialize(inputStream); } /* @@ -211,7 +155,7 @@ private StatsContext testDeserialize(InputStream inputStream) throws IOException */ private static InputStream constructSingleTypeTagInputStream(int valueType) throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - byteArrayOutputStream.write(StatsSerializer.VERSION_ID); + byteArrayOutputStream.write(SerializationUtils.VERSION_ID); encodeSingleTypeTagToOutputStream(valueType, byteArrayOutputStream); return new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); } @@ -219,11 +163,11 @@ private static InputStream constructSingleTypeTagInputStream(int valueType) thro // Construct an InputStream with all 4 types of tags. private static InputStream constructMultiTypeTagInputStream() throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - byteArrayOutputStream.write(StatsSerializer.VERSION_ID); - encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_STRING, byteArrayOutputStream); - encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_INTEGER, byteArrayOutputStream); - encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_TRUE, byteArrayOutputStream); - encodeSingleTypeTagToOutputStream(StatsSerializer.VALUE_TYPE_FALSE, byteArrayOutputStream); + byteArrayOutputStream.write(SerializationUtils.VERSION_ID); + encodeSingleTypeTagToOutputStream(SerializationUtils.VALUE_TYPE_STRING, byteArrayOutputStream); + encodeSingleTypeTagToOutputStream(SerializationUtils.VALUE_TYPE_INTEGER, byteArrayOutputStream); + encodeSingleTypeTagToOutputStream(SerializationUtils.VALUE_TYPE_TRUE, byteArrayOutputStream); + encodeSingleTypeTagToOutputStream(SerializationUtils.VALUE_TYPE_FALSE, byteArrayOutputStream); return new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); } @@ -234,16 +178,16 @@ private static void encodeSingleTypeTagToOutputStream( // encode , tag key is a string "KEY" appended by the field id here. encodeString(KEY + valueType, byteArrayOutputStream); switch (valueType) { - case StatsSerializer.VALUE_TYPE_STRING: + case SerializationUtils.VALUE_TYPE_STRING: // String encoded format: . encodeString(VALUE_STRING, byteArrayOutputStream); break; - case StatsSerializer.VALUE_TYPE_INTEGER: + case SerializationUtils.VALUE_TYPE_INTEGER: // Integer encoded format: . encodeInteger(VALUE_INT, byteArrayOutputStream); break; - case StatsSerializer.VALUE_TYPE_TRUE: - case StatsSerializer.VALUE_TYPE_FALSE: + case SerializationUtils.VALUE_TYPE_TRUE: + case SerializationUtils.VALUE_TYPE_FALSE: // Boolean encoded format: . No tag_value is needed break; default: @@ -271,4 +215,9 @@ private static void encodeString(String input, ByteArrayOutputStream byteArrayOu private static void encodeInteger(int input, ByteArrayOutputStream byteArrayOutputStream) { byteArrayOutputStream.write((byte) input); } + + private static void assertTagContextsEqual(TagContext actual, TagContext expected) { + assertThat(Lists.newArrayList(actual.unsafeGetIterator())) + .containsExactlyElementsIn(Lists.newArrayList(expected.unsafeGetIterator())); + } } diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextRoundtripTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextRoundtripTest.java new file mode 100644 index 0000000000..4cbdc9e224 --- /dev/null +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextRoundtripTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContexts; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for roundtrip serialization with {@link TagContextSerializerImpl}. */ +@RunWith(JUnit4.class) +public class TagContextRoundtripTest { + + private static final TagKeyString K_EMPTY = TagKeyString.create(""); + private static final TagKeyString K1 = TagKeyString.create("k1"); + private static final TagKeyString K2 = TagKeyString.create("k2"); + private static final TagKeyString K3 = TagKeyString.create("k3"); + + private static final TagValueString V_EMPTY = TagValueString.create(""); + private static final TagValueString V1 = TagValueString.create("v1"); + private static final TagValueString V2 = TagValueString.create("v2"); + private static final TagValueString V3 = TagValueString.create("v3"); + + private final TagContextSerializerImpl serializer = new TagContextSerializerImpl(); + private final TagContexts tagContexts = new TagContextsImpl(); + + @Test + public void testRoundtripSerialization() throws Exception { + testRoundtripSerialization(tagContexts.empty()); + testRoundtripSerialization(tagContexts.emptyBuilder().set(K1, V1).build()); + testRoundtripSerialization( + tagContexts.emptyBuilder().set(K1, V1).set(K2, V2).set(K3, V3).build()); + testRoundtripSerialization(tagContexts.emptyBuilder().set(K1, V_EMPTY).build()); + testRoundtripSerialization(tagContexts.emptyBuilder().set(K_EMPTY, V1).build()); + testRoundtripSerialization(tagContexts.emptyBuilder().set(K_EMPTY, V_EMPTY).build()); + } + + private void testRoundtripSerialization(TagContext expected) throws Exception { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + serializer.serialize(expected, output); + ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); + TagContext actual = serializer.deserialize(input); + assertThat(Lists.newArrayList(actual.unsafeGetIterator())) + .containsExactlyElementsIn(Lists.newArrayList(expected.unsafeGetIterator())); + } +} diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java index 664076b6c2..963e16f1e3 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java @@ -16,156 +16,49 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.Collections2; -import com.google.common.testing.EqualsTester; -import io.opencensus.internal.SimpleEventQueue; import io.opencensus.internal.VarInt; -import io.opencensus.stats.Measure.MeasureLong; -import io.opencensus.testing.common.TestClock; -import java.io.ByteArrayInputStream; +import io.opencensus.tags.Tag.TagString; +import io.opencensus.tags.TagContextBuilder; +import io.opencensus.tags.TagContexts; +import io.opencensus.tags.TagKey.TagKeyString; +import io.opencensus.tags.TagValueString; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; -import java.util.Map.Entry; import java.util.Set; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for {@link StatsContext}. */ +/** + * Tests for serializing tags with {@link SerializationUtils} and {@link TagContextSerializerImpl}. + */ @RunWith(JUnit4.class) public class TagContextSerializationTest { - @Rule public final ExpectedException thrown = ExpectedException.none(); - - private static final double TOLERANCE = 1e-6; - - private final StatsComponentImplBase statsComponent = - new StatsComponentImplBase(new SimpleEventQueue(), TestClock.create()); - private final ViewManager viewManager = statsComponent.getViewManager(); - private final StatsContextFactory factory = statsComponent.getStatsContextFactory(); - private final StatsContext defaultStatsContext = factory.getDefault(); - private static final int VERSION_ID = 0; private static final int VALUE_TYPE_STRING = 0; - private static final TagKey K_EMPTY = TagKey.create(""); - private static final TagKey K1 = TagKey.create("k1"); - private static final TagKey K2 = TagKey.create("k2"); - private static final TagKey K3 = TagKey.create("k3"); - private static final TagKey K4 = TagKey.create("k4"); - private static final TagKey K10 = TagKey.create("k10"); - - private static final TagValue V_EMPTY = TagValue.create(""); - private static final TagValue V1 = TagValue.create("v1"); - private static final TagValue V2 = TagValue.create("v2"); - private static final TagValue V3 = TagValue.create("v3"); - private static final TagValue V4 = TagValue.create("v4"); - private static final TagValue V10 = TagValue.create("v10"); - private static final TagValue V20 = TagValue.create("v20"); - private static final TagValue V30 = TagValue.create("v30"); - private static final TagValue V100 = TagValue.create("v100"); - - private static final Tag T1 = Tag.create(K1, V1); - private static final Tag T2 = Tag.create(K2, V2); - private static final Tag T3 = Tag.create(K3, V3); - private static final Tag T4 = Tag.create(K4, V4); - - private static final List AGGREGATIONS_NO_HISTOGRAM = - Arrays.asList( - Aggregation.Sum.create(), - Aggregation.Count.create(), - Aggregation.Range.create(), - Aggregation.Mean.create(), - Aggregation.StdDev.create()); - - private static final View.Window.Cumulative CUMULATIVE = View.Window.Cumulative.create(); - - @Test - public void testWith() { - assertThat(defaultStatsContext.builder().set(K1, V1).build()) - .isEqualTo(defaultStatsContext.with(K1, V1)); - - assertThat(defaultStatsContext.builder().set(K1, V1).set(K2, V2).build()) - .isEqualTo(defaultStatsContext.with(K1, V1, K2, V2)); + private static final TagKeyString K1 = TagKeyString.create("k1"); + private static final TagKeyString K2 = TagKeyString.create("k2"); + private static final TagKeyString K3 = TagKeyString.create("k3"); + private static final TagKeyString K4 = TagKeyString.create("k4"); - assertThat(defaultStatsContext.builder().set(K1, V1).set(K2, V2).set(K3, V3).build()) - .isEqualTo(defaultStatsContext.with(K1, V1, K2, V2, K3, V3)); - } - - @Test - public void testWithComposed() { - StatsContext context1 = defaultStatsContext.with(K1, V1); - assertThat(defaultStatsContext.builder().set(K1, V1).build()).isEqualTo(context1); + private static final TagValueString V1 = TagValueString.create("v1"); + private static final TagValueString V2 = TagValueString.create("v2"); + private static final TagValueString V3 = TagValueString.create("v3"); + private static final TagValueString V4 = TagValueString.create("v4"); - StatsContext context2 = context1.with(K1, V10, K2, V2); - assertThat(defaultStatsContext.with(K1, V10, K2, V2)).isEqualTo(context2); + private static final TagString T1 = TagString.create(K1, V1); + private static final TagString T2 = TagString.create(K2, V2); + private static final TagString T3 = TagString.create(K3, V3); + private static final TagString T4 = TagString.create(K4, V4); - StatsContext context3 = context2.with(K1, V100, K2, V20, K3, V3); - assertThat(defaultStatsContext.with(K1, V100, K2, V20, K3, V3)).isEqualTo(context3); - - StatsContext context4 = context3.with(K3, V30, K4, V4); - assertThat( - defaultStatsContext - .builder() - .set(K1, V100) - .set(K2, V20) - .set(K3, V30) - .set(K4, V4) - .build()) - .isEqualTo(context4); - } - - // The main tests for stats recording are in ViewManagerImplTest. - @Test - public void testRecordDouble() { - viewManager.registerView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - ViewData beforeViewData = - viewManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - assertThat(beforeViewData.getAggregationMap()).isEmpty(); - StatsContext context = - defaultStatsContext.with( - RpcMeasureConstants.RPC_CLIENT_METHOD, TagValue.create("myMethod")); - MeasureMap measurements = - MeasureMap.builder().set(RpcMeasureConstants.RPC_CLIENT_ROUNDTRIP_LATENCY, 5.1).build(); - context.record(measurements); - ViewData afterViewData = - viewManager.getView(RpcViewConstants.RPC_CLIENT_ROUNDTRIP_LATENCY_VIEW); - assertThat(afterViewData.getAggregationMap()).hasSize(1); - for (Entry, List> entry : - afterViewData.getAggregationMap().entrySet()) { - assertThat(entry.getKey()).containsExactly(TagValue.create("myMethod")); - assertThat(entry.getValue()).hasSize(3); - StatsTestUtil.assertAggregationDataListEquals( - Arrays.asList( - AggregationData.SumData.create(5.1), - AggregationData.CountData.create(1), - AggregationData.HistogramData.create(0, 0, 0, 0, 0, 0, 1)), - entry.getValue(), - TOLERANCE); - } - } - - @Test - public void testRecordLong() { - MeasureLong measure = MeasureLong.create("long measure", "description", "1"); - viewManager.registerView( - View.create( - View.Name.create("name"), - "description", - measure, - AGGREGATIONS_NO_HISTOGRAM, - Arrays.asList(K1), - CUMULATIVE)); - MeasureMap measureMap = MeasureMap.builder().set(measure, 1L).build(); - StatsContext context = defaultStatsContext.with(K1, V1); - thrown.expect(UnsupportedOperationException.class); - context.record(measureMap); - } + private final TagContextSerializerImpl serializer = new TagContextSerializerImpl(); + private final TagContexts tagContexts = new TagContextsImpl(); @Test public void testSerializeDefault() throws Exception { @@ -182,68 +75,23 @@ public void testSerializeWithMultiStringTags() throws Exception { testSerialize(T1, T2, T3, T4); } - @Test - public void testRoundtripSerialization() throws Exception { - testRoundtripSerialization(defaultStatsContext.builder().build()); - testRoundtripSerialization(defaultStatsContext.with(K1, V1)); - testRoundtripSerialization(defaultStatsContext.with(K1, V1, K2, V2, K3, V3)); - testRoundtripSerialization(defaultStatsContext.with(K1, V_EMPTY)); - testRoundtripSerialization(defaultStatsContext.with(K_EMPTY, V1)); - testRoundtripSerialization(defaultStatsContext.with(K_EMPTY, V_EMPTY)); - } - - private void testRoundtripSerialization(StatsContext expected) throws Exception { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - expected.serialize(output); - ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); - StatsContext actual = factory.deserialize(input); - assertThat(actual).isEqualTo(expected); - } - - // Tests for Object overrides. - - @Test - public void testEquals() { - new EqualsTester() - .addEqualityGroup(defaultStatsContext, defaultStatsContext) - .addEqualityGroup(defaultStatsContext.with(K1, V1), defaultStatsContext.with(K1, V1)) - .addEqualityGroup( - defaultStatsContext.with(K1, V1, K2, V2), - defaultStatsContext.with(K1, V1, K2, V2), - defaultStatsContext.with(K2, V2, K1, V1)) - .addEqualityGroup(defaultStatsContext.with(K10, V1)) - .addEqualityGroup(defaultStatsContext.with(K1, V10)) - .addEqualityGroup("foo") - .testEquals(); - } - - @Test - public void testToString() { - assertThat(defaultStatsContext.with(K1, V1).toString()) - .isEqualTo(defaultStatsContext.with(K1, V1).toString()); - assertThat(defaultStatsContext.with(K10, V1).toString()) - .isNotEqualTo(defaultStatsContext.with(K1, V1).toString()); - assertThat(defaultStatsContext.with(K1, V10).toString()) - .isNotEqualTo(defaultStatsContext.with(K1, V1).toString()); - } - - private void testSerialize(Tag... tags) throws IOException { - StatsContext.Builder builder = defaultStatsContext.builder(); - for (Tag tag : tags) { + private void testSerialize(TagString... tags) throws IOException { + TagContextBuilder builder = tagContexts.emptyBuilder(); + for (TagString tag : tags) { builder.set(tag.getKey(), tag.getValue()); } ByteArrayOutputStream actual = new ByteArrayOutputStream(); - builder.build().serialize(actual); + serializer.serialize(builder.build(), actual); - Collection> tagPermutation = Collections2.permutations(Arrays.asList(tags)); + Collection> tagPermutation = Collections2.permutations(Arrays.asList(tags)); Set possibleOutputs = new HashSet(); - for (List list : tagPermutation) { + for (List list : tagPermutation) { ByteArrayOutputStream expected = new ByteArrayOutputStream(); expected.write(VERSION_ID); - for (Tag tag : list) { + for (TagString tag : list) { expected.write(VALUE_TYPE_STRING); - encodeString(tag.getKey().asString(), expected); + encodeString(tag.getKey().getName(), expected); encodeString(tag.getValue().asString(), expected); } possibleOutputs.add(expected.toString()); @@ -252,7 +100,7 @@ private void testSerialize(Tag... tags) throws IOException { assertThat(possibleOutputs).contains(actual.toString()); } - private static final void encodeString(String input, ByteArrayOutputStream byteArrayOutputStream) + private static void encodeString(String input, ByteArrayOutputStream byteArrayOutputStream) throws IOException { VarInt.putVarInt(input.length(), byteArrayOutputStream); byteArrayOutputStream.write(input.getBytes("UTF-8")); diff --git a/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java b/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java index 6554c91480..3b0212c1b8 100644 --- a/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java +++ b/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import io.opencensus.tags.TagContextSerializer; import io.opencensus.tags.Tags; import io.opencensus.tags.TagsComponent; import org.junit.Test; @@ -28,4 +29,9 @@ public final class TagsTest { public void getTagContexts() { assertThat(Tags.getTagContexts()).isInstanceOf(TagContextsImpl.class); } + + @Test + public void getTagContextSerializer() { + assertThat(Tags.getTagContextSerializer()).isInstanceOf(TagContextSerializer.class); + } } diff --git a/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java b/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java index 6554c91480..3b0212c1b8 100644 --- a/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java +++ b/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java @@ -15,6 +15,7 @@ import static com.google.common.truth.Truth.assertThat; +import io.opencensus.tags.TagContextSerializer; import io.opencensus.tags.Tags; import io.opencensus.tags.TagsComponent; import org.junit.Test; @@ -28,4 +29,9 @@ public final class TagsTest { public void getTagContexts() { assertThat(Tags.getTagContexts()).isInstanceOf(TagContextsImpl.class); } + + @Test + public void getTagContextSerializer() { + assertThat(Tags.getTagContextSerializer()).isInstanceOf(TagContextSerializer.class); + } } From 1ec4e1b60b561173515f10fa99db617abc9a8985 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 15 Aug 2017 17:26:26 -0700 Subject: [PATCH 0409/1581] Document exceptions thrown by serialization methods. --- .../src/main/java/io/opencensus/tags/TagContextSerializer.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/io/opencensus/tags/TagContextSerializer.java b/core/src/main/java/io/opencensus/tags/TagContextSerializer.java index ced91881df..eab42e02ee 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextSerializer.java +++ b/core/src/main/java/io/opencensus/tags/TagContextSerializer.java @@ -30,6 +30,7 @@ public abstract class TagContextSerializer { * * @param tags the {@code TagContext} to serialize. * @param output the {@link OutputStream} to write the serialized tags to. + * @throws IOException if there is an {@code IOException} while writing to {@code output}. */ public abstract void serialize(TagContext tags, OutputStream output) throws IOException; @@ -40,6 +41,8 @@ public abstract class TagContextSerializer { * * @param input on-the-wire representation of a {@code TagContext}. * @return a {@code TagContext} deserialized from {@code input}. + * @throws IOException if there is a parse error or an {@code IOException} while reading from + * {@code input}. */ public abstract TagContext deserialize(InputStream input) throws IOException; From 4b9eea1c86e817e3a0463bd9b69d21659ee10a6e Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Tue, 15 Aug 2017 18:38:46 -0700 Subject: [PATCH 0410/1581] Add a class to hold multiple TagContext serialization formats. Now TagsComponent contains a TagPropagationComponent, which contains a TagContextBinarySerializer. This design allows us to add more formats in the future by adding them to TagPropagationComponent. TagPropagationComponent is similar to PropagationComponent in the trace package. --- ...r.java => TagContextBinarySerializer.java} | 18 ++++---- .../tags/TagPropagationComponent.java | 44 +++++++++++++++++++ .../main/java/io/opencensus/tags/Tags.java | 8 ++-- .../io/opencensus/tags/TagsComponent.java | 12 ++--- .../java/io/opencensus/tags/TagsTest.java | 4 +- ...va => TagContextBinarySerializerImpl.java} | 6 +-- .../tags/TagPropagationComponentImpl.java | 27 ++++++++++++ .../impl/tags/TagsComponentImplBase.java | 8 ++-- .../tags/TagContextDeserializationTest.java | 5 ++- .../impl/tags/TagContextRoundtripTest.java | 5 ++- .../tags/TagContextSerializationTest.java | 6 ++- .../io/opencensus/impl/tags/TagsTest.java | 4 +- .../io/opencensus/impl/tags/TagsTest.java | 4 +- 13 files changed, 112 insertions(+), 39 deletions(-) rename core/src/main/java/io/opencensus/tags/{TagContextSerializer.java => TagContextBinarySerializer.java} (77%) create mode 100644 core/src/main/java/io/opencensus/tags/TagPropagationComponent.java rename core_impl/src/main/java/io/opencensus/impl/tags/{TagContextSerializerImpl.java => TagContextBinarySerializerImpl.java} (87%) create mode 100644 core_impl/src/main/java/io/opencensus/impl/tags/TagPropagationComponentImpl.java diff --git a/core/src/main/java/io/opencensus/tags/TagContextSerializer.java b/core/src/main/java/io/opencensus/tags/TagContextBinarySerializer.java similarity index 77% rename from core/src/main/java/io/opencensus/tags/TagContextSerializer.java rename to core/src/main/java/io/opencensus/tags/TagContextBinarySerializer.java index eab42e02ee..c228514f48 100644 --- a/core/src/main/java/io/opencensus/tags/TagContextSerializer.java +++ b/core/src/main/java/io/opencensus/tags/TagContextBinarySerializer.java @@ -18,10 +18,10 @@ import java.io.OutputStream; import javax.annotation.concurrent.Immutable; -/** Object for serializing and deserializing {@link TagContext}s. */ -public abstract class TagContextSerializer { - private static final TagContextSerializer NOOP_TAG_CONTEXT_SERIALIZER = - new NoopTagContextSerializer(); +/** Object for serializing and deserializing {@link TagContext}s with the binary format. */ +public abstract class TagContextBinarySerializer { + private static final TagContextBinarySerializer NOOP_TAG_CONTEXT_BINARY_SERIALIZER = + new NoopTagContextBinarySerializer(); /** * Serializes the {@code TagContext} into the on-the-wire representation. @@ -47,15 +47,15 @@ public abstract class TagContextSerializer { public abstract TagContext deserialize(InputStream input) throws IOException; /** - * Returns a {@code TagContextSerializer} that serializes all {@code TagContext}s to zero bytes - * and deserializes all inputs to empty {@code TagContext}s. + * Returns a {@code TagContextBinarySerializer} that serializes all {@code TagContext}s to zero + * bytes and deserializes all inputs to empty {@code TagContext}s. */ - static TagContextSerializer getNoopTagContextSerializer() { - return NOOP_TAG_CONTEXT_SERIALIZER; + static TagContextBinarySerializer getNoopTagContextBinarySerializer() { + return NOOP_TAG_CONTEXT_BINARY_SERIALIZER; } @Immutable - private static final class NoopTagContextSerializer extends TagContextSerializer { + private static final class NoopTagContextBinarySerializer extends TagContextBinarySerializer { @Override public void serialize(TagContext tags, OutputStream output) throws IOException {} diff --git a/core/src/main/java/io/opencensus/tags/TagPropagationComponent.java b/core/src/main/java/io/opencensus/tags/TagPropagationComponent.java new file mode 100644 index 0000000000..54efa8a7a2 --- /dev/null +++ b/core/src/main/java/io/opencensus/tags/TagPropagationComponent.java @@ -0,0 +1,44 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.tags; + +import javax.annotation.concurrent.Immutable; + +/** Object containing all supported {@link TagContext} propagation formats. */ +// TODO(sebright): Add an HTTP serializer. +public abstract class TagPropagationComponent { + private static final TagPropagationComponent NOOP_TAG_PROPAGATION_COMPONENT = + new NoopTagPropagationComponent(); + + /** + * Returns the {@link TagContextBinarySerializer} for this implementation. + * + * @return the {@code TagContextBinarySerializer} for this implementation. + */ + public abstract TagContextBinarySerializer getBinarySerializer(); + + /** Returns a {@code TagPropagationComponent} that contains no-op serializers. */ + static TagPropagationComponent getNoopTagPropagationComponent() { + return NOOP_TAG_PROPAGATION_COMPONENT; + } + + @Immutable + private static final class NoopTagPropagationComponent extends TagPropagationComponent { + + @Override + public TagContextBinarySerializer getBinarySerializer() { + return TagContextBinarySerializer.getNoopTagContextBinarySerializer(); + } + } +} diff --git a/core/src/main/java/io/opencensus/tags/Tags.java b/core/src/main/java/io/opencensus/tags/Tags.java index 86e06af9a7..19190c85d6 100644 --- a/core/src/main/java/io/opencensus/tags/Tags.java +++ b/core/src/main/java/io/opencensus/tags/Tags.java @@ -37,12 +37,12 @@ public static TagContexts getTagContexts() { } /** - * Returns the default {@code TagContextSerializer}. + * Returns the default {@code TagPropagationComponent}. * - * @return the default {@code TagContextSerializer}. + * @return the default {@code TagPropagationComponent}. */ - public static TagContextSerializer getTagContextSerializer() { - return tagsComponent.getTagContextSerializer(); + public static TagPropagationComponent getTagPropagationComponent() { + return tagsComponent.getTagPropagationComponent(); } // Any provider that may be used for TagsComponent can be added here. diff --git a/core/src/main/java/io/opencensus/tags/TagsComponent.java b/core/src/main/java/io/opencensus/tags/TagsComponent.java index ff9e4b6e53..070cb9f76c 100644 --- a/core/src/main/java/io/opencensus/tags/TagsComponent.java +++ b/core/src/main/java/io/opencensus/tags/TagsComponent.java @@ -26,13 +26,13 @@ public abstract class TagsComponent { /** Returns the {@link TagContexts} for this implementation. */ public abstract TagContexts getTagContexts(); - /** Returns the {@link TagContextSerializer} for this implementation. */ - public abstract TagContextSerializer getTagContextSerializer(); + /** Returns the {@link TagPropagationComponent} for this implementation. */ + public abstract TagPropagationComponent getTagPropagationComponent(); /** - * Returns a {@code TagsComponent} that has a no-op implementation for the {@link TagContexts}. + * Returns a {@code TagsComponent} that has a no-op implementation for {@link TagContexts}. * - * @return a {@code TagsComponent} that has a no-op implementation for the {@code TagContexts}. + * @return a {@code TagsComponent} that has a no-op implementation for {@code TagContexts}. */ static TagsComponent getNoopTagsComponent() { return NOOP_TAGS_COMPONENT; @@ -47,8 +47,8 @@ public TagContexts getTagContexts() { } @Override - public TagContextSerializer getTagContextSerializer() { - return TagContextSerializer.getNoopTagContextSerializer(); + public TagPropagationComponent getTagPropagationComponent() { + return TagPropagationComponent.getNoopTagPropagationComponent(); } } } diff --git a/core/src/test/java/io/opencensus/tags/TagsTest.java b/core/src/test/java/io/opencensus/tags/TagsTest.java index fd54f38735..5e8c541c2b 100644 --- a/core/src/test/java/io/opencensus/tags/TagsTest.java +++ b/core/src/test/java/io/opencensus/tags/TagsTest.java @@ -60,7 +60,7 @@ public void defaultTagContexts() { @Test public void defaultTagContextSerializer() { - assertThat(Tags.getTagContextSerializer()) - .isEqualTo(TagContextSerializer.getNoopTagContextSerializer()); + assertThat(Tags.getTagPropagationComponent()) + .isEqualTo(TagPropagationComponent.getNoopTagPropagationComponent()); } } diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextSerializerImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextBinarySerializerImpl.java similarity index 87% rename from core_impl/src/main/java/io/opencensus/impl/tags/TagContextSerializerImpl.java rename to core_impl/src/main/java/io/opencensus/impl/tags/TagContextBinarySerializerImpl.java index 7b2cefa202..6b1b723845 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagContextSerializerImpl.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagContextBinarySerializerImpl.java @@ -14,14 +14,12 @@ package io.opencensus.impl.tags; import io.opencensus.tags.TagContext; -import io.opencensus.tags.TagContextSerializer; +import io.opencensus.tags.TagContextBinarySerializer; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -final class TagContextSerializerImpl extends TagContextSerializer { - TagContextSerializerImpl() {} - +final class TagContextBinarySerializerImpl extends TagContextBinarySerializer { @Override public void serialize(TagContext tags, OutputStream output) throws IOException { SerializationUtils.serialize(tags, output); diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagPropagationComponentImpl.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagPropagationComponentImpl.java new file mode 100644 index 0000000000..2adb97ff82 --- /dev/null +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagPropagationComponentImpl.java @@ -0,0 +1,27 @@ +/* + * Copyright 2017, Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opencensus.impl.tags; + +import io.opencensus.tags.TagContextBinarySerializer; +import io.opencensus.tags.TagPropagationComponent; + +final class TagPropagationComponentImpl extends TagPropagationComponent { + private final TagContextBinarySerializer tagContextBinarySerializer = + new TagContextBinarySerializerImpl(); + + @Override + public TagContextBinarySerializer getBinarySerializer() { + return tagContextBinarySerializer; + } +} diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java b/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java index c1b41fc69c..c1cb50e81e 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/TagsComponentImplBase.java @@ -13,14 +13,14 @@ package io.opencensus.impl.tags; -import io.opencensus.tags.TagContextSerializer; import io.opencensus.tags.TagContexts; +import io.opencensus.tags.TagPropagationComponent; import io.opencensus.tags.TagsComponent; /** Base implementation of {@link TagsComponent}. */ public abstract class TagsComponentImplBase extends TagsComponent { private final TagContexts tagContexts = new TagContextsImpl(); - private final TagContextSerializer tagContextSerializer = new TagContextSerializerImpl(); + private final TagPropagationComponent tagPropagationComponent = new TagPropagationComponentImpl(); @Override public TagContexts getTagContexts() { @@ -28,7 +28,7 @@ public TagContexts getTagContexts() { } @Override - public TagContextSerializer getTagContextSerializer() { - return tagContextSerializer; + public TagPropagationComponent getTagPropagationComponent() { + return tagPropagationComponent; } } diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java index 4495ec1c57..32d4af8342 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextDeserializationTest.java @@ -18,6 +18,7 @@ import com.google.common.collect.Lists; import io.opencensus.internal.VarInt; import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContextBinarySerializer; import io.opencensus.tags.TagContexts; import io.opencensus.tags.TagKey.TagKeyString; import io.opencensus.tags.TagValueString; @@ -31,7 +32,7 @@ /** * Tests for deserializing tags with {@link SerializationUtils} and {@link - * TagContextSerializerImpl}. + * TagContextBinarySerializerImpl}. */ @RunWith(JUnit4.class) public class TagContextDeserializationTest { @@ -40,7 +41,7 @@ public class TagContextDeserializationTest { private static final String VALUE_STRING = "String"; private static final int VALUE_INT = 10; - private final TagContextSerializerImpl serializer = new TagContextSerializerImpl(); + private final TagContextBinarySerializer serializer = new TagContextBinarySerializerImpl(); private final TagContexts tagContexts = new TagContextsImpl(); @Test diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextRoundtripTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextRoundtripTest.java index 4cbdc9e224..e0250ced01 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextRoundtripTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextRoundtripTest.java @@ -17,6 +17,7 @@ import com.google.common.collect.Lists; import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContextBinarySerializer; import io.opencensus.tags.TagContexts; import io.opencensus.tags.TagKey.TagKeyString; import io.opencensus.tags.TagValueString; @@ -26,7 +27,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Tests for roundtrip serialization with {@link TagContextSerializerImpl}. */ +/** Tests for roundtrip serialization with {@link TagContextBinarySerializerImpl}. */ @RunWith(JUnit4.class) public class TagContextRoundtripTest { @@ -40,7 +41,7 @@ public class TagContextRoundtripTest { private static final TagValueString V2 = TagValueString.create("v2"); private static final TagValueString V3 = TagValueString.create("v3"); - private final TagContextSerializerImpl serializer = new TagContextSerializerImpl(); + private final TagContextBinarySerializer serializer = new TagContextBinarySerializerImpl(); private final TagContexts tagContexts = new TagContextsImpl(); @Test diff --git a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java index 963e16f1e3..76116a05f0 100644 --- a/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java +++ b/core_impl/src/test/java/io/opencensus/impl/tags/TagContextSerializationTest.java @@ -18,6 +18,7 @@ import com.google.common.collect.Collections2; import io.opencensus.internal.VarInt; import io.opencensus.tags.Tag.TagString; +import io.opencensus.tags.TagContextBinarySerializer; import io.opencensus.tags.TagContextBuilder; import io.opencensus.tags.TagContexts; import io.opencensus.tags.TagKey.TagKeyString; @@ -34,7 +35,8 @@ import org.junit.runners.JUnit4; /** - * Tests for serializing tags with {@link SerializationUtils} and {@link TagContextSerializerImpl}. + * Tests for serializing tags with {@link SerializationUtils} and {@link + * TagContextBinarySerializerImpl}. */ @RunWith(JUnit4.class) public class TagContextSerializationTest { @@ -57,7 +59,7 @@ public class TagContextSerializationTest { private static final TagString T3 = TagString.create(K3, V3); private static final TagString T4 = TagString.create(K4, V4); - private final TagContextSerializerImpl serializer = new TagContextSerializerImpl(); + private final TagContextBinarySerializer serializer = new TagContextBinarySerializerImpl(); private final TagContexts tagContexts = new TagContextsImpl(); @Test diff --git a/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java b/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java index 3b0212c1b8..c9f897bfe6 100644 --- a/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java +++ b/core_impl_android/src/test/java/io/opencensus/impl/tags/TagsTest.java @@ -15,7 +15,6 @@ import static com.google.common.truth.Truth.assertThat; -import io.opencensus.tags.TagContextSerializer; import io.opencensus.tags.Tags; import io.opencensus.tags.TagsComponent; import org.junit.Test; @@ -32,6 +31,7 @@ public void getTagContexts() { @Test public void getTagContextSerializer() { - assertThat(Tags.getTagContextSerializer()).isInstanceOf(TagContextSerializer.class); + assertThat(Tags.getTagPropagationComponent()) + .isInstanceOf(TagPropagationComponentImpl.class); } } diff --git a/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java b/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java index 3b0212c1b8..c9f897bfe6 100644 --- a/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java +++ b/core_impl_java/src/test/java/io/opencensus/impl/tags/TagsTest.java @@ -15,7 +15,6 @@ import static com.google.common.truth.Truth.assertThat; -import io.opencensus.tags.TagContextSerializer; import io.opencensus.tags.Tags; import io.opencensus.tags.TagsComponent; import org.junit.Test; @@ -32,6 +31,7 @@ public void getTagContexts() { @Test public void getTagContextSerializer() { - assertThat(Tags.getTagContextSerializer()).isInstanceOf(TagContextSerializer.class); + assertThat(Tags.getTagPropagationComponent()) + .isInstanceOf(TagPropagationComponentImpl.class); } } From 78987ec441837a401887094fa49661ed009f9baf Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Wed, 16 Aug 2017 15:00:41 -0700 Subject: [PATCH 0411/1581] Document that the TagContext encoding is shared across OpenCensus implementations. --- .../java/io/opencensus/impl/tags/SerializationUtils.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java b/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java index a8417879c9..8213e26dae 100644 --- a/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java +++ b/core_impl/src/main/java/io/opencensus/impl/tags/SerializationUtils.java @@ -36,9 +36,12 @@ import java.util.Iterator; /** - * {@link TagContext} serialization. + * Methods for serializing and deserializing {@link TagContext}s. * - *

Encoding of tag context information for passing across RPC's: + *

The format defined in this class is shared across all implementations of OpenCensus. It allows + * tags to propagate across requests. + * + *

OpenCensus tag context encoding: * *