Repository: open-telemetry/opentelemetry-java
File: exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java (Java)

Code before:
import io.opentelemetry.exporter.internal.marshal.Serializer;
import io.opentelemetry.exporter.internal.otlp.AnyValueMarshaler;
import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler;
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 final long timeUnixNano;
  private final long observedTimeUnixNano;
  private final ProtoEnumInfo severityNumber;
  private final byte[] severityText;
  @Nullable private final MarshalerWithSize anyValueMarshaler;
  private final KeyValueMarshaler[] attributeMarshalers;
  private final int droppedAttributesCount;
  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 =
        KeyValueMarshaler.createForAttributes(logRecordData.getAttributes());

    MarshalerWithSize bodyMarshaler =
        logRecordData.getBodyValue() == null
            ? null
            : AnyValueMarshaler.create(logRecordData.getBodyValue());

    SpanContext spanContext = logRecordData.getSpanContext();
    return new LogMarshaler(
        logRecordData.getTimestampEpochNanos(),
        logRecordData.getObservedTimestampEpochNanos(),
        toProtoSeverityNumber(logRecordData.getSeverity()),
        MarshalerUtil.toBytes(logRecordData.getSeverityText()),
        bodyMarshaler,
        attributeMarshalers,
        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(),
        MarshalerUtil.toBytes(((ExtendedLogRecordData) logRecordData).getEventName()));
  }

  private LogMarshaler(

Review comment (suggestion):
from field ordering perspective, I put `eventName` at the bottom in all the proto-related files (since makes some sense to order by proto field name), and I put it at the top in other files (since makes some sense that event name is likely the first field you want to check in a log record)

Code after:
import io.opentelemetry.exporter.internal.marshal.Serializer;
import io.opentelemetry.exporter.internal.otlp.AnyValueMarshaler;
import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler;
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;
  private final ProtoEnumInfo severityNumber;
  private final byte[] severityText;
  @Nullable private final MarshalerWithSize anyValueMarshaler;
  private final KeyValueMarshaler[] attributeMarshalers;
  private final int droppedAttributesCount;
  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 =
        KeyValueMarshaler.createForAttributes(logRecordData.getAttributes());

    MarshalerWithSize bodyMarshaler =
        logRecordData.getBodyValue() == null
            ? null
            : AnyValueMarshaler.create(logRecordData.getBodyValue());

    SpanContext spanContext = logRecordData.getSpanContext();
    return new LogMarshaler(
        logRecordData.getTimestampEpochNanos(),
        logRecordData.getObservedTimestampEpochNanos(),
        toProtoSeverityNumber(logRecordData.getSeverity()),
        MarshalerUtil.toBytes(logRecordData.getSeverityText()),
        bodyMarshaler,
        attributeMarshalers,
        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(),
        logRecordData instanceof ExtendedLogRecordData
            ? MarshalerUtil.toBytes(((ExtendedLogRecordData) logRecordData).getEventName())
            : EMPTY_BYTES);