

# OpenTelemetry 0.7.0 메시지를 구문 분석하는 방법
<a name="CloudWatch-metric-streams-formats-opentelemetry-parse"></a>

이 단원에서는 OpenTelemetry 0.7.0의 구문 분석을 시작하는 데 도움이 되는 정보를 제공합니다.

먼저, 언어별 바인딩을 가져와야 합니다. 그러면 이 바인딩을 통해 원하는 언어로 OpenTelemetry 0.7.0 메시지를 구문 분석할 수 있습니다.

**언어별 바인딩을 가져오려면**
+ 단계는 원하는 언어에 따라 다릅니다.
  + Java를 사용하려면 Java 프로젝트에 다음 Maven 종속 항목을 추가합니다. [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. [Protocol Buffers 다운로드](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 바이트 바로 뒤에 있는 버퍼의 위치를 ​​반환합니다. 읽기 측에서는 메시지의 바이트만 읽는 것으로 제한되는 새 버퍼를 생성합니다.

```
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`에 기술된 함수는 크기로 구분된 메시지를 읽을 수 있습니다.

**기타 언어**

기타 언어의 경우 [Protocol Buffers 다운로드](https://developers.google.com/protocol-buffers/docs/downloads)를 참조하세요.

구문 분석기를 구현할 때 Kinesis 레코드에 여러 `ExportMetricsServiceRequest` Protocol Buffers 메시지가 포함될 수 있다는 점을 고려하세요. 각 메시지는 바이트 단위의 레코드 길이를 나타내는 `UnsignedVarInt32`가 있는 헤더로 시작합니다.