Skip to content

Commit

Permalink
Add event name as an incubating feature (#7012)
Browse files Browse the repository at this point in the history
Co-authored-by: jack-berg <[email protected]>
  • Loading branch information
trask and jack-berg authored Jan 16, 2025
1 parent 2fb3eba commit 97410cb
Show file tree
Hide file tree
Showing 25 changed files with 336 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
class ExtendedDefaultLogger implements ExtendedLogger {

private static final Logger INSTANCE = new ExtendedDefaultLogger();
private static final LogRecordBuilder NOOP_LOG_RECORD_BUILDER = new NoopLogRecordBuilder();
private static final ExtendedLogRecordBuilder NOOP_LOG_RECORD_BUILDER =
new NoopExtendedLogRecordBuilder();

private ExtendedDefaultLogger() {}

Expand All @@ -26,13 +27,18 @@ static Logger getNoop() {
}

@Override
public LogRecordBuilder logRecordBuilder() {
public ExtendedLogRecordBuilder logRecordBuilder() {
return NOOP_LOG_RECORD_BUILDER;
}

private static final class NoopLogRecordBuilder implements ExtendedLogRecordBuilder {
private static final class NoopExtendedLogRecordBuilder implements ExtendedLogRecordBuilder {

private NoopLogRecordBuilder() {}
private NoopExtendedLogRecordBuilder() {}

@Override
public ExtendedLogRecordBuilder setEventName(String eventName) {
return this;
}

@Override
public LogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
/** Extended {@link LogRecordBuilder} with experimental APIs. */
public interface ExtendedLogRecordBuilder extends LogRecordBuilder {

// Nothing at the moment, but experimental methods may be added in the future.
// keep this class even if it is empty, since experimental methods may be added in the future.

/**
* Sets the event name, which identifies the class / type of the Event.
*
* <p>This name should uniquely identify the event structure (both attributes and body). A log
* record with a non-empty event name is an Event.
*/
ExtendedLogRecordBuilder setEventName(String eventName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ public interface ExtendedLogger extends Logger {
default boolean isEnabled() {
return true;
}

@Override
ExtendedLogRecordBuilder logRecordBuilder();
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ void buildAndEmit() {
() ->
getLogger()
.logRecordBuilder()
// TODO (trask) once event name stabilizes
// .setEventName("event name")
.setTimestamp(100, TimeUnit.SECONDS)
.setTimestamp(Instant.now())
.setObservedTimestamp(100, TimeUnit.SECONDS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.logs.TestLogRecordData;
import io.opentelemetry.sdk.testing.logs.internal.TestExtendedLogRecordData;
import io.opentelemetry.sdk.testing.trace.TestSpanData;
import io.opentelemetry.sdk.trace.data.EventData;
import io.opentelemetry.sdk.trace.data.SpanData;
Expand All @@ -47,13 +48,14 @@ abstract class TestDataExporter<T> {
Resource.create(Attributes.builder().put("key", "value").build());

private static final LogRecordData LOG1 =
TestLogRecordData.builder()
TestExtendedLogRecordData.builder()
.setResource(RESOURCE)
.setInstrumentationScopeInfo(
InstrumentationScopeInfo.builder("instrumentation")
.setVersion("1")
.setAttributes(Attributes.builder().put("key", "value").build())
.build())
.setEventName("event name")
.setBody("body1")
.setSeverity(Severity.INFO)
.setSeverityText("INFO")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
},
"logRecords": [
{
"eventName": "event name",
"timeUnixNano": "100",
"observedTimeUnixNano": "200",
"severityNumber": 9,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
},
"logRecords": [
{
"eventName": "event name",
"timeUnixNano": "100",
"observedTimeUnixNano": "200",
"severityNumber": 9,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
import io.opentelemetry.proto.logs.v1.internal.LogRecord;
import io.opentelemetry.proto.logs.v1.internal.SeverityNumber;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.logs.data.internal.ExtendedLogRecordData;
import java.io.IOException;
import javax.annotation.Nullable;

final class LogMarshaler extends MarshalerWithSize {
private static final String INVALID_TRACE_ID = TraceId.getInvalid();
private static final String INVALID_SPAN_ID = SpanId.getInvalid();
private static final byte[] EMPTY_BYTES = new byte[0];

private final long timeUnixNano;
private final long observedTimeUnixNano;
Expand All @@ -36,6 +38,7 @@ final class LogMarshaler extends MarshalerWithSize {
private final TraceFlags traceFlags;
@Nullable private final String traceId;
@Nullable private final String spanId;
private final byte[] eventName;

static LogMarshaler create(LogRecordData logRecordData) {
KeyValueMarshaler[] attributeMarshalers =
Expand All @@ -57,7 +60,10 @@ static LogMarshaler create(LogRecordData logRecordData) {
logRecordData.getTotalAttributeCount() - logRecordData.getAttributes().size(),
spanContext.getTraceFlags(),
spanContext.getTraceId().equals(INVALID_TRACE_ID) ? null : spanContext.getTraceId(),
spanContext.getSpanId().equals(INVALID_SPAN_ID) ? null : spanContext.getSpanId());
spanContext.getSpanId().equals(INVALID_SPAN_ID) ? null : spanContext.getSpanId(),
logRecordData instanceof ExtendedLogRecordData
? MarshalerUtil.toBytes(((ExtendedLogRecordData) logRecordData).getEventName())
: EMPTY_BYTES);
}

private LogMarshaler(
Expand All @@ -70,7 +76,8 @@ private LogMarshaler(
int droppedAttributesCount,
TraceFlags traceFlags,
@Nullable String traceId,
@Nullable String spanId) {
@Nullable String spanId,
byte[] eventName) {
super(
calculateSize(
timeUnixNano,
Expand All @@ -82,7 +89,8 @@ private LogMarshaler(
droppedAttributesCount,
traceFlags,
traceId,
spanId));
spanId,
eventName));
this.timeUnixNano = timeUnixNano;
this.observedTimeUnixNano = observedTimeUnixNano;
this.traceId = traceId;
Expand All @@ -93,6 +101,7 @@ private LogMarshaler(
this.anyValueMarshaler = anyValueMarshaler;
this.attributeMarshalers = attributeMarshalers;
this.droppedAttributesCount = droppedAttributesCount;
this.eventName = eventName;
}

@Override
Expand All @@ -115,6 +124,8 @@ protected void writeTo(Serializer output) throws IOException {
output.serializeByteAsFixed32(LogRecord.FLAGS, traceFlags.asByte());
output.serializeTraceId(LogRecord.TRACE_ID, traceId);
output.serializeSpanId(LogRecord.SPAN_ID, spanId);

output.serializeString(LogRecord.EVENT_NAME, eventName);
}

private static int calculateSize(
Expand All @@ -127,7 +138,8 @@ private static int calculateSize(
int droppedAttributesCount,
TraceFlags traceFlags,
@Nullable String traceId,
@Nullable String spanId) {
@Nullable String spanId,
byte[] eventName) {
int size = 0;
size += MarshalerUtil.sizeFixed64(LogRecord.TIME_UNIX_NANO, timeUnixNano);

Expand All @@ -147,6 +159,8 @@ private static int calculateSize(
size += MarshalerUtil.sizeByteAsFixed32(LogRecord.FLAGS, traceFlags.asByte());
size += MarshalerUtil.sizeTraceId(LogRecord.TRACE_ID, traceId);
size += MarshalerUtil.sizeSpanId(LogRecord.SPAN_ID, spanId);

size += MarshalerUtil.sizeBytes(LogRecord.EVENT_NAME, eventName);
return size;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler;
import io.opentelemetry.proto.logs.v1.internal.LogRecord;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.logs.data.internal.ExtendedLogRecordData;
import java.io.IOException;

/** See {@link LogMarshaler}. */
Expand Down Expand Up @@ -55,6 +56,10 @@ public void writeTo(Serializer output, LogRecordData log, MarshalerContext conte
if (!spanContext.getSpanId().equals(INVALID_SPAN_ID)) {
output.serializeSpanId(LogRecord.SPAN_ID, spanContext.getSpanId(), context);
}
if (log instanceof ExtendedLogRecordData) {
output.serializeStringWithContext(
LogRecord.EVENT_NAME, ((ExtendedLogRecordData) log).getEventName(), context);
}
}

@Override
Expand Down Expand Up @@ -93,6 +98,12 @@ public int getBinarySerializedSize(LogRecordData log, MarshalerContext context)
size += MarshalerUtil.sizeSpanId(LogRecord.SPAN_ID, spanContext.getSpanId());
}

if (log instanceof ExtendedLogRecordData) {
size +=
StatelessMarshalerUtil.sizeStringWithContext(
LogRecord.EVENT_NAME, ((ExtendedLogRecordData) log).getEventName(), context);
}

return size;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.logs.TestLogRecordData;
import io.opentelemetry.sdk.testing.logs.internal.TestExtendedLogRecordData;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
Expand All @@ -52,14 +52,15 @@ class LogsRequestMarshalerTest {
private static final String TRACE_ID = TraceId.fromBytes(TRACE_ID_BYTES);
private static final byte[] SPAN_ID_BYTES = new byte[] {0, 0, 0, 0, 4, 3, 2, 1};
private static final String SPAN_ID = SpanId.fromBytes(SPAN_ID_BYTES);
private static final String EVENT_NAME = "hello";
private static final String BODY = "Hello world from this log...";

@Test
void toProtoResourceLogs() {
ResourceLogsMarshaler[] resourceLogsMarshalers =
ResourceLogsMarshaler.create(
Collections.singleton(
TestLogRecordData.builder()
TestExtendedLogRecordData.builder()
.setResource(
Resource.builder().put("one", 1).setSchemaUrl("http://url").build())
.setInstrumentationScopeInfo(
Expand All @@ -68,6 +69,7 @@ void toProtoResourceLogs() {
.setSchemaUrl("http://url")
.setAttributes(Attributes.builder().put("key", "value").build())
.build())
.setEventName(EVENT_NAME)
.setBody(BODY)
.setSeverity(Severity.INFO)
.setSeverityText("INFO")
Expand Down Expand Up @@ -108,11 +110,12 @@ void toProtoLogRecord(MarshalerSource marshalerSource) {
parse(
LogRecord.getDefaultInstance(),
marshalerSource.create(
TestLogRecordData.builder()
TestExtendedLogRecordData.builder()
.setResource(
Resource.create(Attributes.builder().put("testKey", "testValue").build()))
.setInstrumentationScopeInfo(
InstrumentationScopeInfo.builder("instrumentation").setVersion("1").build())
.setEventName(EVENT_NAME)
.setBody(BODY)
.setSeverity(Severity.INFO)
.setSeverityText("INFO")
Expand All @@ -128,6 +131,7 @@ void toProtoLogRecord(MarshalerSource marshalerSource) {
assertThat(logRecord.getTraceId().toByteArray()).isEqualTo(TRACE_ID_BYTES);
assertThat(logRecord.getSpanId().toByteArray()).isEqualTo(SPAN_ID_BYTES);
assertThat(logRecord.getSeverityText()).isEqualTo("INFO");
assertThat(logRecord.getEventName()).isEqualTo(EVENT_NAME);
assertThat(logRecord.getBody()).isEqualTo(AnyValue.newBuilder().setStringValue(BODY).build());
assertThat(logRecord.getAttributesList())
.containsExactly(
Expand All @@ -147,7 +151,7 @@ void toProtoLogRecord_MinimalFields(MarshalerSource marshalerSource) {
parse(
LogRecord.getDefaultInstance(),
marshalerSource.create(
TestLogRecordData.builder()
TestExtendedLogRecordData.builder()
.setResource(
Resource.create(Attributes.builder().put("testKey", "testValue").build()))
.setInstrumentationScopeInfo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.logs.TestLogRecordData;
import io.opentelemetry.sdk.testing.logs.internal.TestExtendedLogRecordData;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
Expand All @@ -39,6 +39,7 @@ class LowAllocationLogRequestMarshalerTest {
AttributeKey.doubleArrayKey("key_double_array");
private static final AttributeKey<List<Boolean>> KEY_BOOLEAN_ARRAY =
AttributeKey.booleanArrayKey("key_boolean_array");
private static final String EVENT_NAME = "hello";
private static final String BODY = "Hello world from this log...";

private static final Resource RESOURCE =
Expand Down Expand Up @@ -72,9 +73,10 @@ private static List<LogRecordData> createLogRecordDataList() {
}

private static LogRecordData createLogRecordData() {
return TestLogRecordData.builder()
return TestExtendedLogRecordData.builder()
.setResource(RESOURCE)
.setInstrumentationScopeInfo(INSTRUMENTATION_SCOPE_INFO)
.setEventName(EVENT_NAME)
.setBody(BODY)
.setSeverity(Severity.INFO)
.setSeverityText("INFO")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -648,8 +648,9 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) {
TraceFlags.getDefault(),
TraceState.getDefault());

try (Scope unused = Span.wrap(spanContext).makeCurrent()) {
try (Scope ignored = Span.wrap(spanContext).makeCurrent()) {
((ExtendedLogRecordBuilder) logger.logRecordBuilder())
.setEventName("event name")
.setBody(
of(
KeyValue.of("str_key", of("value")),
Expand Down Expand Up @@ -699,6 +700,7 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) {

// LogRecord via Logger.logRecordBuilder()...emit()
io.opentelemetry.proto.logs.v1.LogRecord protoLog1 = ilLogs.getLogRecords(0);
assertThat(protoLog1.getEventName()).isEqualTo("event name");
assertThat(protoLog1.getBody())
.isEqualTo(
AnyValue.newBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ final class ExtendedSdkLogRecordBuilder extends SdkLogRecordBuilder
super(loggerSharedState, instrumentationScopeInfo);
}

@Override
public ExtendedSdkLogRecordBuilder setEventName(String eventName) {
super.setEventName(eventName);
return this;
}

@Override
public ExtendedSdkLogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) {
super.setTimestamp(timestamp, unit);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package io.opentelemetry.sdk.logs;

import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
import io.opentelemetry.api.incubator.logs.ExtendedLogger;
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.logs.internal.LoggerConfig;
Expand All @@ -26,4 +27,9 @@ final class ExtendedSdkLogger extends SdkLogger implements ExtendedLogger {
public boolean isEnabled() {
return loggerEnabled;
}

@Override
public ExtendedLogRecordBuilder logRecordBuilder() {
return (ExtendedLogRecordBuilder) super.logRecordBuilder();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ default ReadWriteLogRecord setAllAttributes(Attributes attributes) {
/** Return an immutable {@link LogRecordData} instance representing this log record. */
LogRecordData toLogRecordData();

// TODO (trask) once event name stabilizes, add getEventName()

/**
* Returns the value of a given attribute if it exists. This is the equivalent of calling {@code
* getAttributes().get(key)}.
Expand Down
Loading

0 comments on commit 97410cb

Please sign in to comment.