一、需求

计算业务日志内一个接口请求的响应时间和超过1.5秒的数量,这里需要两个结果,因为有时间戳,打算每分钟运行一次脚本,计算上一分钟的日志信息。结果会传到falcon后由grafana展示

下面就是展示的结果,这是一个汇总图,三个节点,每个节点2个值,一共展示6个监控指标的数据,左侧是响应时间,右侧是超过1.5秒的数量
grafana

二、分享脚本内容如下
#!/usr/bin/env python
import os
import time
import commands
import requests
import json
import sys
import datetime

Time = time.strftime("%Y-%m-%d", time.localtime())
logtime = (datetime.datetime.now()+datetime.timedelta(minutes=-1)).strftime("%Y-%m-%d %H:%M")
Hosts = ['node01','node02','node02']

var = sys.argv[1]
for host in Hosts:
    str1 = "grep \"{logtime}\" /home/xxx.log.{Time}|grep {host}|awk -F = '{str}'".format(logtime=logtime,Time=Time,host=host,str="{sum+=$NF}END{print sum/NR}")
    str2 = "grep \"{logtime}\" /home/xxx.log.{Time}|awk -F = '$1~\"{host}\" && $NF>1500'|wc -l".format(logtime=logtime,Time=Time,host=host)

    if var == "restime":
        str = str1
    elif var == "timeoutnum":
        str = str2
    print str

    class Monitor():
        def __url(self):
            value1 = commands.getoutput(str)
            value = value1.split(".")[0]
            if value.isdigit():
                value = value
            else:
                value = int(0)
            return value
               
        def __falcon(self,value):
            payload_list = []
            ts = int(time.time())
            temp_dict = {
                "endpoint": host,
                "metric": "requestPay"+"_"+var,
                "timestamp": ts,
                "step": 60,
                "value":value,
                "counterType": "GAUGE",
                "tags": "requestPay",
            }
            payload_list.append(temp_dict)
            print temp_dict
            requests.post("http://192.168.xx.xx:1988/v1/push", data=json.dumps(payload_list))
    
        def go(self):
            result = self.__url()
            self.__falcon(result)
    
    value = Monitor()
    value.go()
三、说明
Time = time.strftime("%Y-%m-%d", time.localtime())

这行是使用服务器本地时间,格式为2019-01-01这样的格式,用于匹配文件名后缀,如xxx.log.2019-01-01

logtime = (datetime.datetime.now()+datetime.timedelta(minutes=-1)).strftime("%Y-%m-%d %H:%M")

这行是取当前时间上一分钟的时间,格式是2019-01-01 12:00,用于后面匹配日志时间戳,写shell使用的是下面的方法实现

# date --date="-1 minute" +%Y-%m-%d
2019-01-17

上面的时间函数是最近接触的,后面很多运维工作需要这样的方法

Hosts = ['node01','node02','node02']

这行是Hosts列表,假设现在有三个节点,那么我需要知道每个节点的监控数据,后面采用for循环读取列表内容

var = sys.argv[1]

读取脚本的第一个参数,这里针对两个监控指标分别设置一个参数,分别是restime、timeoutnum,代表响应时间和超时数量。

for host in Hosts:
    str1 = "grep \"{logtime}\" /home/xxx.log.{Time}|grep {host}|awk -F = '{str}'".format(logtime=logtime,Time=Time,host=host,str="{sum+=$NF}END{print sum/NR}")
    str2 = "grep \"{logtime}\" /home/xxx.log.{Time}|awk -F = '$1~\"{host}\" && $NF>1500'|wc -l".format(logtime=logtime,Time=Time,host=host)

使用for循环读取Hosts列表,因为后面上报数据的时候要带着节点信息,所以每次处理日志的时候需要搜索日志内的节点信息和监控数据,下面就是两个命令,目前分析日志只会这么用,囧!

    if var == "restime":
        str = str1
    elif var == "timeoutnum":
        str = str2
    print str

判断参数,如果restime就用str1分析日志,如果是timeoutnum就用str2分析日志

            value1 = commands.getoutput(str)
            value = value1.split(".")[0]

第一行是使用系统的命令,返回处理的结果
第二行是对取出的值进行分割,由于值是浮点数,所以用“.”分割取第一部分内容就是整数,这是split函数的用法,第一列[0],第二列[1],以此类推,当然如果不符合格式取出来有可能是其它信息,后面会进行判断

            if value.isdigit():
                value = value
            else:
                value = int(0)
            return value

这是一个if判断,看结果是否是整数。如果是整数value就不变,如果不是整数,那么赋值为0,由于接口不是每分钟都调用,所以一很多时候使用awk是报错了,那么这时候就认为没有值,所以是0

            temp_dict = {
                "endpoint": host,
                "metric": "requestPay"+"_"+var,
                "timestamp": ts,
                "step": 60,
                "value":value,
                "counterType": "GAUGE",
                "tags": "requestPay",
            }

注意这里endpoint的后面的host是个变量,就是上面for循环里面取到的Hosts值,这样在falcon就可以区分出来各个节点的监控数据了

下面的内容就是falcon上报的方法,网上很多介绍就是照葫芦画瓢,这里就不做介绍了

四、结果展示

cron里面的配置,每分钟一次上报到falcon

* * * * * cd /home/shell;python xxx.py restime;python xxx.py timeoutnum
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