|
10 | 10 | import static java.util.Objects.requireNonNull; |
11 | 11 |
|
12 | 12 | import io.opentelemetry.api.common.AttributeKey; |
| 13 | +import io.opentelemetry.api.common.AttributeType; |
13 | 14 | import io.opentelemetry.api.common.Attributes; |
14 | 15 | import io.opentelemetry.api.trace.SpanContext; |
15 | 16 | import io.opentelemetry.sdk.common.InstrumentationScopeInfo; |
|
60 | 61 | import java.util.Locale; |
61 | 62 | import java.util.Map; |
62 | 63 | import java.util.Set; |
| 64 | +import java.util.StringJoiner; |
63 | 65 | import java.util.concurrent.ConcurrentHashMap; |
64 | 66 | import java.util.concurrent.TimeUnit; |
65 | 67 | import java.util.function.Predicate; |
@@ -472,7 +474,9 @@ private Labels convertAttributes( |
472 | 474 |
|
473 | 475 | Map<String, String> labelNameToValue = new HashMap<>(); |
474 | 476 | attributes.forEach( |
475 | | - (key, value) -> labelNameToValue.put(sanitizeLabelName(key.getKey()), value.toString())); |
| 477 | + (key, value) -> |
| 478 | + labelNameToValue.put( |
| 479 | + sanitizeLabelName(key.getKey()), toLabelValue(key.getType(), value))); |
476 | 480 |
|
477 | 481 | for (int i = 0; i < additionalAttributes.length; i += 2) { |
478 | 482 | labelNameToValue.putIfAbsent( |
@@ -642,4 +646,76 @@ private static String typeString(MetricSnapshot snapshot) { |
642 | 646 | // Simple helper for a log message. |
643 | 647 | return snapshot.getClass().getSimpleName().replace("Snapshot", "").toLowerCase(Locale.ENGLISH); |
644 | 648 | } |
| 649 | + |
| 650 | + private static String toLabelValue(AttributeType type, Object attributeValue) { |
| 651 | + switch (type) { |
| 652 | + case STRING: |
| 653 | + case BOOLEAN: |
| 654 | + case LONG: |
| 655 | + case DOUBLE: |
| 656 | + return attributeValue.toString(); |
| 657 | + case BOOLEAN_ARRAY: |
| 658 | + case LONG_ARRAY: |
| 659 | + case DOUBLE_ARRAY: |
| 660 | + case STRING_ARRAY: |
| 661 | + if (attributeValue instanceof List) { |
| 662 | + return toJsonStr((List<?>) attributeValue); |
| 663 | + } else { |
| 664 | + throw new IllegalStateException( |
| 665 | + String.format( |
| 666 | + "Unexpected label value of %s for %s", |
| 667 | + attributeValue.getClass().getName(), type.name())); |
| 668 | + } |
| 669 | + } |
| 670 | + throw new IllegalStateException("Unrecognized AttributeType: " + type); |
| 671 | + } |
| 672 | + |
| 673 | + public static String toJsonStr(List<?> attributeValue) { |
| 674 | + StringJoiner joiner = new StringJoiner(",", "[", "]"); |
| 675 | + for (int i = 0; i < attributeValue.size(); i++) { |
| 676 | + Object value = attributeValue.get(i); |
| 677 | + joiner.add(value instanceof String ? toJsonValidStr((String) value) : String.valueOf(value)); |
| 678 | + } |
| 679 | + return joiner.toString(); |
| 680 | + } |
| 681 | + |
| 682 | + public static String toJsonValidStr(String str) { |
| 683 | + StringBuilder sb = new StringBuilder(); |
| 684 | + sb.append('"'); |
| 685 | + for (int i = 0; i < str.length(); i++) { |
| 686 | + char c = str.charAt(i); |
| 687 | + |
| 688 | + switch (c) { |
| 689 | + case '"': |
| 690 | + sb.append("\\\""); |
| 691 | + break; |
| 692 | + case '\\': |
| 693 | + sb.append("\\\\"); |
| 694 | + break; |
| 695 | + case '\b': |
| 696 | + sb.append("\\b"); |
| 697 | + break; |
| 698 | + case '\f': |
| 699 | + sb.append("\\f"); |
| 700 | + break; |
| 701 | + case '\n': |
| 702 | + sb.append("\\n"); |
| 703 | + break; |
| 704 | + case '\r': |
| 705 | + sb.append("\\r"); |
| 706 | + break; |
| 707 | + case '\t': |
| 708 | + sb.append("\\t"); |
| 709 | + break; |
| 710 | + default: |
| 711 | + if (c <= 0x1F) { |
| 712 | + sb.append(String.format(Locale.ROOT, "\\u%04X", (int) c)); |
| 713 | + } else { |
| 714 | + sb.append(c); |
| 715 | + } |
| 716 | + } |
| 717 | + } |
| 718 | + sb.append('"'); |
| 719 | + return sb.toString(); |
| 720 | + } |
645 | 721 | } |
0 commit comments