カスタム OpenMetrics チェック

概要

ここでは、Kong からタイミングメトリクスとステータスイベントを収集する簡単なチェックを例に挙げて、OpenMetricsBaseCheckV2 インターフェイスの高度な使用方法について説明します。基本的な OpenMetrics チェックの構成について、詳しくは Kubernetes Prometheus および OpenMetrics メトリクスの収集を参照してください。

: OpenMetricsBaseCheckV2 は Agent v7.26.x+ で利用可能で、Python 3 が必要です。

レガシー実装または OpenMetricsBaseCheck インターフェイスのカスタムチェックガイドをお探しの場合は、Custom Legacy OpenMetrics Check をご覧ください。

高度な使用方法: OpenMetrics チェックインターフェイス

汎用のチェックより高度なチェック (メトリクスの前処理など) が必要な場合は、カスタム OpenMetricsBaseCheckV2 を作成してください。これは汎用チェックの基本クラスです。Prometheus で公開されるメトリクス、イベント、サービスチェックを収集するための構造とヘルパーを提供します。このクラスに基づいてチェックを構成するには、少なくとも以下が必要です。

  • namespacemetrics マッピングを使用したデフォルトインスタンスの作成。
  • check() メソッドの実装および/または
  • 処理される OpenMetric メトリクスの名前を付けたメソッドの作成 (例: self.prometheus_metric_name)

Prometheus メトリクスである kong_upstream_target_health の値をサービスチェックとして使用しているこの Kong インテグレーションの例をご覧ください。

カスタム OpenMetrics チェックの書き方

ここでは、簡単な Kong チェックの記述例を示して、OpenMetricsBaseCheckV2 クラスの使用方法について説明します。次の例は、以下の汎用 Openmetrics チェックの機能を再現します。

instances:
  - openmetrics_endpoint: http://localhost:8001/status/
    namespace: "kong"
    metrics:
      - kong_bandwidth: bandwidth
      - kong_http_consumer_status: http.consumer.status
      - kong_http_status: http.status
      - kong_latency:
          name: latency
          type: counter
      - kong_memory_lua_shared_dict_bytes: memory.lua.shared_dict.bytes
      - kong_memory_lua_shared_dict_total_bytes: memory.lua.shared_dict.total_bytes
      - kong_nginx_http_current_connections: nginx.http.current_connections
      - kong_nginx_stream_current_connections: nginx.stream.current_connections
      - kong_stream_status: stream.status

構成

構成とチェックファイルは、名前が一致していなければなりません。チェックが mycheck.py という名前なら、構成ファイルは mycheck.yaml という名前にしなければなりません。

Openmetrics チェックの構成は、標準の Agent チェックとほぼ同じです。主な違いは、check.yaml ファイルに変数 openmetrics_endpoint を入れることです。conf.d/kong.yaml は以下のようになります。

init_config:

instances:
    # Prometheus のメトリクスエンドポイントの URL
  - openmetrics_endpoint: http://localhost:8001/status/

チェックの書き方

すべての OpenMetrics チェックは、OpenMetricsBaseCheckV2 クラスを継承します。

from datadog_checks.base import OpenMetricsBaseCheckV2

class KongCheck(OpenMetricsBaseCheckV2):

インテグレーションネームスペースの定義

__NAMESPACE__ の値は、このインテグレーションによって収集されたすべてのメトリクスとサービスチェックの前に置かれます。

from datadog_checks.base import OpenMetricsBaseCheckV2

class KongCheck(OpenMetricsBaseCheckV2):
    __NAMESPACE__ = "kong"

メトリクスマッピングの定義

メトリクスのマッピングでは、メトリクス名の変更とネイティブメトリクスタイプのオーバーライドが可能です。

from datadog_checks.base import OpenMetricsBaseCheckV2

class KongCheck(OpenMetricsBaseCheckV2):
    __NAMESPACE__ = "kong"

    def __init__(self, name, init_config, instances):
        super(KongCheck, self).__init__(name, init_config, instances)

        self.metrics_map =  {
            'kong_bandwidth': 'bandwidth',
            'kong_http_consumer_status': 'http.consumer.status',
            'kong_http_status': 'http.status',
            'kong_latency': {
                'name': 'latency',
                'type': 'counter',
            },
            'kong_memory_lua_shared_dict_bytes': 'memory.lua.shared_dict.bytes',
            'kong_memory_lua_shared_dict_total_bytes': 'memory.lua.shared_dict.total_bytes',
            'kong_nginx_http_current_connections': 'nginx.http.current_connections',
            'kong_nginx_stream_current_connections': 'nginx.stream.current_connections',
            'kong_stream_status': 'stream.status',
        }

デフォルトインスタンスの定義

デフォルトのインスタンスは、チェックに使用される基本的なコンフィギュレーションです。デフォルトのインスタンスは、metricsopenmetrics_endpoint をオーバーライドする必要があります。 OpenMetricsBaseCheckV2 の get_default_config を、デフォルトのインスタンスでオーバーライドします。

