python 发送grafana dashboard 面板内容截图到飞书群

需求

每天定时发送grafana dashboard截图至飞书群,每天获取前一天的算力服务器使用率趋势图

环境

  • docker 环境
# 搭建docker环境、配置grafana
#cat docker-compose.yaml 
version: '3.5'
services:
 grafana:
  image: grafana/grafana:latest
  restart: always
  ports:
   - "3001:3000"
  volumes:
   - /etc/localtime:/etc/localtime:ro
   - /etc/timezone:/etc/timezone:ro
   - /data/grafana-docker-compose/grafana:/var/lib/grafana
  environment:
   - GF_RENDERING_SERVER_URL=http://renderer:8081/render
   - GF_RENDERING_CALLBACK_URL=http://grafana:3000/

 renderer:
  image: grafana/grafana-image-renderer:latest
  restart: always
  ports:
   - 8081
  volumes:
   - /etc/localtime:/etc/localtime:ro
   - /etc/timezone:/etc/timezone:ro
  environment:
   - GF_RENDERER_PLUGIN_TZ=Asia/Shanghai
   - GF_RENDERER_PLUGIN_IGNORE_HTTPS_ERRORS=true

  • 查看grafana http://127.0.0.1:3001 (要有选中的这个按钮) ,点击后会有单独的截图页面,证明grafana截图能力没有问题


  • grafana 生成 service account token

飞书设置

  • 飞书开发者后台要创建企业自建应用
#添加机器人 应用能力
# 权限管理要增加 获取与上传图片或文件资源的权限


代码

# 获取时间戳
import json
import re
import sys
import datetime
import time,requests
from requests_toolbelt import MultipartEncoder

def get_time():
    t = datetime.datetime.now()
    # 当前日期
    t1 = t.strftime('%Y-%m-%d %H:%M:%S')
    # 转为秒级时间戳
    ts1 = time.mktime(time.strptime(t1, '%Y-%m-%d %H:%M:%S'))
    # 转为毫秒级
    end_time = int(str(ts1 * 1000).split(".")[0])

    # 24小时前
    t2 = (t - datetime.timedelta(hours=24)).strftime("%Y-%m-%d %H:%M:%S")
    # 转为秒级时间戳
    ts2 = time.mktime(time.strptime(t2, '%Y-%m-%d %H:%M:%S'))
    # 转为毫秒级
    start_time = int(str(ts2 * 1000).split(".")[0])
    return str(start_time), str(end_time)


# 下载pic
# width=1500&height=1600 这是宽、高设置
def download_pic():
    grafana_server = "http://127.0.0.1:3001"
    url = (grafana_server + '/render/d/cc92c73d-d285-496f-a370-27f857ca/5LmxxxK6v6ZuG576k5Yip546H' +
           '?orgId=1&from=' +
           get_time()[0] + '&to=' + get_time()[1] +
           "&panelId=30&width=1500&height=1600&tz=Asia%2FShanghai"
           )
    print(url)

    header = {"Content-Type": "application/json", "Authorization": "Bearer glsa_xxx"}  # 用管理员去Grafana生成API Key (即上步骤生成的service account token )
    res = requests.get(url, headers=header)
    time_now = int(time.time())
    time_local = time.localtime(time_now)
    dt = time.strftime("%Y-%m-%d", time_local)
    img_name = "img" + dt + ".jpg"
    filename = img_name
    with open(filename, "wb") as f:
        f.write(res.content)

        return filename



def send_message():
    time_now = int(time.time())
    time_local = time.localtime(time_now)
    dt = time.strftime("%Y-%m-%d", time_local)
    img_name = "img" + dt + ".jpg"
    print('图片名称: %s' %img_name)
    # 获取 tenant_access_token
    #在飞书自建的应用里找到 App ID 、和App Secret
    url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"
    data = {"app_id": "xxx","app_secret": "xxx"}  # 在飞书自建应用里可以查看
    header = {"content-type":"application/json", "charset":"utf-8"}
    res = requests.post(url,headers=header,json=data)
    # print(type(res.json()))
    #print(res.json()['tenant_access_token'])
    image_tenant_access_token = res.json()['tenant_access_token']
    print('image_tenant_access_token:',image_tenant_access_token)
    print("------------------")

    # 使用tenant_access_token上传图片
    upload_image_url = "https://open.feishu.cn/open-apis/im/v1/images"
    upload_image_header = {"Authorization":"Bearer %s"%image_tenant_access_token}
    #form = {"image_type": "message","image":("img2024-02-25.jpg",open('img2024-02-25.jpg','rb'))}
    form = {"image_type": "message","image":(img_name,open(img_name,'rb'))}
    multi_form = MultipartEncoder(form)
    upload_image_header['Content-Type'] = multi_form.content_type
    upload_image_res = requests.request("POST",url=upload_image_url,headers=upload_image_header,data=multi_form)
    upload_image_res_dict = upload_image_res.json()
    image_key = upload_image_res_dict['data']['image_key']
    print('image_key:',image_key)
    print("-----------------")

    # 使用image_key 发送图片, robot_url 为飞书群里自建的机器人 hook地址
    robot_url = "https://open.feishu.cn/open-apis/bot/v2/hook/xxx"
    robot_data = {"msg_type":"image","content":{"image_key": "%s"%image_key}}
    robot_header = {"Content-Type": "application/json"}
    robot_res = requests.post(headers=robot_header,url=robot_url,json=robot_data)
    print(robot_res.text)

def Alarm(img,message,computerroom):
    data = {
            "msg_type": "interactive",
            "card": {
                "elements": [{
                    "tag": "div",
                    "text": {
                        "content": "<font color='grey'> **%s** </font>"  %img,
                        "tag": "lark_md",
                        }
                    } ,{
                        "tag": "div",
                        "text": {
                            "content": "<font color='grey'> %s </font>" %message,
                            "tag": "lark_md"
                            }
                        } , {
                            "tag": "div",
                            "text": {
                                "content": "消息平台: 阿里云\n运维团队: DeepLang\n机房信息: %s"  %(computerroom),
                                "tag": "lark_md"
                                }
                            }, ],
                        "header": {
                            "title": {
                                "content": "机房GPU使用率信息",
                                "tag": "plain_text"
                                },
                            "template": "red"
                            }
                        }
            }
    url='https://open.feishu.cn/open-apis/bot/v2/hook/xxx'
    header = {
            'Content - Type': 'application / json'
            }
    data = json.dumps(data)
    return requests.post(url,data,header)

if __name__ == '__main__':
    #发送告警信息
    img="GPU使用率信息"
    message="前一天GTPU使用率信息"
    computerroom="机房"
    Alarm(img,message,computerroom)
    #下载图片
    download_pic()
    #发送图片
    send_message()

  • 运行后结果

  • crontab定时任务可自行设置

00 10 * * * python3 /opt/scripts/gpu/gpuutil.py > /dev/null
posted @ 2024-02-26 22:03  lixinliang  阅读(484)  评论(0编辑  收藏  举报