
#! /usr/bin/env bash
MONGO=mongo
TMPFOLDER=/tmp
SCRIPT="
var count = 0;
var resultstr = 0;
function isEmptyObject(obj) {
for (var name in obj) {
return false;
}
return true;
}
function getQueryOrRemove(obj) {
if(!isEmptyObject(obj.query)) {
return obj.op + '(' + tojson(obj.query) + ')';
} else {
return obj.op + '()';
}
}
function safe_assign(from, to) {
if(!isEmptyObject(from)) {
to = from;
}
}
function getUpdate(obj) {
command = obj.op + '(';
if(!isEmptyObject(obj.query)) {
command += tojson(obj.query);
}
if(!isEmptyObject(obj.updateobj)) {
command += ', ' + tojson(obj.updateobj);
}
command += ')';
return command;
}
function getCommand(obj) {
if(isEmptyObject(obj.command)) {
return obj.op + '(' + tojson(obj.command) + ')';
} else {
return obj.op + '()';
}
}
function get_command(obj) {
var str = new Array();
str[0] = obj.ns
if(obj.op == 'query' || obj.op == 'remove') {
str[1] = getQueryOrRemove(obj);
} else if (obj.op == 'update') {
str[1] = getUpdate(obj);
} else if (obj.op == 'insert') {
str[1] = obj.op + '()';
} else if (obj.op == 'command') {
str[1] = getCommand(obj);
}
if(obj.ntoreturn >= 1) {
str[2] = 'limit(' + obj.ntoreturn + ')';
}
return str.join('.');
}
function getOutput(dbName){
var db = conn.getDB(dbName);
var level = db.getProfilingLevel();
if(level <= 0) {
db.setProfilingLevel(1, %s);
}
var cursor = db.system.profile.find({%s}).sort({ts:-1}).limit(200);
while(cursor.hasNext()) {
var doc = tojson(cursor.next());
var obj = eval('(' + doc + ')');
output = new Array();
output[0] = obj.ts.valueOf();
output[1] = get_command(obj).replace(/\|/g,'<<VERTICAL>>');
output[2] = '-';
output[3] = '-';
output[4] = '-';
output[5] = '-';
output[6] = '%s';
if(!isEmptyObject(obj.nscanned)) {
output[2] = obj.nscanned;
}
if(!isEmptyObject(obj.nreturned)) {
output[3] = obj.nreturned;
}
if(!isEmptyObject(obj.millis)) {
output[4] = obj.millis;
}
if(!isEmptyObject(obj.client)) {
output[5] = obj.client;
}
count ++;
resultstr+=(output.join('<<:>>') + '<<###>>');
}
}
var conn = new Mongo('%s');
var list = db.adminCommand('listDatabases');
var showList = new Array();
for (cc in list.databases){
var name = list.databases[cc].name;
if(name!='local' && name!='test' && name!='admin'){
showList.push(name);
}
}
for(var i=0;i<showList.length;i++){
getOutput(showList[i]);
}
if(count>0){
print(count+'<<COUNT>>|MongoDB_Slow_Query<<###>>'+resultstr);
}else{
print('');
}
"
function monitor {
MONGO_LAST_TIME="mongo_info_${PORT}"
if [[ -f ./$MONGO_LAST_TIME ]] ; then
LAST_TIME=$(cat ./$MONGO_LAST_TIME)
if [[ -n "$LAST_TIME" ]] ; then
CONDITION="ts:{\$gt:new Date($LAST_TIME)}"
fi
fi
printf "$SCRIPT" "$6" "$CONDITION" "$3" "$2:$3"> "$TMPFOLDER/mongo.js"
OUTPUT=$("$1/$MONGO" "$2":"$3" "$TMPFOLDER/mongo.js" --quiet)
if [[ -n "$OUTPUT" ]] ; then
RECORD_TIME="0$(date +%s)000"
echo "$RECORD_TIME" > ./$MONGO_LAST_TIME
fi
}
function usage {
printf "\nUsage check_mongo_slow_query:\n"
printf "\t<-f mongo可执行程序的路径>\n"
printf "\t<-w 设置告警状态的慢查询语句阈值>\n"
printf "\t<-c 设置紧急状态的慢查询语句阈值>\n"
printf "\t[-u 连接数据库的用户名]\n"
printf "\t[-p 连接数据库的密码]\n"
printf "\t[-P 连接数据库的端口]\n"
printf "\t[-H 设置MongoDB服务器所在的主机IP地址]\n"
printf "\t[-t 设置记录慢查询语句的时间阈值]\n"
printf "\t-h 打印帮助信息\n"
}
while getopts :u:p:P:f:w:c:t:H:h arg; do
case $arg in
u) NAME=$OPTARG;;
p) PASSWD=$OPTARG;;
H) HOST=$OPTARG;;
P) PORT=$OPTARG;;
f) BINPATH=$OPTARG;;
t) THRESHOLD=$OPTARG;;
w) WARNING=$OPTARG;;
c) CRITICAL=$OPTARG;;
h) usage
exit 0;;
?) printf "无效的参数!\n"
usage
exit 3;;
esac
done
if [[ ! -x "$BINPATH/$MONGO" ]] ; then
printf "$BINPATH/$MONGO不是有效的可执行程序.\n"
usage
exit 3
fi
#set the default port
if [[ -z "$PORT" ]] ; then
PORT=27017
fi
#set the default IP address
if [[ -z "$HOST" ]] ; then
HOST=127.0.0.1
#TODO:需要修改为127.0.0.1
fi
if [[ -z "$WARNING" || -z "$CRITICAL" ]] ; then
printf "必须提供用于设置监控项状态的阈值.\n"
usage
exit 3
fi
#set the default threshold
if [[ -z "$THRESHOLD" ]] ; then
THRESHOLD=100
fi
monitor "$BINPATH" "$HOST" "$PORT" "$NAME" "$PASSWD" "$THRESHOLD"
if [[ ! -z $OUTPUT ]] ; then
# count=$(printf "%s" "$OUTPUT" | awk -F '<<###>>' 'print NF')
# OUTPUT=$(echo $OUTPUT) #删除OUTPUT中的换行符
# printf "${count}<<COUNT>>|MongoDB_Slow_Query<<###>>%s\n" "$OUTPUT"
#OUTPUT=`echo $OUTPUT|awk '{for(i=1;i<=NF;++i){if(index($0,"error")>1){print "not_master_and_slaveok_is_false";break;}}}'`
OUTPUT=`echo $OUTPUT|awk '{for(i=1;i<=NF;++i){if(index($0,"error")>1){print "0";break;}}}'`
echo $OUTPUT
exit 1
else
exit 0
fi