# ログAPI

> Source: https://www.ymotongpoo.com/works/otel-specs-ja/spec/logs/api/


**ステータス**: [安定（Stable）](../../document-status/)（別途明記されている箇所を除く）

ログAPIは、既存のロギングライブラリとOpenTelemetryのログデータモデルの間を橋渡しする[ログアペンダー](/works/otel-specs-ja/spec/logs/supplementary-guidelines/#how-to-create-a-log4j-log-appender)をロギングライブラリの作者が構築するために提供されています。

ログAPIは、計装ライブラリや、計装対象のライブラリ・アプリケーションから直接呼び出すこともできます。ただし、言語によっては直接使う場合により[エルゴノミックなAPI](#エルゴノミックなapi)を自由に提供できます（MAY）。

ログAPIは、次の主要なコンポーネントから構成されます。

* [LoggerProvider](#loggerprovider)はAPIのエントリーポイントです。`Logger`へのアクセスを提供します。
* [Logger](#logger)は、[LogRecord](/works/otel-specs-ja/spec/logs/data-model/#log-and-event-record-definition)としてログを発行する役割を担います。

```mermaid
graph TD
    A[LoggerProvider] -->|Get| B(Logger)
    B -->|Emit| C(LogRecord)
```

## LoggerProvider

`Logger`は`LoggerProvider`を通じてアクセスできます。

通常、`LoggerProvider`は中央の場所からアクセスされることが期待されます。したがって、APIはグローバルな既定の`LoggerProvider`を設定・登録・アクセスする手段を提供すべきです（SHOULD）。

### LoggerProviderの操作

`LoggerProvider`は次の機能を提供しなければなりません（MUST）。

* `Logger`の取得

#### Loggerの取得

このAPIは、次の[計装スコープ](/works/otel-specs-ja/spec/logs/data-model/#field-instrumentationscope)パラメータを受け付けなければなりません（MUST）。

* `name`: [計装スコープ](/works/otel-specs-ja/spec/common/instrumentation-scope/)の名前を指定します。例えば[計装ライブラリ](../../glossary/#instrumentation-library)（`io.opentelemetry.contrib.mongodb`など）、パッケージ、モジュール、クラス名などです。アプリケーションやライブラリに組み込みのOpenTelemetry計装がある場合、[計装対象ライブラリ](../../glossary/#instrumented-library)と[計装ライブラリ](../../glossary/#instrumentation-library)が同じライブラリを指すことがあります。このシナリオでは、`name`はそのライブラリまたはアプリケーション内のモジュール名またはコンポーネント名を表します。ロガー名を定義するログ発生源（Javaの[Logger Name](https://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html#getLogger(java.lang.String))など）については、そのロガー名を計装スコープ名として記録すべきです（should）。

* `version`（オプション）: 計装スコープにバージョンがある場合（ライブラリバージョンなど）、そのバージョンを指定します。値の例: 1.0.0。

* `schema_url`（オプション）: 発行されるテレメトリーに記録すべきSchema URLを指定します。

* `attributes`（オプション）: 発行されるテレメトリーに関連付ける計装スコープ属性を指定します。このAPIは、属性がまったくない場合を含め、可変数の属性を受け付けられる構造でなければなりません（MUST）。

`Logger`に対して*同一*という語を使う場合、すべてのパラメータが等しいインスタンスを指します。`Logger`に対して*異なる*という語を使う場合、少なくとも1つのパラメータの値が異なるインスタンスを指します。

## Logger

`Logger`は`LogRecord`を発行する役割を担います。

`Logger`は次の機能を提供しなければなりません（MUST）。

- [`LogRecord`の発行](#logrecordの発行)

`Logger`は次の機能を提供すべきです（SHOULD）。

- [`Logger`が`Enabled`かどうかの報告](#enabled)

### LogRecordの発行

このAPIを呼び出すことの効果は、処理パイプラインへ`LogRecord`を発行することです。

このAPIは次のパラメータを受け付けなければなりません（MUST）。

- [Timestamp](/works/otel-specs-ja/spec/logs/data-model/#field-timestamp)（オプション）
- [Observed Timestamp](/works/otel-specs-ja/spec/logs/data-model/#field-observedtimestamp)（オプション）
- `LogRecord`に関連付ける[コンテキスト](/works/otel-specs-ja/spec/context/)。暗黙のコンテキストがサポートされている場合、このパラメータはオプションであるべきで（SHOULD）、指定されなければ現在のコンテキストを使わなければなりません（MUST）。明示的なコンテキストのみがサポートされる場合、このパラメータは必須であるべきです（SHOULD）。
- [Severity Number](/works/otel-specs-ja/spec/logs/data-model/#field-severitynumber)（オプション）
- [Severity Text](/works/otel-specs-ja/spec/logs/data-model/#field-severitytext)（オプション）
- [Body](/works/otel-specs-ja/spec/logs/data-model/#field-body)（オプション）
- [Attributes](/works/otel-specs-ja/spec/logs/data-model/#field-attributes)（オプション）
- [Event Name](/works/otel-specs-ja/spec/logs/data-model/#field-eventname)（オプション）

このAPIは次のパラメータを受け付けてもよい（MAY）です。

- Exception（オプション）: LogRecordに関連付けられる例外（またはエラー）。

### Enabled

`LogRecord`を生成する際に計算コストの高い処理を実行することをユーザーが避けられるようにするため、`Logger`はこの`Enabled` APIを提供すべきです（SHOULD）。

このAPIは次のパラメータを受け付けるべきです（SHOULD）。

- `LogRecord`に関連付ける[コンテキスト](/works/otel-specs-ja/spec/context/)。暗黙のコンテキストがサポートされている場合、このパラメータはオプションであるべきで（SHOULD）、指定されなければ現在のコンテキストを使わなければなりません（MUST）。明示的なコンテキストのみがサポートされる場合、このパラメータを受け付けることが必須です（REQUIRED）。
- [Severity Number](/works/otel-specs-ja/spec/logs/data-model/#field-severitynumber)（オプション）
- [Event Name](/works/otel-specs-ja/spec/logs/data-model/#field-eventname)（オプション）

このAPIは、言語に慣用的なブーリアン型を返さなければなりません（MUST）。返される値が`true`であれば、指定された引数に対して`Logger`が有効であることを意味し、`false`であれば`Logger`が無効であることを意味します。

APIのドキュメントには、`Enabled`の呼び出しは任意であり、[`LogRecord`の発行](#logrecordの発行)の前に必須ではないことを記載すべきです（SHOULD）。これは、`LogRecord`の構築が高コストな場合、例えばそのbodyや属性をデータベースから取得した値から計算しなければならない場合にのみ関係する、パフォーマンス上の最適化です。そうした場合、計装は先に`Enabled`を呼び出し、`false`が返されればその処理をスキップできます。`LogRecord`の構築が低コストな場合、計装は直接発行できます。ドキュメントにはまた、返される値は静的ではなく時間の経過とともに変化し得るため、キャッシュした値が古くなる可能性があることも記載すべきです（SHOULD）。

## オプションパラメータと必須パラメータ

定義された操作にはさまざまなパラメータが含まれ、その一部はオプションと表示されています。オプションと表示されていないパラメータは必須です。

オプションパラメータそれぞれについて、APIはそれを受け付けられる構造でなければなりません（MUST）が、ユーザーに指定を義務付けてはなりません（MUST NOT）。

必須パラメータそれぞれについて、APIはユーザーに指定を義務付ける構造でなければなりません（MUST）。

## 並行処理に関する要件

並行実行をサポートする言語では、ログAPIは特定の保証と安全性を提供します。

**LoggerProvider** - すべてのメソッドについて、実装が既定で並行使用に対して安全である必要があることをドキュメント化しなければなりません（MUST）。

**Logger** - すべてのメソッドについて、実装が既定で並行使用に対して安全である必要があることをドキュメント化しなければなりません（MUST）。

## エルゴノミックなAPI

**ステータス**: [開発中（Development）](../../document-status/)

言語は、より使いやすく便利なロギングAPIを追加で提供してもよい（MAY）です。

エルゴノミックなAPIは、[イベントの意味論](/works/otel-specs-ja/semconv/general/events/)に従うイベントレコードの発行をより便利にすべきです（SHOULD）。

エルゴノミックなAPIの設計は、その言語にとって慣用的であるべきです（SHOULD）。

## 参考文献

- [OTEP0150 ロギングライブラリSDKプロトタイプ仕様](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/oteps/logs/0150-logging-library-sdk.md)

