├── LICENSE.md ├── README.md ├── Templates └── Template_MongoDB.xml ├── bin ├── mongodb-stats.sh └── zabbix-mongodb.py └── zabbix_agentd.d └── userparameter_mongodb.conf /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Long Chen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zabbix-MongoDB 2 | A Zabbix plugin for monitoring MongoDB. 3 | 4 | # Installation 5 | 1. Import the mongodb template to zabbix and link it to the zabbix mongodb host. 6 | 2. Copy the scripts to mongodb host in /usr/local/bin . 7 | 3. Copy mongodb zabbix agent configuration to /etc/zabbix-agent/zabbix_agentd.d and restart zabbix agent. 8 | 9 | Note: 10 | - Zabbix sender uses zabbix agent configuration to send the metrics, please check the hostname is set in the zabbix agent config /etc/zabbix/zabbix_agentd.conf, by default the hostname may be commented out. 11 | 12 | The following metrics are collected on mongodb version 3.0 by using python mongodb client, and then sent by zabbix sender. 13 | 14 | **Server Stats** 15 | - mongodb.ismaster 16 | - mongodb.version 17 | - mongodb.storageEngine 18 | - mongodb.uptime 19 | - mongodb.okstatus 20 | - mongodb.asserts.msg 21 | - mongodb.asserts.rollovers 22 | - mongodb.asserts.regular 23 | - mongodb.asserts.warning 24 | - mongodb.asserts.user 25 | - mongodb.backgroundFlushing.flushes 26 | - mongodb.backgroundFlushing.total_ms 27 | - mongodb.operation.getmore 28 | - mongodb.operation.insert 29 | - mongodb.operation.update 30 | - mongodb.operation.command 31 | - mongodb.operation.query 32 | - mongodb.operation.delete 33 | - mongodb.memory.resident 34 | - mongodb.memory.virtual 35 | - mongodb.memory.mapped 36 | - mongodb.memory.mappedWithJournal 37 | - mongodb.connection.current 38 | - mongodb.connection.available 39 | - mongodb.connection.totalCreated 40 | - mongodb.network.numRequests 41 | - mongodb.network.bytesOut 42 | - mongodb.network.bytesIn 43 | - mongodb.heap.size 44 | - mongodb.page.faults 45 | - mongodb.globalLock.totalTime 46 | - mongodb.globalLock.currentQueue.total 47 | - mongodb.globalLock.currentQueue.writers 48 | - mongodb.globalLock.currentQueue.readers 49 | - mongodb.globalLock.activeClients.total 50 | - mongodb.globalLock.activeClients.writers 51 | - mongodb.globalLock.activeClients.readers 52 | 53 | **DB Stats** 54 | - mongodb.stats.storageSize[db] 55 | - mongodb.stats.ok[db] 56 | - mongodb.stats.avgObjSize[db] 57 | - mongodb.stats.indexes[db] 58 | - mongodb.stats.objects[db] 59 | - mongodb.stats.collections[db] 60 | - mongodb.stats.fileSize[db] 61 | - mongodb.stats.numExtents[db] 62 | - mongodb.stats.dataSize[db] 63 | - mongodb.stats.indexSize[db] 64 | - mongodb.stats.nsSizeMB[db] 65 | 66 | # License 67 | [MIT](/LICENSE.md) 68 | -------------------------------------------------------------------------------- /Templates/Template_MongoDB.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 3.2 4 | 2017-08-14T15:50:26Z 5 | 6 | 7 | Templates 8 | 9 | 10 | 11 | 2897 | 2898 | 2899 | 2900 | {Template MongoDB:mongodb.fsync-locked.last()}=1 2901 | and {Template MongoDB:mongodb.hidden.last()}=1 2902 | and {Template MongoDB:mongodb.priority.last()}=0 2903 | 0 2904 | 2905 | Locked, hidden and priority 0 on {HOST.NAME} 2906 | 0 2907 | 2908 | 2909 | 0 2910 | 2 2911 | The database is locked, hidden and priority set to 0 2912 | 0 2913 | 0 2914 | 2915 | 2916 | 2917 | 2918 | {Template MongoDB:mongodb.fsync-locked.last()}=1 2919 | and {Template MongoDB:mongodb.hidden.last()}=1 2920 | and {Template MongoDB:mongodb.priority.last()}=1 2921 | 0 2922 | 2923 | Locked, hidden and priority 1 on {HOST.NAME} 2924 | 0 2925 | 2926 | 2927 | 0 2928 | 4 2929 | The database is locked, hidden and priority set to 1 2930 | 0 2931 | 0 2932 | 2933 | 2934 | 2935 | 2936 | {Template MongoDB:mongodb.fsync-locked.last()}=1 2937 | and {Template MongoDB:mongodb.hidden.last()}=0 2938 | and {Template MongoDB:mongodb.priority.last()}=0 2939 | 0 2940 | 2941 | Locked, not hidden and priority 0 on {HOST.NAME} 2942 | 0 2943 | 2944 | 2945 | 0 2946 | 4 2947 | The database is locked, hidden and priority set to 0 2948 | 0 2949 | 0 2950 | 2951 | 2952 | 2953 | 2954 | {Template MongoDB:mongodb.fsync-locked.last()}=1 2955 | and {Template MongoDB:mongodb.hidden.last()}=0 2956 | and {Template MongoDB:mongodb.priority.last()}=1 2957 | 0 2958 | 2959 | Locked, not hidden and priority 1 on {HOST.NAME} 2960 | 0 2961 | 2962 | 2963 | 0 2964 | 4 2965 | The database is locked, not hidden and priority set to 1 2966 | 0 2967 | 0 2968 | 2969 | 2970 | 2971 | 2972 | {Template MongoDB:mongodb.oplog.last()}<259200 2973 | 1 2974 | {Template MongoDB:mongodb.oplog.last()}>259320 2975 | MongoDB Oplog length 3 days on {HOST.NAME} 2976 | 0 2977 | 2978 | 2979 | 0 2980 | 4 2981 | 2982 | 0 2983 | 0 2984 | 2985 | 2986 | 2987 | 2988 | {Template MongoDB:mongodb.oplog.last()}<604800 and not {Template MongoDB:mongodb.oplog.last()}<259200 2989 | 1 2990 | {Template MongoDB:mongodb.oplog.last()}>604920 2991 | MongoDB Oplog length 7 days on {HOST.NAME} 2992 | 0 2993 | 2994 | 2995 | 0 2996 | 2 2997 | 2998 | 0 2999 | 0 3000 | 3001 | 3002 | 3003 | 3004 | {Template MongoDB:mongodb.oplog-sync.last()}>=60 and not {Template MongoDB:mongodb.oplog-sync.last()}>=300 3005 | 1 3006 | {Template MongoDB:mongodb.oplog-sync.last()}<30 3007 | MongoDB Oplog Sync 1 minute on {HOST.NAME} 3008 | 0 3009 | 3010 | 3011 | 0 3012 | 2 3013 | 3014 | 0 3015 | 0 3016 | 3017 | 3018 | 3019 | 3020 | {Template MongoDB:mongodb.oplog-sync.last()}>=300 3021 | 1 3022 | {Template MongoDB:mongodb.oplog-sync.last()}<240 3023 | MongoDB Oplog Sync 5 minute on {HOST.NAME} 3024 | 0 3025 | 3026 | 3027 | 0 3028 | 4 3029 | 3030 | 0 3031 | 0 3032 | 3033 | 3034 | 3035 | 3036 | {Template MongoDB:proc.num[mongod].count(#3,0)}=3 3037 | 0 3038 | 3039 | MongoDB process is not running on {HOST.NAME} 3040 | 0 3041 | 3042 | 3043 | 0 3044 | 4 3045 | 3046 | 0 3047 | 0 3048 | 3049 | 3050 | 3051 | 3052 | {Template MongoDB:mongodb.okstatus.count(#3,0)}=3 3053 | 0 3054 | 3055 | MongoDB server status is not OK 3056 | 0 3057 | 3058 | 3059 | 0 3060 | 3 3061 | 3062 | 0 3063 | 0 3064 | 3065 | 3066 | 3067 | 3068 | {Template MongoDB:mongodb.used-cache-p.last()}>=90 and {Template MongoDB:mongodb.used-cache-p.last()}<95 3069 | 0 3070 | 3071 | MongoDB Wired Tiger Used cache 90% on {HOST.NAME} 3072 | 0 3073 | 3074 | 3075 | 0 3076 | 2 3077 | 3078 | 0 3079 | 0 3080 | 3081 | 3082 | 3083 | 3084 | {Template MongoDB:mongodb.used-cache-p.last()}>=95 3085 | 0 3086 | 3087 | MongoDB Wired Tiger Used cache 95% on {HOST.NAME} 3088 | 0 3089 | 3090 | 3091 | 0 3092 | 4 3093 | 3094 | 0 3095 | 0 3096 | 3097 | 3098 | 3099 | 3100 | {Template MongoDB:mongodb.fsync-locked.last()}=0 3101 | and {Template MongoDB:mongodb.hidden.last()}=1 3102 | and {Template MongoDB:mongodb.priority.last()}=0 3103 | 0 3104 | 3105 | Not locked, but is hidden and priority 0 on {HOST.NAME} 3106 | 0 3107 | 3108 | 3109 | 0 3110 | 2 3111 | The database is not locked, but is hidden and priority set to 0 3112 | 0 3113 | 0 3114 | 3115 | 3116 | 3117 | 3118 | {Template MongoDB:mongodb.fsync-locked.last()}=0 3119 | and {Template MongoDB:mongodb.hidden.last()}=1 3120 | and {Template MongoDB:mongodb.priority.last()}=1 3121 | 0 3122 | 3123 | Not locked, is hidden and priority 1 on {HOST.NAME} 3124 | 0 3125 | 3126 | 3127 | 0 3128 | 4 3129 | The database is not locked, is hidden and priority set to 1 3130 | 0 3131 | 0 3132 | 3133 | 3134 | 3135 | 3136 | {Template MongoDB:mongodb.fsync-locked.last()}=0 3137 | and {Template MongoDB:mongodb.hidden.last()}=0 3138 | and {Template MongoDB:mongodb.priority.last()}=0 3139 | 0 3140 | 3141 | Not locked or hidden, but priority 0 on {HOST.NAME} 3142 | 0 3143 | 3144 | 3145 | 0 3146 | 2 3147 | The database is not locked or hidden, but priority set to 0 3148 | 0 3149 | 0 3150 | 3151 | 3152 | 3153 | 3154 | {Template MongoDB:mongodb.page.faults.min(#3)}>{$PAGE_FAULT_TH_WARN} 3155 | 0 3156 | 3157 | Page faults detected on {HOST.NAME} (LV={ITEM.VALUE}) 3158 | 0 3159 | 3160 | 3161 | 0 3162 | 2 3163 | 3164 | 0 3165 | 0 3166 | 3167 | 3168 | 3169 | 3170 | 3171 | 3172 | MongoDB::asserts 3173 | 900 3174 | 200 3175 | 0.0000 3176 | 100.0000 3177 | 1 3178 | 1 3179 | 0 3180 | 1 3181 | 0 3182 | 0.0000 3183 | 0.0000 3184 | 0 3185 | 0 3186 | 0 3187 | 0 3188 | 3189 | 3190 | 0 3191 | 0 3192 | 1A7C11 3193 | 0 3194 | 7 3195 | 0 3196 | 3197 | Template MongoDB 3198 | mongodb.asserts.msg 3199 | 3200 | 3201 | 3202 | 1 3203 | 0 3204 | F63100 3205 | 0 3206 | 7 3207 | 0 3208 | 3209 | Template MongoDB 3210 | mongodb.asserts.regular 3211 | 3212 | 3213 | 3214 | 2 3215 | 0 3216 | 2774A4 3217 | 0 3218 | 7 3219 | 0 3220 | 3221 | Template MongoDB 3222 | mongodb.asserts.rollovers 3223 | 3224 | 3225 | 3226 | 3 3227 | 0 3228 | A54F10 3229 | 0 3230 | 7 3231 | 0 3232 | 3233 | Template MongoDB 3234 | mongodb.asserts.user 3235 | 3236 | 3237 | 3238 | 4 3239 | 0 3240 | FC6EA3 3241 | 0 3242 | 7 3243 | 0 3244 | 3245 | Template MongoDB 3246 | mongodb.asserts.warning 3247 | 3248 | 3249 | 3250 | 3251 | 3252 | MongoDB::connections 3253 | 900 3254 | 200 3255 | 0.0000 3256 | 100.0000 3257 | 1 3258 | 1 3259 | 0 3260 | 1 3261 | 0 3262 | 0.0000 3263 | 0.0000 3264 | 0 3265 | 0 3266 | 0 3267 | 0 3268 | 3269 | 3270 | 0 3271 | 4 3272 | 1A7C11 3273 | 0 3274 | 7 3275 | 0 3276 | 3277 | Template MongoDB 3278 | mongodb.connection.available 3279 | 3280 | 3281 | 3282 | 1 3283 | 5 3284 | F63100 3285 | 0 3286 | 7 3287 | 0 3288 | 3289 | Template MongoDB 3290 | mongodb.connection.current 3291 | 3292 | 3293 | 3294 | 3295 | 3296 | MongoDB::global lock::active clients 3297 | 900 3298 | 200 3299 | 0.0000 3300 | 100.0000 3301 | 1 3302 | 1 3303 | 0 3304 | 1 3305 | 0 3306 | 0.0000 3307 | 0.0000 3308 | 0 3309 | 0 3310 | 0 3311 | 0 3312 | 3313 | 3314 | 0 3315 | 0 3316 | F63100 3317 | 0 3318 | 7 3319 | 0 3320 | 3321 | Template MongoDB 3322 | mongodb.globalLock.activeClients.total 3323 | 3324 | 3325 | 3326 | 1 3327 | 0 3328 | 1A7C11 3329 | 0 3330 | 7 3331 | 0 3332 | 3333 | Template MongoDB 3334 | mongodb.globalLock.activeClients.readers 3335 | 3336 | 3337 | 3338 | 2 3339 | 0 3340 | 2774A4 3341 | 0 3342 | 7 3343 | 0 3344 | 3345 | Template MongoDB 3346 | mongodb.globalLock.activeClients.writers 3347 | 3348 | 3349 | 3350 | 3351 | 3352 | MongoDB::global lock::current queue 3353 | 900 3354 | 200 3355 | 0.0000 3356 | 100.0000 3357 | 1 3358 | 1 3359 | 0 3360 | 1 3361 | 0 3362 | 0.0000 3363 | 0.0000 3364 | 0 3365 | 0 3366 | 0 3367 | 0 3368 | 3369 | 3370 | 0 3371 | 0 3372 | F63100 3373 | 0 3374 | 7 3375 | 0 3376 | 3377 | Template MongoDB 3378 | mongodb.globalLock.currentQueue.total 3379 | 3380 | 3381 | 3382 | 1 3383 | 0 3384 | 1A7C11 3385 | 0 3386 | 7 3387 | 0 3388 | 3389 | Template MongoDB 3390 | mongodb.globalLock.currentQueue.readers 3391 | 3392 | 3393 | 3394 | 2 3395 | 0 3396 | 2774A4 3397 | 0 3398 | 7 3399 | 0 3400 | 3401 | Template MongoDB 3402 | mongodb.globalLock.currentQueue.writers 3403 | 3404 | 3405 | 3406 | 3407 | 3408 | MongoDB::memory 3409 | 900 3410 | 200 3411 | 0.0000 3412 | 100.0000 3413 | 1 3414 | 1 3415 | 0 3416 | 1 3417 | 0 3418 | 0.0000 3419 | 0.0000 3420 | 0 3421 | 0 3422 | 0 3423 | 0 3424 | 3425 | 3426 | 0 3427 | 0 3428 | 2774A4 3429 | 0 3430 | 7 3431 | 0 3432 | 3433 | Template MongoDB 3434 | mongodb.memory.virtual 3435 | 3436 | 3437 | 3438 | 1 3439 | 0 3440 | FC6EA3 3441 | 0 3442 | 7 3443 | 0 3444 | 3445 | Template MongoDB 3446 | mongodb.memory.mappedWithJournal 3447 | 3448 | 3449 | 3450 | 2 3451 | 0 3452 | 1A7C11 3453 | 0 3454 | 7 3455 | 0 3456 | 3457 | Template MongoDB 3458 | mongodb.used-cache 3459 | 3460 | 3461 | 3462 | 3463 | 3464 | MongoDB::network 3465 | 900 3466 | 200 3467 | 0.0000 3468 | 100.0000 3469 | 1 3470 | 1 3471 | 0 3472 | 1 3473 | 0 3474 | 0.0000 3475 | 0.0000 3476 | 0 3477 | 0 3478 | 0 3479 | 0 3480 | 3481 | 3482 | 0 3483 | 0 3484 | 1A7C11 3485 | 0 3486 | 7 3487 | 0 3488 | 3489 | Template MongoDB 3490 | mongodb.network.bytesIn 3491 | 3492 | 3493 | 3494 | 1 3495 | 0 3496 | F63100 3497 | 0 3498 | 7 3499 | 0 3500 | 3501 | Template MongoDB 3502 | mongodb.network.bytesOut 3503 | 3504 | 3505 | 3506 | 2 3507 | 0 3508 | 2774A4 3509 | 1 3510 | 7 3511 | 0 3512 | 3513 | Template MongoDB 3514 | mongodb.network.numRequests 3515 | 3516 | 3517 | 3518 | 3519 | 3520 | MongoDB::operations 3521 | 900 3522 | 200 3523 | 0.0000 3524 | 100.0000 3525 | 1 3526 | 1 3527 | 0 3528 | 1 3529 | 0 3530 | 0.0000 3531 | 0.0000 3532 | 0 3533 | 0 3534 | 0 3535 | 0 3536 | 3537 | 3538 | 0 3539 | 0 3540 | 1A7C11 3541 | 0 3542 | 7 3543 | 0 3544 | 3545 | Template MongoDB 3546 | mongodb.operation.command 3547 | 3548 | 3549 | 3550 | 1 3551 | 0 3552 | F63100 3553 | 0 3554 | 7 3555 | 0 3556 | 3557 | Template MongoDB 3558 | mongodb.operation.delete 3559 | 3560 | 3561 | 3562 | 2 3563 | 0 3564 | 2774A4 3565 | 0 3566 | 7 3567 | 0 3568 | 3569 | Template MongoDB 3570 | mongodb.operation.getmore 3571 | 3572 | 3573 | 3574 | 3 3575 | 0 3576 | A54F10 3577 | 0 3578 | 7 3579 | 0 3580 | 3581 | Template MongoDB 3582 | mongodb.operation.insert 3583 | 3584 | 3585 | 3586 | 4 3587 | 0 3588 | FC6EA3 3589 | 0 3590 | 7 3591 | 0 3592 | 3593 | Template MongoDB 3594 | mongodb.operation.query 3595 | 3596 | 3597 | 3598 | 5 3599 | 0 3600 | 6C59DC 3601 | 0 3602 | 7 3603 | 0 3604 | 3605 | Template MongoDB 3606 | mongodb.operation.update 3607 | 3608 | 3609 | 3610 | 3611 | 3612 | MongoDB::OplogLength 3613 | 900 3614 | 200 3615 | 0.0000 3616 | 100.0000 3617 | 1 3618 | 1 3619 | 0 3620 | 1 3621 | 0 3622 | 0.0000 3623 | 0.0000 3624 | 0 3625 | 0 3626 | 0 3627 | 0 3628 | 3629 | 3630 | 0 3631 | 0 3632 | 1A7C11 3633 | 0 3634 | 2 3635 | 0 3636 | 3637 | Template MongoDB 3638 | mongodb.oplog 3639 | 3640 | 3641 | 3642 | 3643 | 3644 | MongoDB::OplogSync 3645 | 900 3646 | 200 3647 | 0.0000 3648 | 100.0000 3649 | 1 3650 | 1 3651 | 0 3652 | 1 3653 | 0 3654 | 0.0000 3655 | 0.0000 3656 | 0 3657 | 0 3658 | 0 3659 | 0 3660 | 3661 | 3662 | 0 3663 | 0 3664 | 1A7C11 3665 | 0 3666 | 2 3667 | 0 3668 | 3669 | Template MongoDB 3670 | mongodb.oplog-sync 3671 | 3672 | 3673 | 3674 | 3675 | 3676 | MongoDB::page faults 3677 | 900 3678 | 200 3679 | 0.0000 3680 | 100.0000 3681 | 1 3682 | 1 3683 | 0 3684 | 1 3685 | 0 3686 | 0.0000 3687 | 0.0000 3688 | 0 3689 | 0 3690 | 0 3691 | 0 3692 | 3693 | 3694 | 0 3695 | 0 3696 | DD0000 3697 | 0 3698 | 7 3699 | 0 3700 | 3701 | Template MongoDB 3702 | mongodb.page.faults 3703 | 3704 | 3705 | 3706 | 3707 | 3708 | Wired Tiger Memory Usage 3709 | 900 3710 | 200 3711 | 0.0000 3712 | 100.0000 3713 | 1 3714 | 1 3715 | 0 3716 | 1 3717 | 0 3718 | 0.0000 3719 | 0.0000 3720 | 0 3721 | 0 3722 | 0 3723 | 0 3724 | 3725 | 3726 | 0 3727 | 0 3728 | 1A7C11 3729 | 0 3730 | 2 3731 | 0 3732 | 3733 | Template MongoDB 3734 | mongodb.total-cache 3735 | 3736 | 3737 | 3738 | 1 3739 | 0 3740 | F63100 3741 | 0 3742 | 2 3743 | 0 3744 | 3745 | Template MongoDB 3746 | mongodb.used-cache 3747 | 3748 | 3749 | 3750 | 2 3751 | 0 3752 | 2774A4 3753 | 0 3754 | 2 3755 | 0 3756 | 3757 | Template MongoDB 3758 | mongodb.dirty-cache 3759 | 3760 | 3761 | 3762 | 3 3763 | 0 3764 | A54F10 3765 | 1 3766 | 2 3767 | 0 3768 | 3769 | Template MongoDB 3770 | mongodb.used-cache-p 3771 | 3772 | 3773 | 3774 | 3775 | 3776 | 3777 | 3778 | MongoDB ismaster status 3779 | 3780 | 3781 | 0 3782 | False 3783 | 3784 | 3785 | 1 3786 | True 3787 | 3788 | 3789 | 3790 | 3791 | MongoDB ok status 3792 | 3793 | 3794 | 0 3795 | False 3796 | 3797 | 3798 | 1 3799 | True 3800 | 3801 | 3802 | 3803 | 3804 | 3805 | -------------------------------------------------------------------------------- /bin/mongodb-stats.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Date: 22/01/2017 4 | # Author: Long Chen 5 | # Description: A script to send MongoDB stats to zabbix server by using zabbix sender 6 | # Requires: Zabbix Sender, zabbix-mongodb.py 7 | 8 | get_MongoDB_metrics(){ 9 | python /usr/local/bin/zabbix-mongodb.py 10 | } 11 | 12 | # Send the results to zabbix server by using zabbix sender 13 | result=$(get_MongoDB_metrics | /usr/bin/zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -i - 2>&1) 14 | response=$(echo "$result" | awk -F ';' '$1 ~ /^info/ && match($1,/[0-9].*$/) {sum+=substr($1,RSTART,RLENGTH)} END {print sum}') 15 | if [ -n "$response" ]; then 16 | echo "$response" 17 | else 18 | echo "$result" 19 | fi 20 | -------------------------------------------------------------------------------- /bin/zabbix-mongodb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Date: 03/01/2017 4 | Author: Long Chen 5 | Description: A script to get MongoDB metrics 6 | Requires: MongoClient in python 7 | """ 8 | 9 | from calendar import timegm 10 | from time import gmtime 11 | 12 | from pymongo import MongoClient, errors 13 | from sys import exit 14 | 15 | import json 16 | 17 | class MongoDB(object): 18 | """main script class""" 19 | # pylint: disable=too-many-instance-attributes 20 | def __init__(self): 21 | self.mongo_host = "127.0.0.1" 22 | self.mongo_port = 27017 23 | self.mongo_db = ["admin", ] 24 | self.mongo_user = None 25 | self.mongo_password = None 26 | self.__conn = None 27 | self.__dbnames = None 28 | self.__metrics = [] 29 | 30 | def connect(self): 31 | """Connect to MongoDB""" 32 | if self.__conn is None: 33 | if self.mongo_user is None: 34 | try: 35 | self.__conn = MongoClient('mongodb://%s:%s' % 36 | (self.mongo_host, 37 | self.mongo_port)) 38 | except errors.PyMongoError as py_mongo_error: 39 | print('Error in MongoDB connection: %s' % 40 | str(py_mongo_error)) 41 | else: 42 | try: 43 | self.__conn = MongoClient('mongodb://%s:%s@%s:%s' % 44 | (self.mongo_user, 45 | self.mongo_password, 46 | self.mongo_host, 47 | self.mongo_port)) 48 | except errors.PyMongoError as py_mongo_error: 49 | print('Error in MongoDB connection: %s' % 50 | str(py_mongo_error)) 51 | 52 | def add_metrics(self, k, v): 53 | """add each metric to the metrics list""" 54 | dict_metrics = {} 55 | dict_metrics['key'] = k 56 | dict_metrics['value'] = v 57 | self.__metrics.append(dict_metrics) 58 | 59 | def print_metrics(self): 60 | """print out all metrics""" 61 | metrics = self.__metrics 62 | for metric in metrics: 63 | zabbix_item_key = str(metric['key']) 64 | zabbix_item_value = str(metric['value']) 65 | print('- ' + zabbix_item_key + ' ' + zabbix_item_value) 66 | 67 | def get_db_names(self): 68 | """get a list of DB names""" 69 | if self.__conn is None: 70 | self.connect() 71 | db_handler = self.__conn[self.mongo_db[0]] 72 | 73 | master = db_handler.command('isMaster')['ismaster'] 74 | dict_metrics = {} 75 | dict_metrics['key'] = 'mongodb.ismaster' 76 | if master: 77 | dict_metrics['value'] = 1 78 | db_names = self.__conn.database_names() 79 | self.__dbnames = db_names 80 | else: 81 | dict_metrics['value'] = 0 82 | self.__metrics.append(dict_metrics) 83 | 84 | def get_mongo_db_lld(self): 85 | """print DB list in json format, to be used for 86 | mongo db discovery in zabbix""" 87 | if self.__dbnames is None: 88 | db_names = self.get_db_names() 89 | else: 90 | db_names = self.__dbnames 91 | dict_metrics = {} 92 | db_list = [] 93 | dict_metrics['key'] = 'mongodb.discovery' 94 | dict_metrics['value'] = {"data": db_list} 95 | if db_names is not None: 96 | for db_name in db_names: 97 | dict_lld_metric = {} 98 | dict_lld_metric['{#MONGODBNAME}'] = db_name 99 | db_list.append(dict_lld_metric) 100 | dict_metrics['value'] = '{"data": ' + json.dumps(db_list) + '}' 101 | self.__metrics.insert(0, dict_metrics) 102 | 103 | def get_oplog(self): 104 | """get replica set oplog information""" 105 | if self.__conn is None: 106 | self.connect() 107 | db_handler = self.__conn['local'] 108 | 109 | coll = db_handler.oplog.rs 110 | 111 | op_first = (coll.find().sort('$natural', 1).limit(1)) 112 | op_last = (coll.find().sort('$natural', -1).limit(1)) 113 | 114 | # if host is not a member of replica set, without this check we will 115 | # raise StopIteration as guided in 116 | # http://api.mongodb.com/python/current/api/pymongo/cursor.html 117 | 118 | if op_first.count() > 0 and op_last.count() > 0: 119 | op_fst = (op_first.next())['ts'].time 120 | op_last_st = op_last[0]['ts'] 121 | op_lst = (op_last.next())['ts'].time 122 | 123 | status = round(float(op_lst - op_fst), 1) 124 | self.add_metrics('mongodb.oplog', status) 125 | 126 | current_time = timegm(gmtime()) 127 | oplog = int(((str(op_last_st).split('('))[1].split(','))[0]) 128 | self.add_metrics('mongodb.oplog-sync', (current_time - oplog)) 129 | 130 | 131 | def get_maintenance(self): 132 | """get replica set maintenance info""" 133 | if self.__conn is None: 134 | self.connect() 135 | db_handler = self.__conn 136 | 137 | fsync_locked = int(db_handler.is_locked) 138 | self.add_metrics('mongodb.fsync-locked', fsync_locked) 139 | 140 | try: 141 | config = db_handler.admin.command("replSetGetConfig", 1) 142 | connstring = (self.mongo_host + ':' + str(self.mongo_port)) 143 | connstrings = list() 144 | 145 | for i in range(0, len(config['config']['members'])): 146 | host = config['config']['members'][i]['host'] 147 | connstrings.append(host) 148 | 149 | if connstring in host: 150 | priority = config['config']['members'][i]['priority'] 151 | hidden = int(config['config']['members'][i]['hidden']) 152 | 153 | self.add_metrics('mongodb.priority', priority) 154 | self.add_metrics('mongodb.hidden', hidden) 155 | except errors.PyMongoError: 156 | print ('Error while fetching replica set configuration.' 157 | 'Not a member of replica set?') 158 | except UnboundLocalError: 159 | print ('Cannot use this mongo host: must be one of ' + ','.join(connstrings)) 160 | exit(1) 161 | 162 | def get_server_status_metrics(self): 163 | """get server status""" 164 | if self.__conn is None: 165 | self.connect() 166 | db_handler = self.__conn[self.mongo_db[0]] 167 | ss = db_handler.command('serverStatus') 168 | 169 | # db info 170 | self.add_metrics('mongodb.version', ss['version']) 171 | self.add_metrics('mongodb.storageEngine', ss['storageEngine']['name']) 172 | self.add_metrics('mongodb.uptime', int(ss['uptime'])) 173 | self.add_metrics('mongodb.okstatus', int(ss['ok'])) 174 | 175 | # asserts 176 | for k, v in ss['asserts'].items(): 177 | self.add_metrics('mongodb.asserts.' + k, v) 178 | 179 | # operations 180 | for k, v in ss['opcounters'].items(): 181 | self.add_metrics('mongodb.operation.' + k, v) 182 | 183 | # memory 184 | for k in ['resident', 'virtual', 'mapped', 'mappedWithJournal']: 185 | self.add_metrics('mongodb.memory.' + k, ss['mem'][k]) 186 | 187 | # connections 188 | for k, v in ss['connections'].items(): 189 | self.add_metrics('mongodb.connection.' + k, v) 190 | 191 | # network 192 | for k, v in ss['network'].items(): 193 | self.add_metrics('mongodb.network.' + k, v) 194 | 195 | # extra info 196 | self.add_metrics('mongodb.page.faults', 197 | ss['extra_info']['page_faults']) 198 | 199 | #wired tiger 200 | if ss['storageEngine']['name'] == 'wiredTiger': 201 | self.add_metrics('mongodb.used-cache', 202 | ss['wiredTiger']['cache'] 203 | ["bytes currently in the cache"]) 204 | self.add_metrics('mongodb.total-cache', 205 | ss['wiredTiger']['cache'] 206 | ["maximum bytes configured"]) 207 | self.add_metrics('mongodb.dirty-cache', 208 | ss['wiredTiger']['cache'] 209 | ["tracked dirty bytes in the cache"]) 210 | 211 | # global lock 212 | lock_total_time = ss['globalLock']['totalTime'] 213 | self.add_metrics('mongodb.globalLock.totalTime', lock_total_time) 214 | for k, v in ss['globalLock']['currentQueue'].items(): 215 | self.add_metrics('mongodb.globalLock.currentQueue.' + k, v) 216 | for k, v in ss['globalLock']['activeClients'].items(): 217 | self.add_metrics('mongodb.globalLock.activeClients.' + k, v) 218 | 219 | def get_db_stats_metrics(self): 220 | """get DB stats for each DB""" 221 | if self.__conn is None: 222 | self.connect() 223 | if self.__dbnames is None: 224 | self.get_db_names() 225 | if self.__dbnames is not None: 226 | for mongo_db in self.__dbnames: 227 | db_handler = self.__conn[mongo_db] 228 | dbs = db_handler.command('dbstats') 229 | for k, v in dbs.items(): 230 | if k in ['storageSize', 'ok', 'avgObjSize', 'indexes', 231 | 'objects', 'collections', 'fileSize', 232 | 'numExtents', 'dataSize', 'indexSize', 233 | 'nsSizeMB']: 234 | self.add_metrics('mongodb.stats.' + k + 235 | '[' + mongo_db + ']', int(v)) 236 | def close(self): 237 | """close connection to mongo""" 238 | if self.__conn is not None: 239 | self.__conn.close() 240 | 241 | if __name__ == '__main__': 242 | mongodb = MongoDB() 243 | mongodb.get_db_names() 244 | mongodb.get_mongo_db_lld() 245 | mongodb.get_oplog() 246 | mongodb.get_maintenance() 247 | mongodb.get_server_status_metrics() 248 | mongodb.get_db_stats_metrics() 249 | mongodb.print_metrics() 250 | mongodb.close() 251 | -------------------------------------------------------------------------------- /zabbix_agentd.d/userparameter_mongodb.conf: -------------------------------------------------------------------------------- 1 | # mongodb stats 2 | UserParameter=mongodb.zabbix.sender,/usr/local/bin/mongodb-stats.sh 3 | --------------------------------------------------------------------------------