これについての洞察を得るお手伝いをします。しかしその前に、私は Java プログラマーではなく、C/C++ プログラマーであることをお伝えしなければなりません。つまり、神経節でどのように機能するかをお知らせでき、必要なコードを書き換えるために Java/Python で同等のメソッドを見つけることができるということです。
ガングリアには、目的を達成するための API がないことに注意してください。
最初に、適切に理解するために以下の神経節の設定を検討してください。

GS1 と GS2 はシステム メトリックを収集し、それらを GM にプッシュします。したがって、あなたの質問によると、独自の Java/Python ベースのアプリケーションでそのようなメトリックをすべて収集したい場合は、アプリケーションをマスター サーバーにインストールする必要があります (つまり、GS を独自のアプリケーションに置き換えます)。
GS1 と GS2 は、収集されたすべてのメトリックを UDP ユニキャスト チャネルまたは UDP マルチキャスト チャネルのいずれかで送信します。スケーラビリティを容易にするために、すべての gmond.conf で UDP ユニキャストを有効にすることをお勧めします。
あなたの質問は、GMを独自のツールに置き換えることに関するものであるため、GS1とGS2についてはあまり議論しません。
GM は 2 つの重要なライブラリを多用して UDP 接続を確立し、データを独自の読み取り可能な形式に変換します。それらは、UDP 接続を確立して関連するアクティビティを実行するAPR (Apache Portable Runtime) と、ネットワークを介してデータを送信し、RPC を実行するXDR (External Data Representation) です。
まず、Java と Python で APR と XDR に相当するライブラリを見つける必要があります。XDR はすでに Java で利用可能であり、APR を独自の基本的な実装に置き換えて、ネットワーク間操作 (つまり、UDP ソケットの作成など) を実行することができます。
ganglia のgmond.cソース ファイルを開き、 1436行目に移動します。C 関数が見つかります。
static void process_udp_recv_channel(const apr_pollfd_t *desc, apr_time_t now)
.
この機能は、基本的に「UDP 接続の確立」と「データを読み取り可能な形式に変換する」アクティビティを実行します。
上記の関数の呼び出しフローを以下に示します。

では、1436 行目の関数を展開して、さらに理解を深めましょう。
この関数の最初の引数は、IP、ポートなどのネットワーク パラメータを保持します。構造は以下で展開されます。Java でも同様のオブジェクトを見つけることができます。
struct apr_pollfd_t {
apr_pool_t *p; /**< associated pool */
apr_datatype_e desc_type; /**< descriptor type */
apr_int16_t reqevents; /**< requested events */
apr_int16_t rtnevents; /**< returned events */
apr_descriptor desc; /**< @see apr_descriptor */
void *client_data; /**< allows app to associate context */
};
SFLOW が無効になっている場合、2 番目のパラメーターは何もしません。
そのため、APR プール、UDP 接続などの作成から始めます。
socket = desc->desc.s;
channel = desc->client_data;
apr_pool_create(&p, global_context);
status = apr_socket_addr_get(&remotesa, APR_LOCAL, socket);
status = apr_sockaddr_info_get(&remotesa, NULL, remotesa->family, remotesa->port, 0, p);
/* Grab the data */
status = apr_socket_recvfrom(remotesa, socket, 0, buf, &len);
if(status != APR_SUCCESS)
{
apr_pool_destroy(p);
return;
}
apr_sockaddr_ip_buffer_get(remoteip, 256, remotesa);
/* Check the ACL */
if(Ganglia_acl_action( channel->acl, remotesa) != GANGLIA_ACCESS_ALLOW)
{
apr_pool_destroy(p);
return;
}
variable のすべての宣言は、展開された関数の先頭 (1439 行から 1456 行) にあります。
次に、XDR ストリームを作成します。
xdrmem_create(&x, buf, max_udp_message_len, XDR_DECODE);
メタデータとメトリック値を保存する構造体のデータをフラッシュします。
memset( &fmsg, 0, sizeof(Ganglia_metadata_msg));
memset( &vmsg, 0, sizeof(Ganglia_value_msg));
fmsg ( Ganglia_metadata_msg
) および vmsg ( Ganglia_value_msg
) 構造体の定義は、gm_protocol.hヘッダー ファイルにあります。それらをJavaで書き直してください。
次に、受信したメッセージが「メタデータ」か「メトリック値」かを判断します。
xdr_Ganglia_msg_formats(&x, &id); // this function is located in the source file gm_protocol_xdr.c and this file is generated by rpcgen.
注: rpcgenは rpc コンパイラであり、その説明はこの質問にあります。
注: gm_protocol_xdr.cへのリンクは次のとおりです。
id
は であり、その宣言を以下enum
に示します。
enum Ganglia_msg_formats {
gmetadata_full = 128,
gmetric_ushort = 128 + 1,
gmetric_short = 128 + 2,
gmetric_int = 128 + 3,
gmetric_uint = 128 + 4,
gmetric_string = 128 + 5,
gmetric_float = 128 + 6,
gmetric_double = 128 + 7,
gmetadata_request = 128 + 8,
};
typedef enum Ganglia_msg_formats Ganglia_msg_formats;
の値に基づいてid
、パケットが持つ値の種類を判断できます。この目的のために、この関数は別の関数 (実際には rpcgen によって生成されます) を呼び出して、パケットが持つ値の種類を判断し、見つかった場合は人間が読める形式にも変換します。
機能は次のとおりです。
xdr_Ganglia_value_msg(&x, &vmsg);
この関数の完全な展開は、gm_protocol_xdr.cの 275 行目から見つけることができます。
その後、これらのパケットで好きなことを行うことができます。
最後に、割り当てられたすべての XDR 変数と APR プールを解放する必要があります。
これにより、独自のアプリケーションを開始するための公正なアイデアが得られることを願っています.