from datadog_checks.base import OpenMetricsBaseCheckV2

class KongCheck(OpenMetricsBaseCheckV2):
    __NAMESPACE__ = "kong"

    def __init__(self, name, init_config, instances):
        super(KongCheck, self).__init__(name, init_config, instances)

        self.metrics_map = {
            'kong_bandwidth': 'bandwidth',
            'kong_http_consumer_status': 'http.consumer.status',
            'kong_http_status': 'http.status',
            'kong_latency': {
                'name': 'latency',
                'type': 'counter',
            },
            'kong_memory_lua_shared_dict_bytes': 'memory.lua.shared_dict.bytes',
            'kong_memory_lua_shared_dict_total_bytes': 'memory.lua.shared_dict.total_bytes',
            'kong_nginx_http_current_connections': 'nginx.http.current_connections',
            'kong_nginx_stream_current_connections': 'nginx.stream.current_connections',
            'kong_stream_status': 'stream.status',
        }

      def get_default_config(self):
            return {'metrics': self.metrics_map}

check メソッドの実装

さらに機能を実装したい場合は、check() 関数をオーバーライドします。

instance から、メトリクスをポーリングするための Prometheus または OpenMetrics のメトリクスエンドポイント endpoint を使用します。

def check(self, instance):
    endpoint = instance.get('openmetrics_endpoint')
例外

不正なコンフィギュレーション、プログラミングエラー、メトリクスを収集できないなどの理由でチェックを実行できない場合は、わかりやすい例外を生成する必要があります。デバッグのために、この例外はログに記録され、Agent のステータスコマンドに表示されます。以下に例を示します。

$ sudo /etc/init.d/datadog-agent info

  Checks
  ======

    my_custom_check
    ---------------
      - instance #0 [ERROR]: Unable to find openmetrics_endpoint in config file.
      - Collected 0 metrics & 0 events

ConfigurationError を使用して check() メソッドを補強します。

from datadog_checks.base import ConfigurationError

def check(self, instance):
    endpoint = instance.get('openmetrics_endpoint')
    if endpoint is None:
        raise ConfigurationError("Unable to find openmetrics_endpoint in config file.")

次に、データを取得するとすぐにフラッシュします。


def check(self, instance):
    endpoint = instance.get('openmetrics_endpoint')
    if endpoint is None:
        raise ConfigurationError("Unable to find openmetrics_endpoint in config file.")

    super().check(instance)

ここまでのまとめ

from datadog_checks.base import OpenMetricsBaseCheckV2
from datadog_checks.base import ConfigurationError

class KongCheck(OpenMetricsBaseCheckV2):
    __NAMESPACE__ = "kong"

    def __init__(self, name, init_config, instances):
        super(KongCheck, self).__init__(name, init_config, instances)

        self.metrics_map = {
            'kong_bandwidth': 'bandwidth',
            'kong_http_consumer_status': 'http.consumer.status',
            'kong_http_status': 'http.status',
            'kong_latency': {
                'name': 'latency',
                'type': 'counter',
            },
            'kong_memory_lua_shared_dict_bytes': 'memory.lua.shared_dict.bytes',
            'kong_memory_lua_shared_dict_total_bytes': 'memory.lua.shared_dict.total_bytes',
            'kong_nginx_http_current_connections': 'nginx.http.current_connections',
            'kong_nginx_stream_current_connections': 'nginx.stream.current_connections',
            'kong_stream_status': 'stream.status',
        }

      def get_default_config(self):
            return {'metrics': self.metrics_map}

      def check(self, instance):
          endpoint = instance.get('openmetrics_endpoint')
          if endpoint is None:
              raise ConfigurationError("Unable to find openmetrics_endpoint in config file.")

          super().check(instance)

さらに改良するには

Prometheus および OpenMetrics の基本インテグレーションに関する詳細は、インテグレーションのデベロッパ用ドキュメントをご参照ください。

Openmetrics で利用できるすべてのコンフィギュレーションオプションを見るには、conf.yaml.example を参照してください。 追加のコンフィギュレーションオプションにデフォルト値を含めることで、OpenMetrics のチェック機能を向上させることができます。

exclude_metrics
一部のメトリクスは、重複していたり、高いカーディナリティをもたらすため、無視されます。このリストに含まれるメトリクスは、ログに Unable to handle metric というデバッグ行が表示されることなく、静かにスキップされます。 特定のフィルターにマッチするもの以外のすべてのメトリクスを除外するには、 - ^(?!foo).*$ のような負のルックアヘッド正規表現を使用します。
share_labels
share_labels マッピングが提供された場合、複数のメトリクスでラベルを共有することができます。キーはラベルを共有する公開メトリクスを表し、値は共有の動作を構成するマッピングです。各マッピングは、labelsmatchvalues のキーのうち少なくとも 1 つを持つ必要があります。
exclude_labels
exclude_labels は、除外するラベルの配列です。除外されるラベルは、メトリクスの送信時にタグとして追加されません。

その他の参考資料