diff --git a/api/src/main/java/io/opentelemetry/OpenTelemetry.java b/api/src/main/java/io/opentelemetry/OpenTelemetry.java index e113a466548..ae7a9a3cc7d 100644 --- a/api/src/main/java/io/opentelemetry/OpenTelemetry.java +++ b/api/src/main/java/io/opentelemetry/OpenTelemetry.java @@ -23,6 +23,10 @@ import io.opentelemetry.correlationcontext.spi.CorrelationContextManagerFactory; import io.opentelemetry.internal.Obfuscated; import io.opentelemetry.internal.Utils; +import io.opentelemetry.logs.DefaultLogSinkProvider; +import io.opentelemetry.logs.LogSink; +import io.opentelemetry.logs.spi.LogSinkProvider; +import io.opentelemetry.logs.spi.LogSinkProviderFactory; import io.opentelemetry.metrics.DefaultMeterProvider; import io.opentelemetry.metrics.Meter; import io.opentelemetry.metrics.MeterProvider; @@ -55,6 +59,7 @@ public final class OpenTelemetry { private final TracerProvider tracerProvider; private final MeterProvider meterProvider; private final CorrelationContextManager contextManager; + private final LogSinkProvider logSinkProvider; private volatile ContextPropagators propagators = DefaultContextPropagators.builder().addHttpTextFormat(new HttpTraceContext()).build(); @@ -144,6 +149,34 @@ public static Meter getMeter(String instrumentationName, String instrumentationV return getMeterProvider().get(instrumentationName, instrumentationVersion); } + /** + * Returns a singleton {@link LogSinkProvider}. + * + * @return registered LogSinkProvider or default via {@link DefaultLogSinkProvider#getInstance()}. + * @throws IllegalStateException if a specified MeterProvider (via system properties) could not be + * found. + * @since 0.1.0 + */ + private static LogSinkProvider getLogSinkProvider() { + return getInstance().logSinkProvider; + } + + /** + * Gets or creates a named and versioned log sink instance. + * + *

This is a shortcut method for + * getLogSinkProvider().get(instrumentationName, instrumentationVersion). + * + * @param instrumentationName The name of the instrumentation library, not the name of the + * instrument*ed* library. + * @param instrumentationVersion The version of the instrumentation library. + * @return a tracer instance. + * @since 0.7.0 + */ + public static LogSink getLogSink(String instrumentationName, String instrumentationVersion) { + return getLogSinkProvider().get(instrumentationName, instrumentationVersion); + } + /** * Returns a singleton {@link CorrelationContextManager}. * @@ -210,6 +243,13 @@ private OpenTelemetry() { meterProviderFactory != null ? meterProviderFactory.create() : DefaultMeterProvider.getInstance(); + + LogSinkProviderFactory logProviderFactory = loadSpi(LogSinkProviderFactory.class); + this.logSinkProvider = + logProviderFactory != null + ? logProviderFactory.create() + : DefaultLogSinkProvider.getInstance(); + CorrelationContextManagerFactory contextManagerProvider = loadSpi(CorrelationContextManagerFactory.class); contextManager = diff --git a/api/src/main/java/io/opentelemetry/common/AnyValue.java b/api/src/main/java/io/opentelemetry/common/AnyValue.java new file mode 100644 index 00000000000..893fd4ec2ad --- /dev/null +++ b/api/src/main/java/io/opentelemetry/common/AnyValue.java @@ -0,0 +1,291 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * 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.opentelemetry.common; + +import com.google.auto.value.AutoValue; +import java.util.List; +import java.util.Map; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * A class that represents all the possible values for a data body. An {@code AnyValue} can have 6 + * types of values: {@code String}, {@code boolean}, {@code int}, {@code double}, {@code array}, or + * {@code kvlist}. represented through {@code AnyValue.Type}. A {@code array} or a {@code kvlist} + * can in turn hold other {@code AnyValue} instances, allowing for mapping to JSON-like structures. + * + * @since 0.7.0 + */ +@Immutable +public abstract class AnyValue { + + /** + * An enum that represents all the possible value types for an {@code AnyValue}. + * + * @since 0.7.0 + */ + public enum Type { + STRING, + BOOL, + INT, + DOUBLE, + ARRAY, + KVLIST + } + + /** + * Returns an {@code AnyValue} with a string value. + * + * @param stringValue The new value. + * @return an {@code AnyValue} with a string value. + * @since 0.7.0 + */ + public static AnyValue stringAnyValue(String stringValue) { + return AnyValueString.create(stringValue); + } + + /** + * Returns the string value of this {@code AnyValue}. An UnsupportedOperationException will be + * thrown if getType() is not {@link AnyValue.Type#STRING}. + * + * @return the string value of this {@code AttributeValue}. + * @since 0.7.0 + */ + public String getStringValue() { + throw new UnsupportedOperationException( + String.format("This type can only return %s data", getType().name())); + } + + /** + * Returns an {@code AnyValue} with an int value. + * + * @param intValue The new value. + * @return an {@code AnyValue} with a int value. + * @since 0.7.0 + */ + public static AnyValue intAnyValue(int intValue) { + return AnyValueInt.create(intValue); + } + + public int getIntValue() { + throw new UnsupportedOperationException( + String.format("This type can only return %s data", getType().name())); + } + + /** + * Returns an {@code AnyValue} with a bool value. + * + * @param boolValue The new value. + * @return an {@code AnyValue} with a bool value. + * @since 0.7.0 + */ + public static AnyValue boolAnyValue(boolean boolValue) { + return AnyValueBool.create(boolValue); + } + + /** + * Returns the boolean value of this {@code AnyValue}. An UnsupportedOperationException will be + * thrown if getType() is not {@link AnyValue.Type#BOOL}. + * + * @return the boolean value of this {@code AttributeValue}. + * @since 0.7.0 + */ + public boolean getBoolValue() { + throw new UnsupportedOperationException( + String.format("This type can only return %s data", getType().name())); + } + + /** + * Returns an {@code AnyValue} with a double value. + * + * @param doubleValue The new value. + * @return an {@code AnyValue} with a double value. + * @since 0.7.0 + */ + public static AnyValue doubleAnyValue(double doubleValue) { + return AnyValueDouble.create(doubleValue); + } + + /** + * Returns the double value of this {@code AnyValue}. An UnsupportedOperationException will be + * thrown if getType() is not {@link AnyValue.Type#DOUBLE}. + * + * @return the double value of this {@code AttributeValue}. + * @since 0.7.0 + */ + public double getDoubleValue() { + throw new UnsupportedOperationException( + String.format("This type can only return %s data", getType().name())); + } + + /** + * Returns an {@code AnyValue} with a array value. + * + * @param values The new value. + * @return an {@code AnyValue} with a array value. + * @since 0.7.0 + */ + public static AnyValue arrayAnyValue(List values) { + return AnyValueArray.create(values); + } + + /** + * Returns the array value of this {@code AnyValue}. An UnsupportedOperationException will be + * thrown if getType() is not {@link AnyValue.Type#ARRAY}. + * + * @return the array value of this {@code AttributeValue}. + * @since 0.7.0 + */ + public List getArrayValue() { + throw new UnsupportedOperationException( + String.format("This type can only return %s data", getType().name())); + } + + /** + * Returns an {@code AnyValue} with a kvlist value. + * + * @param values The new value. + * @return an {@code AnyValue} with a kvlist value. + * @since 0.7.0 + */ + public static AnyValue kvlistAnyValue(Map values) { + return AnyValueKvlist.create(values); + } + + /** + * Returns the string value of this {@code AnyValue}. An UnsupportedOperationException will be + * thrown if getType() is not {@link AnyValue.Type#STRING}. + * + * @return the string value of this {@code AttributeValue}. + * @since 0.7.0 + */ + public Map getKvlistValue() { + throw new UnsupportedOperationException( + String.format("This type can only return %s data", getType().name())); + } + + public abstract Type getType(); + + @Immutable + @AutoValue + abstract static class AnyValueString extends AnyValue { + AnyValueString() {} + + static AnyValue create(String stringValue) { + return new AutoValue_AnyValue_AnyValueString(stringValue); + } + + @Override + public final Type getType() { + return Type.STRING; + } + + @Override + @Nullable + public abstract String getStringValue(); + } + + @Immutable + @AutoValue + abstract static class AnyValueInt extends AnyValue { + AnyValueInt() {} + + static AnyValue create(int intValue) { + return new AutoValue_AnyValue_AnyValueInt(intValue); + } + + @Override + public final Type getType() { + return Type.INT; + } + + @Override + public abstract int getIntValue(); + } + + @Immutable + @AutoValue + abstract static class AnyValueBool extends AnyValue { + AnyValueBool() {} + + static AnyValue create(boolean boolValue) { + return new AutoValue_AnyValue_AnyValueBool(boolValue); + } + + @Override + public final Type getType() { + return Type.BOOL; + } + + @Override + public abstract boolean getBoolValue(); + } + + @Immutable + @AutoValue + abstract static class AnyValueDouble extends AnyValue { + AnyValueDouble() {} + + static AnyValue create(double doubleValue) { + return new AutoValue_AnyValue_AnyValueDouble(doubleValue); + } + + @Override + public final Type getType() { + return Type.DOUBLE; + } + + @Override + public abstract double getDoubleValue(); + } + + @Immutable + @AutoValue + abstract static class AnyValueArray extends AnyValue { + AnyValueArray() {} + + static AnyValue create(List arrayValue) { + return new AutoValue_AnyValue_AnyValueArray(arrayValue); + } + + @Override + public final Type getType() { + return Type.ARRAY; + } + + @Override + public abstract List getArrayValue(); + } + + @Immutable + @AutoValue + abstract static class AnyValueKvlist extends AnyValue { + AnyValueKvlist() {} + + static AnyValue create(Map kvlistValue) { + return new AutoValue_AnyValue_AnyValueKvlist(kvlistValue); + } + + @Override + public final Type getType() { + return Type.KVLIST; + } + + @Override + public abstract Map getKvlistValue(); + } +} diff --git a/api/src/main/java/io/opentelemetry/logs/DefaultLogRecord.java b/api/src/main/java/io/opentelemetry/logs/DefaultLogRecord.java new file mode 100644 index 00000000000..6b02f28462e --- /dev/null +++ b/api/src/main/java/io/opentelemetry/logs/DefaultLogRecord.java @@ -0,0 +1,160 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * 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.opentelemetry.logs; + +import io.opentelemetry.common.AnyValue; +import io.opentelemetry.common.AttributeValue; +import java.util.Map; + +public class DefaultLogRecord implements LogRecord { + private long timestamp; + private byte[] traceId; + private byte[] spanId; + private int flags; + private Severity severity; + private String severityText; + private String name; + private AnyValue body; + private Map attributes; + + private DefaultLogRecord() {} + + /** + * Clone method, used so that changes through the builder do not affect the record built. + * + * @param template LogRecord from which to copy + */ + private DefaultLogRecord(DefaultLogRecord template) { + timestamp = template.timestamp; + traceId = template.traceId; + spanId = template.spanId; + flags = template.flags; + severity = template.severity; + severityText = template.severityText; + name = template.name; + body = template.body; + attributes = template.attributes; + } + + @Override + public long getTimeUnixNano() { + return timestamp; + } + + @Override + public byte[] getTraceId() { + return traceId; + } + + @Override + public byte[] getSpanId() { + return spanId; + } + + @Override + public int getFlags() { + return flags; + } + + @Override + public Severity getSeverity() { + return severity; + } + + @Override + public String getSeverityText() { + return severityText; + } + + @Override + public String getName() { + return name; + } + + @Override + public AnyValue getBody() { + return body; + } + + @Override + public Map getAttributes() { + return attributes; + } + + public static class Builder implements LogRecord.Builder { + DefaultLogRecord template = new DefaultLogRecord(); + + @Override + public LogRecord.Builder withUnixTimeNano(long timestamp) { + template.timestamp = timestamp; + return this; + } + + @Override + public LogRecord.Builder withTraceId(byte[] traceId) { + template.traceId = traceId; + return this; + } + + @Override + public LogRecord.Builder withSpanId(byte[] spanId) { + template.spanId = spanId; + return this; + } + + @Override + public LogRecord.Builder withFlags(int flags) { + template.flags = flags; + return this; + } + + @Override + public LogRecord.Builder withSeverity(Severity severity) { + template.severity = severity; + return this; + } + + @Override + public LogRecord.Builder withSeverityText(String severityText) { + template.severityText = severityText; + return this; + } + + @Override + public LogRecord.Builder withName(String name) { + template.name = name; + return this; + } + + @Override + public LogRecord.Builder withBody(AnyValue body) { + template.body = body; + return this; + } + + @Override + public LogRecord.Builder withAttributes(Map attributes) { + template.attributes = attributes; + return this; + } + + @Override + public LogRecord build() { + return new DefaultLogRecord(template); + } + } +} diff --git a/api/src/main/java/io/opentelemetry/logs/DefaultLogSinkProvider.java b/api/src/main/java/io/opentelemetry/logs/DefaultLogSinkProvider.java new file mode 100644 index 00000000000..e0371851b96 --- /dev/null +++ b/api/src/main/java/io/opentelemetry/logs/DefaultLogSinkProvider.java @@ -0,0 +1,55 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * 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.opentelemetry.logs; + +import io.opentelemetry.logs.spi.LogSinkProvider; +import javax.annotation.Nullable; + +public class DefaultLogSinkProvider implements LogSinkProvider { + + @Nullable private static DefaultLogSinkProvider instance; + @Nullable static LogSink sink; + + @Override + public LogSink get(String instrumentationName) { + return getSink(); + } + + @Override + public LogSink get(String instrumentationName, String instrumentationVersion) { + return getSink(); + } + + private static LogSink getSink() { + if (sink == null) { + sink = new NoOpLogSink(); + } + return sink; + } + + /** + * Returns a shared no-op instance of {@link LogSinkProvider}. + * + * @return no-op instance + */ + public static LogSinkProvider getInstance() { + if (instance == null) { + instance = new DefaultLogSinkProvider(); + } + return instance; + } +} diff --git a/api/src/main/java/io/opentelemetry/logs/LogRecord.java b/api/src/main/java/io/opentelemetry/logs/LogRecord.java new file mode 100644 index 00000000000..3d38d774201 --- /dev/null +++ b/api/src/main/java/io/opentelemetry/logs/LogRecord.java @@ -0,0 +1,102 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * 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.opentelemetry.logs; + +import io.opentelemetry.common.AnyValue; +import io.opentelemetry.common.AttributeValue; +import java.util.Map; + +public interface LogRecord { + long getTimeUnixNano(); + + byte[] getTraceId(); + + byte[] getSpanId(); + + int getFlags(); + + Severity getSeverity(); + + String getSeverityText(); + + String getName(); + + AnyValue getBody(); + + Map getAttributes(); + + enum Severity { + UNDEFINED_SEVERITY_NUMBER(0), + TRACE(1), + TRACE2(2), + TRACE3(3), + TRACE4(4), + DEBUG(5), + DEBUG2(6), + DEBUG3(7), + DEBUG4(8), + INFO(9), + INFO2(10), + INFO3(11), + INFO4(12), + WARN(13), + WARN2(14), + WARN3(15), + WARN4(16), + ERROR(17), + ERROR2(18), + ERROR3(19), + ERROR4(20), + FATAL(21), + FATAL2(22), + FATAL3(23), + FATAL4(24), + ; + + private final int severityNumber; + + Severity(int severityNumber) { + this.severityNumber = severityNumber; + } + + public int getSeverityNumber() { + return severityNumber; + } + } + + interface Builder { + Builder withUnixTimeNano(long timestamp); + + Builder withTraceId(byte[] traceId); + + Builder withSpanId(byte[] spanId); + + Builder withFlags(int flags); + + Builder withSeverity(Severity severity); + + Builder withSeverityText(String severityText); + + Builder withName(String name); + + Builder withBody(AnyValue body); + + Builder withAttributes(Map attributes); + + LogRecord build(); + } +} diff --git a/api/src/main/java/io/opentelemetry/logs/LogSink.java b/api/src/main/java/io/opentelemetry/logs/LogSink.java new file mode 100644 index 00000000000..6cd87fac5c4 --- /dev/null +++ b/api/src/main/java/io/opentelemetry/logs/LogSink.java @@ -0,0 +1,28 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * 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.opentelemetry.logs; + +public interface LogSink { + /** + * Supply a {@link LogRecord} object for transport if a logging backend is supplied and + * configured. + * + * @param record record to transmit + * @since 0.7.0 + */ + void offer(LogRecord record); +} diff --git a/api/src/main/java/io/opentelemetry/logs/NoOpLogSink.java b/api/src/main/java/io/opentelemetry/logs/NoOpLogSink.java new file mode 100644 index 00000000000..73321531ef5 --- /dev/null +++ b/api/src/main/java/io/opentelemetry/logs/NoOpLogSink.java @@ -0,0 +1,22 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * 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.opentelemetry.logs; + +public class NoOpLogSink implements LogSink { + @Override + public void offer(LogRecord record) {} +} diff --git a/api/src/main/java/io/opentelemetry/logs/spi/LogSinkProvider.java b/api/src/main/java/io/opentelemetry/logs/spi/LogSinkProvider.java new file mode 100644 index 00000000000..1f64f792381 --- /dev/null +++ b/api/src/main/java/io/opentelemetry/logs/spi/LogSinkProvider.java @@ -0,0 +1,43 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * 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.opentelemetry.logs.spi; + +import io.opentelemetry.logs.LogSink; + +public interface LogSinkProvider { + + /** + * Gets or creates a named log sink instance. + * + * @param instrumentationName The name of the instrumentation library, not the name of the + * instrument*ed* library. + * @return a tracer instance. + * @since 0.7.0 + */ + LogSink get(String instrumentationName); + + /** + * Gets or creates a named and versioned log sink instance. + * + * @param instrumentationName The name of the instrumentation library, not the name of the + * instrument*ed* library. + * @param instrumentationVersion The version of the instrumentation library. + * @return a log sink instance. + * @since 0.7.0 + */ + LogSink get(String instrumentationName, String instrumentationVersion); +} diff --git a/api/src/main/java/io/opentelemetry/logs/spi/LogSinkProviderFactory.java b/api/src/main/java/io/opentelemetry/logs/spi/LogSinkProviderFactory.java new file mode 100644 index 00000000000..ab57affcaa7 --- /dev/null +++ b/api/src/main/java/io/opentelemetry/logs/spi/LogSinkProviderFactory.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * 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.opentelemetry.logs.spi; + +/** + * LogSinkProviderFactory is a service provider for {@link LogSinkProvider}. Fully qualified class + * name of the implementation should be registered in {@code + * META-INF/services/io.opentelemetry.logs.spi.LogSinkProviderFactory}.
+ *
+ * A specific implementation can be selected by a system property {@code + * io.opentelemetry.logs.spi.LogSinkProviderFactory} with value of fully qualified class name. + * + * @see io.opentelemetry.OpenTelemetry + */ +public interface LogSinkProviderFactory { + /** + * Creates a new {@link LogSinkProvider} interface. + * + * @return a log sink provider instance + * @since 0.7.0 + */ + LogSinkProvider create(); +} diff --git a/api/src/test/java/io/opentelemetry/common/AnyValueTest.java b/api/src/test/java/io/opentelemetry/common/AnyValueTest.java new file mode 100644 index 00000000000..639073046ae --- /dev/null +++ b/api/src/test/java/io/opentelemetry/common/AnyValueTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * 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.opentelemetry.common; + +import static com.google.common.truth.Truth.assertThat; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class AnyValueTest { + + @Test + public void stringAnyValue() { + String testString = "e176f922-cf82-4fe7-93d0-f68440a825cf"; + AnyValue stringValue = AnyValue.stringAnyValue(testString); + assertThat(stringValue.getStringValue()).isEqualTo(testString); + assertThat(stringValue.getType()).isEqualTo(AnyValue.Type.STRING); + } + + @Test + public void boolAnyValue() { + AnyValue boolValue = AnyValue.boolAnyValue(true); + assertThat(boolValue.getBoolValue()).isTrue(); + assertThat(boolValue.getType()).isEqualTo(AnyValue.Type.BOOL); + } + + @Test + public void intAnyValue() { + int testInt = 12345; + AnyValue intValue = AnyValue.intAnyValue(testInt); + assertThat(intValue.getIntValue()).isEqualTo(testInt); + assertThat(intValue.getType()).isEqualTo(AnyValue.Type.INT); + } + + @Test + public void doubleAnyValue() { + double testDouble = 12345.0d; + AnyValue doubleValue = AnyValue.doubleAnyValue(testDouble); + assertThat(doubleValue.getDoubleValue()).isEqualTo(testDouble); + assertThat(doubleValue.getType()).isEqualTo(AnyValue.Type.DOUBLE); + } + + @Test + public void arrayAnyValue() { + String testString = "b729c730-4378-455b-8387-0f47250c3549"; + int testInt = 42; + List testList = new ArrayList<>(); + testList.add(AnyValue.stringAnyValue(testString)); + testList.add(AnyValue.intAnyValue(testInt)); + AnyValue arrayValue = AnyValue.arrayAnyValue(testList); + assertThat(arrayValue.getArrayValue()).isEqualTo(testList); + assertThat(arrayValue.getType()).isEqualTo(AnyValue.Type.ARRAY); + } + + @Test + public void kvlistAnyValue() { + String testKey = "b193ffe4-b657-4e8d-8110-b77839468389"; + AnyValue testValue = AnyValue.intAnyValue(42); + Map testMap = new HashMap<>(); + testMap.put(testKey, testValue); + AnyValue kvlistValue = AnyValue.kvlistAnyValue(testMap); + assertThat(kvlistValue.getKvlistValue()).isEqualTo(testMap); + assertThat(kvlistValue.getType()).isEqualTo(AnyValue.Type.KVLIST); + } +} diff --git a/api/src/test/java/io/opentelemetry/logs/DefaultLogRecordTest.java b/api/src/test/java/io/opentelemetry/logs/DefaultLogRecordTest.java new file mode 100644 index 00000000000..1bec70d7337 --- /dev/null +++ b/api/src/test/java/io/opentelemetry/logs/DefaultLogRecordTest.java @@ -0,0 +1,74 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * 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.opentelemetry.logs; + +import static com.google.common.truth.Truth.assertThat; + +import io.opentelemetry.common.AnyValue; +import io.opentelemetry.common.AttributeValue; +import io.opentelemetry.logs.LogRecord.Severity; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class DefaultLogRecordTest { + + @Test + public void testDefaultLogRecord() { + long testTimestamp = 123L; + byte[] testTraceId = {'a', 'b', 'c'}; + byte[] testSpanId = {'z', 'y', 'x'}; + int testFlags = 1; + Severity testSeverity = Severity.ERROR2; + String testSeverityText = "severityText"; + String testName = "an event name"; + AnyValue testBody = AnyValue.stringAnyValue("A test body"); + Map testAttributes = new HashMap<>(); + testAttributes.put("one", AttributeValue.stringAttributeValue("test1")); + testAttributes.put("two", AttributeValue.longAttributeValue(42L)); + + LogRecord.Builder builder = + new DefaultLogRecord.Builder() + .withUnixTimeNano(testTimestamp) + .withTraceId(testTraceId) + .withSpanId(testSpanId) + .withFlags(testFlags) + .withSeverity(testSeverity) + .withSeverityText(testSeverityText) + .withName(testName) + .withAttributes(testAttributes) + .withBody(testBody); + LogRecord record = builder.build(); + + assertThat(record.getTimeUnixNano()).isEqualTo(testTimestamp); + assertThat(record.getTraceId()).isEqualTo(testTraceId); + assertThat(record.getSpanId()).isEqualTo(testSpanId); + assertThat(record.getFlags()).isEqualTo(testFlags); + assertThat(record.getSeverity()).isEqualTo(testSeverity); + assertThat(record.getSeverityText()).isEqualTo(testSeverityText); + assertThat(record.getName()).isEqualTo(testName); + assertThat(record.getAttributes()).isEqualTo(testAttributes); + assertThat(record.getBody()).isEqualTo(testBody); + + LogRecord secondRecord = builder.withUnixTimeNano(456L).build(); + assertThat(secondRecord.getTimeUnixNano()).isEqualTo(456L); + assertThat(record.getTimeUnixNano()).isNotEqualTo(456L); + } +} diff --git a/api/src/test/java/io/opentelemetry/logs/LogSinkTest.java b/api/src/test/java/io/opentelemetry/logs/LogSinkTest.java new file mode 100644 index 00000000000..c3a0407b984 --- /dev/null +++ b/api/src/test/java/io/opentelemetry/logs/LogSinkTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * 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.opentelemetry.logs; + +import io.opentelemetry.OpenTelemetry; +import io.opentelemetry.common.AnyValue; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class LogSinkTest { + + @Test + public void testNoOpLogSink() { + LogSink sink = OpenTelemetry.getLogSink("tests", "0.1"); + LogRecord record = + new DefaultLogRecord.Builder() + .withUnixTimeNano(System.nanoTime()) + .withBody(AnyValue.stringAnyValue("test value")) + .build(); + sink.offer(record); + } +}