Repository: open-telemetry/opentelemetry-java
File: exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java (Java)

Code before:
    SpanContext spanContext = exemplar.getSpanContext();
    if (spanContext.isValid()) {
      return new Exemplar(
          value,
          convertAttributes(
              null, // resource attributes are only copied for point's attributes
              null, // scope attributes are only needed for point's attributes
              exemplar.getFilteredAttributes(),
              "trace_id",
              spanContext.getTraceId(),
              "span_id",
              spanContext.getSpanId()),
          exemplar.getEpochNanos() / NANOS_PER_MILLISECOND);
    } else {
      return new Exemplar(
          value,
          convertAttributes(
              null, // resource attributes are only copied for point's attributes
              null, // scope attributes are only needed for point's attributes
              exemplar.getFilteredAttributes()),
          exemplar.getEpochNanos() / NANOS_PER_MILLISECOND);
    }
  }

  private InfoSnapshot makeTargetInfo(Resource resource) {
    return new InfoSnapshot(
        new MetricMetadata("target"),
        Collections.singletonList(
            new InfoDataPointSnapshot(
                convertAttributes(
                    null, // resource attributes are only copied for point's attributes
                    null, // scope attributes are only needed for point's attributes
                    resource.getAttributes()))));
  }

  private InfoSnapshot makeScopeInfo(Set<InstrumentationScopeInfo> scopes) {
    List<InfoDataPointSnapshot> prometheusScopeInfos = new ArrayList<>(scopes.size());
    for (InstrumentationScopeInfo scope : scopes) {
      prometheusScopeInfos.add(
          new InfoDataPointSnapshot(
              convertAttributes(
                  null, // resource attributes are only copied for point's attributes
                  scope,
                  scope.getAttributes())));
    }
    return new InfoSnapshot(new MetricMetadata("otel_scope"), prometheusScopeInfos);
  }

  /**
   * Convert OpenTelemetry attributes to Prometheus labels.
   *

Review comment (suggestion):
```suggestion
   * @param scope will be converted to {@code otel_scope_*} labels if ...
```

Code after:
      return new Exemplar(
          value,
          convertAttributes(
              null, // resource attributes are only copied for point's attributes
              null, // scope attributes are only needed for point's attributes
              exemplar.getFilteredAttributes()),
          exemplar.getEpochNanos() / NANOS_PER_MILLISECOND);
    }
  }

  private InfoSnapshot makeTargetInfo(Resource resource) {
    return new InfoSnapshot(
        new MetricMetadata("target"),
        Collections.singletonList(
            new InfoDataPointSnapshot(
                convertAttributes(
                    null, // resource attributes are only copied for point's attributes
                    null, // scope attributes are only needed for point's attributes
                    resource.getAttributes()))));
  }

  /**
   * Convert OpenTelemetry attributes to Prometheus labels.
   *
   * @param resource optional resource (attributes) to be converted.
   * @param scope will be converted to {@code otel_scope_*} labels.
   * @param attributes the attributes to be converted.
   * @param additionalAttributes optional list of key/value pairs, may be empty.
   */
  @SuppressWarnings({"rawtypes", "unchecked"})
  private Labels convertAttributes(
      @Nullable Resource resource,
      @Nullable InstrumentationScopeInfo scope,
      Attributes attributes,
      String... additionalAttributes) {

    List<AttributeKey<?>> allowedAttributeKeys =
        allowedResourceAttributesFilter != null
            ? filterAllowedResourceAttributeKeys(resource)
            : Collections.emptyList();

    Map<String, String> labelNameToValue = new HashMap<>();
    attributes.forEach(
        (key, value) ->
            labelNameToValue.put(
                sanitizeLabelName(key.getKey()), toLabelValue(key.getType(), value)));

    for (int i = 0; i < additionalAttributes.length; i += 2) {
      labelNameToValue.putIfAbsent(
          requireNonNull(additionalAttributes[i]), additionalAttributes[i + 1]);
    }