OpenTelemetry とは？

効果的なオブザーバビリティを提供する、高品質でユビキタスなポータブルテレメトリです。

CNCF（Cloud Native Computing Foundation） のプロジェクトの OpenTracing と OpenCensus がマージされて生まれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227791/fe74489b-92a7-b07c-1932-d9ad62fcd0b9.png)

Opentelemetry は、API、SDK、およびツールのコレクションです。これらを使用してテレメトリデータ（メトリクス、ログ、トレース）を計測、生成、収集、エクスポートし、ソフトウェアのパフォーマンスと動作の分析に役立てます。

## 特徴

- トレース、メトリクス、ログ
- ライブラリやフレームワークとの統合
- オープンソース、ベンダー中立



40 以上の オブザーバビリティのベンダーにサポートされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227791/b40eac0b-469a-6f3d-a773-54619893f5d3.png)

クラウドコンピューティングやマイクロサービスアーキテクチャが主流になったことで、ビジネス要件は複雑化し、オブザーバビリティが重要視されています。オブザーバビリティとは、内部の状況を理解する能力です。

システムを監視するためには、コードがトレースやメトリクス、ログを出力する必要があります。その後、計測データはオブザーバビリティバックエンドに送信されます。

OpenTelemetry は以下の２つの処理を行います。

1. 独自のデータ形式やツールに縛られず、生成したデータを保持できる。
2. 単一の API 郡の提供。



## 構成要素

OpenTelemetry は、以下のコンポーネントで構成されています。

- テレメトリの形式を定義するプロトコル
- テレメトリのデータ型の命名規則
- テレメトリーデータを生成するための API 郡
- API 郡と テレメトリの出力をサポートする SDK
- 一般的なライブラリとフレームワークを計測できるようにするライブラリ
- コード変更なしでテレメトリーデータを生成する自動計測コンポーネント
- テレメトリーデータを受信、処理、エクスポートするプロキシである OpenTelemetry Collector
- OpenTelemetry Operator for Kubernetes, OpenTelemetry Helm Charts, Faas 向けのコミュニティアセットなど



## JavaScript (Node.js) の例

実際に、テレメトリをエクスポートする例を見てみます。例では Express が使用されています。

OpenTelemetry JavaScript は次のリポジトリで構成されています。

- [opentelemetry-js](https://github.com/open-telemetry/opentelemetry-js)、コア API と SDK を含むリポジトリ。
- [opentelemetry-js-contrib](https://github.com/open-telemetry/opentelemetry-js-contrib)、 コア以外

まずは、 `package.json` をセットアップします。

```sh
npm init -y
```

Express 関連の依存関係をインストールします。

```sh
npm install typescript \
  ts-node \
  @types/node \
  express \
  @types/express

# initialize typescript
npx tsc --init
```

普通に HTTP サーバを作成して起動してみます。

```sh
/*app.ts*/
import express, { Express } from 'express';

const PORT: number = parseInt(process.env.PORT || '8080');
const app: Express = express();

function getRandomNumber(min: number, max: number) {
  return Math.floor(Math.random() * (max - min) + min);
}

app.get('/rolldice', (req, res) => {
  res.send(getRandomNumber(1, 6).toString());
});

app.listen(PORT, () => {
  console.log(`Listening for requests on http://localhost:${PORT}`);
});
```

http://localhost:8080/rolldice にアクセスすると、動作していることが確認できます。



### OpenTelemetry を追加する

OpenTelemetry を追加するのに必要なパッケージを追加でインストールします。OpenTelemetry の Node SDK を使用します。

```sh
npm install @opentelemetry/sdk-node \
  @opentelemetry/api \
  @opentelemetry/auto-instrumentations-node \
  @opentelemetry/sdk-metrics
```

計測のセットアップは、アプリケーションのコードの実行の前に行われる必要があります。

```ts
/*instrumentation.ts*/
import { NodeSDK } from '@opentelemetry/sdk-node';
import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import {
  PeriodicExportingMetricReader,
  ConsoleMetricExporter,
} from '@opentelemetry/sdk-metrics';

const sdk = new NodeSDK({
  traceExporter: new ConsoleSpanExporter(),
  metricReader: new PeriodicExportingMetricReader({
    exporter: new ConsoleMetricExporter(),
  }),
  instrumentations: [getNodeAutoInstrumentations()],
});

sdk.start();
```

## 参考

- https://opentelemetry.io/