headerValues);
}
diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/ServiceOrigin.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/ServiceOrigin.java
new file mode 100644
index 0000000000..00ce0e4f8c
--- /dev/null
+++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/ServiceOrigin.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you 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 co.elastic.apm.agent.tracer.metadata;
+
+import javax.annotation.Nullable;
+
+public interface ServiceOrigin {
+
+ ServiceOrigin withId(@Nullable String apiId);
+
+ ServiceOrigin withName(@Nullable CharSequence name);
+
+ ServiceOrigin withVersion(@Nullable String version);
+}
diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/User.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/User.java
index 3524cd7653..21e29fd962 100644
--- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/User.java
+++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/User.java
@@ -37,4 +37,8 @@ public interface User {
* The username of the logged in user
*/
User withUsername(String userName);
+
+ User withId(String id);
+
+ User withEmail(String email);
}
diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/DataWriter.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/DataWriter.java
new file mode 100644
index 0000000000..80232a06b1
--- /dev/null
+++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/DataWriter.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you 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 co.elastic.apm.agent.tracer.reporting;
+
+import javax.annotation.Nullable;
+
+public interface DataWriter {
+
+ void writeStructure(StructureType type);
+
+ void writeKey(CharSequence name);
+
+ void writeKey(CharSequence name, boolean sanitized);
+
+ void writeKey(CharSequence name, boolean sanitized, @Nullable String suffix);
+
+ void writeValue(boolean value);
+
+ void writeValue(long value);
+
+ void writeValue(double value);
+
+ void writeValue(CharSequence value);
+
+ void writeValue(CharSequence value, boolean trimmed);
+
+ int size();
+
+ void report();
+
+ enum StructureType {
+ OBJECT_START,
+ OBJECT_END,
+ ARRAY_START,
+ ARRAY_END,
+ NEXT,
+ NEW
+ }
+}
diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/DoubleSupplier.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/DoubleSupplier.java
similarity index 94%
rename from apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/DoubleSupplier.java
rename to apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/DoubleSupplier.java
index 120a72221d..390dfe97e2 100644
--- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/DoubleSupplier.java
+++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/DoubleSupplier.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package co.elastic.apm.agent.metrics;
+package co.elastic.apm.agent.tracer.reporting;
public interface DoubleSupplier {
diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/Labels.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/Labels.java
similarity index 98%
rename from apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/Labels.java
rename to apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/Labels.java
index c6a2e0475d..7bfcee52dc 100644
--- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/Labels.java
+++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/Labels.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package co.elastic.apm.agent.metrics;
+package co.elastic.apm.agent.tracer.reporting;
import co.elastic.apm.agent.tracer.pooling.Recyclable;
@@ -31,10 +31,6 @@
* However, there are also top-level labels which are not nested under the {@code labels} object,
* for example {@link #getTransactionName()}, {@link #getTransactionType()}, {@link #getSpanType()} and {@link #getSpanSubType()}.
*
- * Metrics are structured into multiple {@link MetricSet}s.
- * For each distinct combination of {@link Labels}, there is one {@link MetricSet}.
- *
- *
* Labels allow for {@link CharSequence}s as a value,
* thus avoiding allocations for {@code transaction.name.toString()} when tracking breakdown metrics for a transaction.
* Iterations over the labels also don't allocate an Iterator, in contrast to {@code Map.entrySet().iterator()}.
diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/ReportingTracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/ReportingTracer.java
new file mode 100644
index 0000000000..68caa70f80
--- /dev/null
+++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/ReportingTracer.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you 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 co.elastic.apm.agent.tracer.reporting;
+
+import co.elastic.apm.agent.tracer.Tracer;
+
+import java.io.Closeable;
+import java.util.concurrent.ScheduledExecutorService;
+
+public interface ReportingTracer extends Tracer {
+
+ void addMetric(String name, Labels labels, DoubleSupplier metric);
+
+ void removeMetric(String name, Labels labels);
+
+ /**
+ * Reports an ECS-logging formatted log message.
+ *
+ * @param log log message generated by ecs-logging
+ */
+ void reportLog(String log);
+
+ /**
+ * Reports an ECS-logging formatted log message.
+ *
+ * @param log log message generated by ecs-logging
+ */
+ void reportLog(byte[] log);
+
+ DataWriter newWriter(int maxSerializedSize);
+
+ ScheduledExecutorService getSharedSingleThreadedPool();
+
+ void addShutdownHook(Closeable job);
+}
diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/sampling/ProbabilitySamplerTest.java b/apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/direct/ProbabilitySamplerTest.java
similarity index 74%
rename from apm-agent-core/src/test/java/co/elastic/apm/agent/impl/sampling/ProbabilitySamplerTest.java
rename to apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/direct/ProbabilitySamplerTest.java
index 216c593d11..447ab5ecdc 100644
--- a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/sampling/ProbabilitySamplerTest.java
+++ b/apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/direct/ProbabilitySamplerTest.java
@@ -16,14 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-package co.elastic.apm.agent.impl.sampling;
+package co.elastic.apm.agent.tracer.direct;
-import co.elastic.apm.agent.impl.transaction.Id;
-import co.elastic.apm.agent.impl.transaction.TraceState;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.CsvSource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -40,25 +36,10 @@ void setUp() {
assertThat(sampler.getSampleRate()).isEqualTo(SAMPLING_RATE);
}
- @ParameterizedTest
- @CsvSource({"0.0","1.0","0.5"})
- void headerCaching(double rate) {
-
- // will indirectly test ConstantSampler as we delegate to it for 0 and 1 values
- sampler = ProbabilitySampler.of(rate);
-
- String rateHeader = sampler.getTraceStateHeader();
- assertThat(rateHeader).isEqualTo(TraceState.getHeaderValue(rate));
-
- assertThat(rateHeader)
- .describedAs("sample rate header should return same instance on each call")
- .isSameAs(sampler.getTraceStateHeader());
- }
-
@Test
void isSampledEmpiricalTest() {
int sampledTransactions = 0;
- Id id = Id.new128BitId();
+ TestId id = TestId.new128BitId();
for (int i = 0; i < ITERATIONS; i++) {
id.setToRandomValue();
if (sampler.isSampled(id)) {
@@ -71,7 +52,7 @@ void isSampledEmpiricalTest() {
@Test
void testSamplingUpperBoundary() {
long upperBound = Long.MAX_VALUE / 2;
- final Id transactionId = Id.new128BitId();
+ final TestId transactionId = TestId.new128BitId();
transactionId.fromLongs((long) 0, upperBound - 1);
assertThat(ProbabilitySampler.of(0.5).isSampled(transactionId)).isTrue();
@@ -86,7 +67,7 @@ void testSamplingUpperBoundary() {
@Test
void testSamplingLowerBoundary() {
long lowerBound = -Long.MAX_VALUE / 2;
- final Id transactionId = Id.new128BitId();
+ final TestId transactionId = TestId.new128BitId();
transactionId.fromLongs((long) 0, lowerBound + 1);
assertThat(ProbabilitySampler.of(0.5).isSampled(transactionId)).isTrue();
diff --git a/apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/direct/TestId.java b/apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/direct/TestId.java
new file mode 100644
index 0000000000..e0875fe99a
--- /dev/null
+++ b/apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/direct/TestId.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you 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 co.elastic.apm.agent.tracer.direct;
+
+import co.elastic.apm.agent.tracer.Id;
+import co.elastic.apm.agent.tracer.util.HexUtils;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class TestId implements Id {
+
+ private final byte[] data;
+ private boolean empty = true;
+
+ public static TestId new128BitId() {
+ return new TestId(16);
+ }
+
+ public static TestId new64BitId() {
+ return new TestId(8);
+ }
+
+ private TestId(int idLengthBytes) {
+ data = new byte[idLengthBytes];
+ }
+
+ @Override
+ public void setToRandomValue() {
+ setToRandomValue(ThreadLocalRandom.current());
+ }
+
+ public void setToRandomValue(Random random) {
+ random.nextBytes(data);
+ onMutation(false);
+ }
+
+ public void fromLongs(long... values) {
+ if (values.length * Long.BYTES != data.length) {
+ throw new IllegalArgumentException("Invalid number of long values");
+ }
+ final ByteBuffer buffer = ByteBuffer.wrap(data);
+ for (long value : values) {
+ buffer.putLong(value);
+ }
+ onMutation();
+ }
+
+ public void copyFrom(TestId other) {
+ System.arraycopy(other.data, 0, data, 0, data.length);
+ this.empty = other.empty;
+ }
+
+ private void onMutation() {
+ onMutation(isAllZeros(data));
+ }
+
+ private void onMutation(boolean empty) {
+ this.empty = empty;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TestId that = (TestId) o;
+ return Arrays.equals(data, that.data);
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(data);
+ }
+
+ @Override
+ public String toString() {
+ return HexUtils.bytesToHex(data);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return empty;
+ }
+
+ private static boolean isAllZeros(byte[] bytes) {
+ for (byte b : bytes) {
+ if (b != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public long getLeastSignificantBits() {
+ return readLong(data.length - 8);
+ }
+
+ private long readLong(int offset) {
+ long lsb = 0;
+ for (int i = offset; i < offset + 8; i++) {
+ lsb = (lsb << 8) | (data[i] & 0xff);
+ }
+ return lsb;
+ }
+}
diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/LabelsTest.java b/apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/reporting/LabelsTest.java
similarity index 99%
rename from apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/LabelsTest.java
rename to apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/reporting/LabelsTest.java
index 21e55850c0..a27919baec 100644
--- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/LabelsTest.java
+++ b/apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/reporting/LabelsTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package co.elastic.apm.agent.metrics;
+package co.elastic.apm.agent.tracer.reporting;
import org.junit.jupiter.api.Test;
diff --git a/apm-opentracing/pom.xml b/apm-opentracing/pom.xml
index dd19c4819b..ecc1111fc8 100644
--- a/apm-opentracing/pom.xml
+++ b/apm-opentracing/pom.xml
@@ -39,6 +39,12 @@
${project.version}
test