set setting reset

インフラ関連の小ネタと備忘録

pgpool への connection を munin でグラフ化

bash で munin がんばるシリーズです。 pgrep で取得した情報からごにょごにょやっています。

Used な Connection が増えまくったことで新規コネクションが pgpool によって待たされることがないようにリソース監視しましょうというのが目的です。

グラフ化できるのは下記の通りです。

  • トータルのコネクション数
  • 接続待ち(wait)のコネクション数
  • idle のコネクション数
  • 各クライアントからのコネクション数
  • おまけ

f:id:rriifftt:20150409144700p:plain

pgpool_connection_state.sh

#!/bin/bash

# munin の設定
if [ "$1" = "autoconf" ]; then
    echo yes
    exit 0
fi

if [ "$1" = "config" ]; then
    echo "graph_title pgpool connections state"
    echo "graph_args --base 1000 -l 0"
    echo "graph_category Connections"
    echo "graph_vlabel pgpool connections state"
    echo "graph_scale yes"
    echo "graph_info pgpool connections state"

    info=("total_connection" "wait_connection" "used_connection")
    for i in "${info[@]}"
    do
        echo "${i}.label pgpool ${i} connection states"
        echo "${i}.info pgpool ${i} states"
        echo "${i}.type GAUGE"
        echo "${i}.draw LINE3"
    done

    base=`pgrep -f "pgpool[:]" -l | grep -v "/usr/bin/pgpool"`
    # 10_0_0_1_idle のようにクライアントごとにラベルを作成
    # ひどい
    client_labels=`echo "${base}" | grep -v "wait" | grep -v "worker" | sed 's/(/ (/g' | awk {'print $5,$7'} | sort | uniq | sed 's/\./_/g' | sed 's/ /_/g'`
    echo "${client_labels}" | while read line
    do
        echo "${line}.label ${line}"
        echo "${line}.info pgpool connections from ${line}"
        echo "${line}.type GAUGE"
        echo "${line}.draw AREA"
    done

    states=("idle" "SELECT" "INSERT" "UPDATE" "DELETE")
    for s in "${states[@]}"
    do
        echo "all_${s}_connecions.label all_${s}"
        echo "all_${s}_connecions.info pgpool connections from all_${s}"
        echo "all_${s}_connecions.type GAUGE"
        echo "all_${s}_connecions.draw LINE3"
    done
    exit 0
fi

# pgrep から pgpool の接続状態を取得する
# DML 毎、クライアント毎にグラフを表示
base=`pgrep -f pgpool -l | grep -v "/usr/bin/pgpool"`

# wait for connecion の総数を表示
wait_count=`echo "${base}" | grep "wai[t]" | wc -l`
echo "wait_connection.value ${wait_count}"

# idle を含めた利用中のコネクション総数を表示
used_connections=`echo "${base}" | grep -v "wai[t]" | grep -v "worker process" | grep -v "PCP"`
used_connection_count=`echo "${used_connections}" | wc -l`
echo "used_connection.value ${used_connection_count}"

# 全てのコネクション数を表示
total_connections=`expr ${wait_count} + ${used_connection_count}`
echo "total_connection.value ${total_connections}"

get_connection_counts()
{
    state=$1
    # idle や DML ごとの総数
    connections_per_state=`echo "${used_connections}" | grep -i "${state}"`
    connections_per_state_num=`echo "${connections_per_state}" | wc -l`
    if [ -z "${connections_per_state_num}" ]; then
        connections_per_state_num=0
    fi
    echo "all_${state}_connecions.value ${connections_per_state_num}"

    # クライアント毎の idle や DML などの接続数を表示
    clients=`echo "${connections_per_state}" | awk {'print $5'} | cut -d '(' -f 1 | sed 's/\./_/g' | sort | uniq -c`
    echo "${clients}" | while read line
    do
        count=`echo "${line}" | awk {'print $1'}`
        client=`echo "${line}" | awk {'print $2'}`
        if [ -z "${count}" ]; then
            count=0
        fi
        echo "${client}_${state}.value ${count}"
    done
}

# Main
states=("idle" "SELECT" "INSERT" "UPDATE" "DELETE")
for s in ${states[@]}
do
    get_connection_counts ${s}
done
exit 0

pgrep とても便利ですね