

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 如何剖析 OpenTelemetry 0.7.0 訊息
<a name="CloudWatch-metric-streams-formats-opentelemetry-parse"></a>

本節提供資訊，可協助您開始剖析 OpenTelemetry 0.7.0.。

首先，您應該取得特定語言的連結，讓您能夠以偏好的語言剖析 OpenTelemetry 0.7.0 訊息。

**若要取得特定語言的連結**
+ 步驟取決於您偏好的語言。
  + 若要使用 Java，請將下列 Maven 相依性新增到您的 Java 專案： [OpenTelemetry Java >> 0.14.1](https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-proto/0.14.1)。
  + 若要使用任何其他語言，請依照下列步驟執行：

    1. 確定已支援您的語言，方法是檢查[產生您的類別](https://developers.google.com/protocol-buffers/docs/proto3#generating)的清單。

    1. 依照[下載協定緩衝區](https://developers.google.com/protocol-buffers/docs/downloads)上的步驟安裝 Protobuf 編譯器。

    1. 下載 [v0.7.0 版](https://github.com/open-telemetry/opentelemetry-proto/releases/tag/v0.7.0) OpenTelemetry 0.7.0 ProtoBuf 定義。

    1. 確認您位於已下載 OpenTelemetry 0.7.0 ProtoBuf 定義的根資料夾中。隨後依序建立 `src` 資料夾，並執行命令以產生特定語言的綁定。如需詳細資訊，請參閱[產生您的類別](https://developers.google.com/protocol-buffers/docs/proto3#generating)。

       下列是如何產生 Javascript 連結的範例。

       ```
       protoc --proto_path=./ --js_out=import_style=commonjs,binary:src \
       opentelemetry/proto/common/v1/common.proto \
       opentelemetry/proto/resource/v1/resource.proto \
       opentelemetry/proto/metrics/v1/metrics.proto \
       opentelemetry/proto/collector/metrics/v1/metrics_service.proto
       ```

下列章節包含使用特定語言的連結的範例，您可以依照先前指示建置相關連結。

**Java**

```
package com.example;

import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class MyOpenTelemetryParser {

    public List<ExportMetricsServiceRequest> parse(InputStream inputStream) throws IOException {
        List<ExportMetricsServiceRequest> result = new ArrayList<>();

        ExportMetricsServiceRequest request;
        /* A Kinesis record can contain multiple `ExportMetricsServiceRequest`
           records, each of them starting with a header with an
           UnsignedVarInt32 indicating the record length in bytes:
            ------ --------------------------- ------ -----------------------
           |UINT32|ExportMetricsServiceRequest|UINT32|pExportMetricsService...
            ------ --------------------------- ------ -----------------------
         */
        while ((request = ExportMetricsServiceRequest.parseDelimitedFrom(inputStream)) != null) {
            // Do whatever we want with the parsed message
            result.add(request);
        }

        return result;
    }
}
```

**Javascript**

此範例假設已產生連結的根資料夾為 `./`

函數的資料引數 `parseRecord` 可為下列其中一種類型：
+ `Uint8Array` 這是最佳的
+ `Buffer` 在節點下最佳
+ `Array.{{number}}` 8 位元整數

```
const pb = require('google-protobuf')
const pbMetrics =
    require('./opentelemetry/proto/collector/metrics/v1/metrics_service_pb')

function parseRecord(data) {
    const result = []

    // Loop until we've read all the data from the buffer
    while (data.length) {
        /* A Kinesis record can contain multiple `ExportMetricsServiceRequest`
           records, each of them starting with a header with an
           UnsignedVarInt32 indicating the record length in bytes:
            ------ --------------------------- ------ -----------------------
           |UINT32|ExportMetricsServiceRequest|UINT32|ExportMetricsService...
            ------ --------------------------- ------ -----------------------
         */
        const reader = new pb.BinaryReader(data)
        const messageLength = reader.decoder_.readUnsignedVarint32()
        const messageFrom = reader.decoder_.cursor_
        const messageTo = messageFrom + messageLength

        // Extract the current `ExportMetricsServiceRequest` message to parse
        const message = data.subarray(messageFrom, messageTo)

        // Parse the current message using the ProtoBuf library
        const parsed =
            pbMetrics.ExportMetricsServiceRequest.deserializeBinary(message)

        // Do whatever we want with the parsed message
        result.push(parsed.toObject())

        // Shrink the remaining buffer, removing the already parsed data
        data = data.subarray(messageTo)
    }

    return result
}
```

**Python**

您必須自行閱讀 `var-int` 分隔符或使用內部方法 `_VarintBytes(size)` 和 `_DecodeVarint32(buffer, position)`。這些傳回緩衝區中的位置恰好在大小位元組之後。讀取端可構造一個新的緩衝區，且僅限於讀取訊息的位元組。

```
size = my_metric.ByteSize()
f.write(_VarintBytes(size))
f.write(my_metric.SerializeToString())
msg_len, new_pos = _DecodeVarint32(buf, 0)
msg_buf = buf[new_pos:new_pos+msg_len]
request = metrics_service_pb.ExportMetricsServiceRequest()
request.ParseFromString(msg_buf)
```

**Go**

請使用 `Buffer.DecodeMessage()`。

**C\#**

請使用 `CodedInputStream`。該列表可以讀取以大小分隔的訊息。

**C\+\+**

`google/protobuf/util/delimited_message_util.h` 中描述的函數可以讀取以大小分隔的訊息。

**其他語言**

如需其他語言，請參閱[下載協定緩衝區](https://developers.google.com/protocol-buffers/docs/downloads)。

實作剖析器時，請考慮 Kinesis 記錄可以包含多個 `ExportMetricsServiceRequest` 協定緩衝區訊息，每個訊息都以具有 `UnsignedVarInt32` 的標題為開頭，而該標題可指示記錄長度 (以位元組為單位)。