为了账号安全,请及时绑定邮箱和手机立即绑定

利用zabbix生成awstats日志分析图表并用Python调用zabbix API批量添加item

标签:
Python


    awstats作为一款日志分析软件,功能不错,但是界面过于简单,也没有图表功能,这里我采取了一种变通的方法,将awstats的分析结果(pv、hits(文件数)、bandwidth、visits(独立ip))添加到zabbix,并通过zabbix生成趋势图表。

    在前两篇文章中,我们队awstats的使用及其工作方式进行了简明扼要的介绍:awstats对每个站点进行分析之后,会生成一个“awstats012016.txt”格式的“数据库”文件;awstats的展示页面便是从该文件中取数据生成的。

    1. 多server多站点情况下awstats日志分析

    2. awstats CGI模式下动态生成页面缓慢的改进

    这篇文章的思路就是从这个文本格式的‘数据库文件’中取得我们想要的数据,然后通过自定义的脚本将其添加到zabbix中,最终满足我们生成pv趋势图表的需求。

    而完成此任务的关键就是分析似‘awstats052016.txt’的数据文件的内容格式(ps:以笔者“多年”shell经验来看,”分析源文件格式“和“生成目标文件格式”这俩“格式”在日常的shell编程中占用了很大一部分时间。扯远了O(∩_∩)O~)

    首先是自定义脚本作为zabbix的key,从对应的‘数据文件’中取得pv、hits、bandwidth、visits的值。用shell实现如下

cat web_pv.sh

#!/bin/sh

#从例如api/awstats052016.txt这样的awstats数据库文件里取得昨天的pv等统计(因为awstats本身就是统计到昨天的日志)

#by  ljk  20160506

#blog    http://kaifly.blog.51cto.com/

#shell脚本的$1 $2分别代表站点名称(格式如www或bbs)和统计项(pv 文件数 字节 独立ip)

basedir='/usr/local/awstats-7.4/result'

date_f1=$(date +%m%Y -d '1 day ago')

date_f2=$(date +%Y%m%d -d '1 day ago')

cd $basedir/$1

#下面关于awk的用法中有一个小技巧,匹配到指定的项之后,停止继续搜索余下的内容。这对于体积较大的文件可以节约不少时间

content=`awk '$1 == "'$date_f2'" {{print} {exit}}' awstats$date_f1\.txt`

case $2 in

    "pages")

        echo $content|awk '{print $2}';;    #pv

    "hits")

        echo $content|awk '{print $3}';;    #hits/文件数

    "bandwidth")

        echo $content|awk '{print $4}';;    #bandwidth/字节

    "visits")

        echo $content|awk '{print $5}';;    #visits/独立ip

    *)

        echo "unknow value";;

esac

然后在awstats所在的server的zabbix的‘userparameter.conf’文件中添用户自定义key,并重启zabbix_agentd

UserParameter=web_pv[*],/bin/sh /usr/local/zabbix/etc/zabbix_agentd.conf.d/web_pv.sh $1 $2

接着在zabbix_server端通过zabbix_get命令尝试获取这些值,key格式为“web_pv[站点名,监控项]”,例如

wKioL1czRTXDNt-9AAA2gArdX7k085.png

能取到值,说明自定义key是ok的。

    接下来就是在zabbix里添加各站点的item了,这里通过Python实现(zbx接口通过json传递数据,处理json python比shell方便太多了)

    这里需要仔细阅读下zabbix的api文档https://www.zabbix.com/documentation/3.0/manual/api和查看zabbix数据库结构(确保万无一失嘛)

    首先在zabbix里创建一个template,名为Template site PV,这一步手动创建即可

然后开始通过Python自动化添加items

cat shells/add_web-pv_item_to_zabbix.py

#!/bin/env python3

"""

将各站点的4种(pages,hits,bandwidth,visits)item添加/更新到zabbix的 'Template Site-PV'

by ljk  20160507

"""

import os,requests

basedir='/usr/local/services/awstats-7.4/result/'

items=['pages','hits','bandwidth','visits']

url='http://192.168.1.199/api_jsonrpc.php'

zbx_api_headers={'Content-Type':'application/json-rpc'}    #定义通过zabbix api操作时必带的header

