MySQL Telemetry ログ

OpenTelemetryは、可観測性を保ってデータを転送するための標準仕様です。MySQLはすでに、OpenTelemetry のトレース (Traces) とメトリクス (Metrics) への対応を提供してきました。そしてMySQL 9.1以降、OpenTelemetryの残された仕様であるログ (Logging) への対応を提供しています。OpenTelemetryは、トレース・メトリクス・ログを含むテレメトリ・データを生成・収集・エクスポートするための標準化された仕組みを提供します。この標準を採用することで、MySQLのユーザーはデータベースや接続されているアプリケーション、そしてMySQLが動作しているシステムについて、より深い洞察を得られるようになります。

OpenTelemetry: ログ

2024年前半には、ログ用のAPIは開発段階から安定版のステータスへ移行しました。OpenTelemetryのログサポートは、異なるアプリケーションやシステムを横断してログデータを収集し、関連付ける標準化された手段を提供します。これにより、ログをトレースやメトリクスと結び付けられるようになります。システム動作の分析にあたってより多くのコンテキストを取得できるようになって、トラブルシューティングが容易になり、可観測性が向上します。また、Cloud Native Compute Foundation (CNCF) 標準に従ってログを収集・エクスポートできます。

MySQL と OpenTelemetry

MySQLはOpenTelemetry仕様に対応し、データベースからトレース、メトリクス、ログを収集し、相互を関連付けできるようにしました。この統合によって、以下のことが可能となります:

  • リクエストのトレース: システム全体でリクエストの経路を追跡し、ボトルネックやパフォーマンス上の問題を特定できます。

    • 8.4 LTS および 9.x イノベーション・リリースで利用できます。

  • メトリクスのモニタリング: クエリの実行時間、エラー率、リソース使用率などの、重要なパフォーマンス指標を追跡できます。

    • 8.4 LTS および 9.x イノベーション・リリースで利用できます。

  • ログの相互関連付け: ログメッセージを特定のトレースやメトリクスと関連付け、トラブルシューティングに役立つより詳しいコンテキストを提供できます。

    • 9.1 イノベーションリリースから利用できます。

テレメトリデータの関連付け

OpenTelemetryは、以下の属性を用いてトレース、メトリクス、ログの相互関連付けをサポートしています:

  • 実行時刻: 生成された時刻に基づいてデータをそろえます。
  • 実行コンテキスト: トレースIDやスパンIDを用いて、特定のリクエストやオペレーションにデータを関連付けます。
  • テレメトリの発生元: 特定のサービスやコンポーネントなど、データがどこから来たのかを識別します。

これらの相関手法をうまく活用すると、システムの動作を包括的に理解でき、問題の素早い特定と解決が実現できます。

MySQL を用いた OpenTelemetry のスケール

大規模な MySQL データベースの導入に、OpenTelemetryは特に適しています。安全なプッシュベースのモデルを使うことで、特権アクセス権限を必要とせずに、数千ものデータベースからテレメトリデータを収集できます。

OpenTelemetry Collector をログエージェントとして用いる

OpenTelemetry Collectorは、MySQLを含むさまざまなソースから、ログデータを効率的に収集・処理できる汎用ミドルウェアです。OpenTelemetryのロギング標準を使用することで、ログデータの収集とエクスポートを合理化できます。

MySQL レシーバーから Otel Collector へ

Direct-to-Collector アプローチ

direct-to-collector アプローチ (コレクターに直接送信するアプローチ) を採用することで、ログエージェントが不要となり、ログ収集が簡素化されます。MySQLは構造化された形式でログデータをOpenTelemetry Collectorに直接送信できるため、パフォーマンスが向上し、オーバーヘッドが削減されます。他にもアプローチはいくつかありますが、ここではシンプルに Direct-to-Collector に焦点を当てています。

次のような利点が期待できます:

  • ログ管理の簡素化: 複雑なログ解析やテール処理が不要です。
  • パフォーマンス向上: ログ収集エージェントによるオーバーヘッドを削減します。
  • セキュリティ強化: セキュアなコレクターへのログの直接送信を実現します。
  • 柔軟性の向上: OpenTelemetryパイプラインを用いて、データ処理とルーティングをカスタマイズできます。

これらの手法の実装を通じて、OpenTelemetryの潜在能力は最大限に活用され、MySQLの導入環境を最適化しつつ、正確なデータに基づく判断を下せるようになります。

OpenTelemetry Collector: レシーバー

MySQLはOpenTelemetry APIを採用しているため、YAMLでのレシーバー設定には標準の設定ファイルをそのまま使えます。デフォルト設定のみで十分であり、特別に追加やカスタマイズは必要ありません。

receivers:
  otlp:
    protocols:
      http:

OpenTelemetry Collector: エクスポーター

次に、テレメトリデータの出力先(ターゲット)を定義します。つまり、データを「どこに」エクスポートするのかという詳細についての設定です。たとえば、otlpでのlogエンドポイントへ出力するには、下記のような設定になります。

exporters:
  otlp:
    endpoint: "<an ip>:443"
    headers:
      secret: "YOUR_API_KEY"
      <other headers>: "W"

出力される値は、OpenTelemetryをネイティブにサポートし、OTLP形式のデータを受け取れるバックエンドアプリケーションで取得できます。

開発者向けには、ローカルのJSONファイルを出力にするようなシンプルな構成も設定できます。例としては以下のとおりです。

exporters:
  file/log:
    path: /Users/developer/otel/errorlog.json
    rotation:
      max_megabytes: 10
      max_days: 3
      max_backups: 3
      localtime: true

