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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章