#取得用于zabbix api认证的token,通过用户名密码请求api生成

#生成方式请参考api文档,有个这个token,可以省去账号密码认证

api_auth="738024dfda33cc6020fb1f5e3617" 

#这里我在前期实验的时候,手动添加了几个item了,所以这里先取出template里已经存在的item,以便后期创建时过滤掉这些item

exist_items_filter={    #通过zabbix api查询已经存在的web_pv[*,*]的item,这里是json格式的过滤条件

    "jsonrpc": "2.0",

    "method": "item.get",

    "params": {

        "output":[

            "name",

        ],

        "search": {

            "key_":"web_pv"

        }

    },

    "auth":api_auth,

    "id": 0

}

exist_items=requests.post(url,headers=zbx_api_headers,json=exist_items_filter)

os.chdir(basedir)

sites=os.listdir(path='.')

def create_item():

    for site in sites:

        for item in items:

            if site+'-'+item not in exist_items.text:

                #先给不同情况下的units和multiplier赋值

                if item=='pages' or item=='hits':

                    units='万'

                    multiplier=0.0001

                elif item=='bandwidth':

                    units='B'

                    multiplier=1

                else:

                    units=''

                    multiplier=1

                #定义创建item的json数据格式

                num=10

                create_item_post={

                    "jsonrpc": "2.0",

                    "method": "item.create",

                    "params": {

                        "name": site+','+item,

                        "key_": "www_pv["+site+','+item+"]",

                        "hostid": "10134",

                        "type": 0,

                        "value_type": 3,

                        "history": 7,

                        "delay": 28800,

                        "units": units,

                        "applications": [774],

                        "interfaceid": "0",

                        "formula": multiplier

                    },

                    "auth": api_auth,

                    "id": num

                }

                try:

                    create_item_result=requests.post(url,headers=zbx_api_headers,json=create_item_post)            

                    #打印处理每个条目的结果

                    print('{}-{}: return_code {} details {}'.format(site,item,create_item_result.status_code,create_item_result.json))

                    num+=1

                except:

                    print('{}-{}: error'.format(site,item))

                    import sys

                    sys.exit(255)

#create_item()

#update函数,其实是我在执行create_item()的时候将key的名字写错了,无奈在写一个update_item()吧

def update_item():

    num=100    #对应zbx api中的id字段,随意指定,确保每次调用api时该值不同即可(这里用自增的方式)

    #定义更新item的json数据格式

    update={

        "jsonrpc": "2.0",

        "method": "item.update",

        "params": {

            "itemid": "",

            "key_": ""

        },

        "auth": api_auth,

        "id": num

    }

    #取得site pv模板下所有错误的item(key以www_py开头的),hostid的值实际为template site PV模板的templateid

    wrong_items_filter={

            "jsonrpc": "2.0",

            "method": "item.get",

            "params": {

               "output":["key_","hostid"],

                "search": {"hostid":"10134","key_":"www_pv"}

            },

            "auth": api_auth,

            "id": 0

        }

    wrong_items=requests.post(url,headers=zbx_api_headers,json=wrong_items_filter).json()['result']    #wrong_items为list

    for wrong_item in wrong_items:

        if wrong_item['hostid'] != '10119':    #img2从template site pv继承而来 所以这里每个item对应两条记录对应template site pv的hostid:10134和img2的hostid:10119,所以不需要修改img2的

            update['params']['itemid']=wrong_item['itemid']

            update['params']['key_']=wrong_item['key_'].replace('www','web',1)            

            try:

                update_item_result=requests.post(url,headers=zbx_api_headers,json=update)

                print('{} ---- details {}'.format(wrong_item['key_'],update_item_result.json()))

                num+=1

            except:

                print('{}-{}: error'.format(site,item))

                import sys

                sys.exit(255)

#update_item()

    后续的批量生成image和生成screen都可以通过zbx 的API来完成,这里就不再列举了  

    ok,最后看两张zabbix生成的靓图吧

wKiom1cz7y3gx8H_AAFbYDcLV3Q395.png

wKiom1cz77qSrYKWAAGSoXMhnv4994.png

©著作权归作者所有:来自51CTO博客作者kai404的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消