複数のエクスポート先へデータを出力したり、OpenTelemetry Collector プロセッサーを介してルーティングすることもできます。

OpenTelemetry Collector: パイプライン

最後に、サービスパイプラインを定義します。以下の例では、ログパイプラインがOTLP経由で受信したログデータを受け取り、標準のバッチプロセッサを使用します。このバッチプロセッサは効率向上に役立ち、さらにカスタマイズもできます。

service:
  pipelines:
    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [file/log]

MySQL Telemetryコンポーネントのインストール

デフォルトでは、MySQL Server でテレメトリは有効化されていませんが、コンポーネントの追加は非常に簡単です。

クライアントで MySQLサーバーに接続し、以下を実行します:

mysql> INSTALL COMPONENT 'file://component_telemetry';

デフォルトのテレメトリ・トレースコンポーネントの設定は、以下で確認できます:

mysql> SHOW VARIABLES LIKE '%telemetry%';

デフォルトでは、インストールされたテレメトリ・ログはローカルのOpenTelemetry Collectorに接続するような設定となっています。

OpenTelemetry Collectorの実行

上記の例に従って OpenTelemetry Collectorを実行すると、ログデータはfile/logの設定、つまり /Users/developer/otel/errorlog.json へ送られます。

./otelcol --config=./configlog.yaml

環境が整えばテストとして、ログイン時に誤ったパスワードを入力してみてください。

そうすると、JSON ログ形式でエラーイベントが生成され、完全なコンテキスト情報が付与されます。

出力されたログデータの例

ビデオ説明とデモ

ビデオ説明とデモについては、こちらをご覧ください。(訳者註: 翻訳時現在、こちらのリンク先ビデオは削除されております)

まとめ

OpenTelemetryとそれが提供する、テレメトリデータ(トレース、メトリクス、ログ)を収集し、相互関連付けする標準化された手法を用いれば、MySQLが導入されたシステムの環境を包括的に把握できます。

この深められたインサイトにより、次のことが可能になります:

  • パフォーマンスの最適化: ボトルネックを特定し、MySQLデータベースの改善点を絞り込む。
  • トラブルシューティングの簡素化: ログをトレースやメトリクスと関連付けて、問題の原因を迅速に診断・解決する。
  • セキュリティの強化: 特権アクセスを不要にする安全なプッシュ型のデータ収集モデルを活用する。
  • 効率的なスケーリング: 数千ものMySQLデータベースが存在する大規模な導入でも、テレメトリデータを効率的に管理し貴重なインサイトを得る。

さらにOpenTelemetry Collectorはデータ処理とルーティングの柔軟性を備え、可観測性のパイプラインの合理化を促進します。

いつもMySQLをご利用いただきありがとうございます!

関連するリンク:

OpenTelemetry Collector がJSONでファイル出力したイベント例

{
  "resourceLogs": [
    {
      "resource": {
        "attributes": [
          {
            "key": "telemetry.sdk.language",
            "value": {
              "stringValue": "cpp"
            }
          },
          {
            "key": "service.namespace",
            "value": {
              "stringValue": "mysql"
            }
          },
          {
            "key": "service.instance.id",
            "value": {
              "stringValue": "developer-mac:28511"
            }
          },
          {
            "key": "telemetry.sdk.name",
            "value": {
              "stringValue": "opentelemetry"
            }
          },
          {
            "key": "service.name",
            "value": {
              "stringValue": "mysqld"
            }
          },
          {
            "key": "service.version",
            "value": {
              "stringValue": "9.1.0"
            }
          },
          {
            "key": "telemetry.sdk.version",
            "value": {
              "stringValue": "1.15.0"
            }
          }
        ]
      },
      "scopeLogs": [
        {
          "scope": {
            "name": "1.0.0"
          },
          "logRecords": [
            {
              "timeUnixNano": "1734458944000000000",
              "observedTimeUnixNano": "1734458944772071000",
              "severityNumber": 9,
              "severityText": "INFO",
              "body": {
                "stringValue": "Access denied for user 'root'@'localhost' (using password: YES)"
              },
              "attributes": [
                {
                  "key": "mysql.event_name",
                  "value": {
                    "stringValue": "logger/error/error_log"
                  }
                },
                {
                  "key": "err_code",
                  "value": {
                    "intValue": "10926"
                  }
                },
                {
                  "key": "err_symbol",
                  "value": {
                    "stringValue": "ER_ACCESS_DENIED_ERROR_WITH_PASSWORD"
                  }
                },
                {
                  "key": "SQL_state",
                  "value": {
                    "stringValue": "HY000"
                  }
                },
                {
                  "key": "thread",
                  "value": {
                    "intValue": "12"
                  }
                },
                {
                  "key": "source_file",
                  "value": {
                    "stringValue": "sql_authentication.cc"
                  }
                },
                {
                  "key": "source_line",
                  "value": {
                    "intValue": "1658"
                  }
                },
                {
                  "key": "function",
                  "value": {
                    "stringValue": "login_failed_error"
                  }
                },
                {
                  "key": "component",
                  "value": {
                    "stringValue": "sha256_password"
                  }
                },
                {
                  "key": "subsystem",
                  "value": {
                    "stringValue": "Server"
                  }
                }
              ],
              "traceId": "",
              "spanId": ""
            }
          ]
        }
      ],
      "schemaUrl": "http://mysql.com/telemetry/schema/1.0.0"
    }
  ]
}