前言
疫情以来,居家办公,闲来无事,折腾下telemetry协议相关的监控,现有资料大都只是展示了,如何采集数据,对于数据的处理很少提及,本文将数据处理部分补齐,方便读者更快速理解,关于telemetry协议,这里不做过多概述。值得注意的是现有的open-telemetry和本文中的telemetry还是有所不同,前者较为广义,主要讲框架,是可观察性的主要框架之一,本次实验中的telemetry协议较为狭义,仅为可观测中的metric部分做参考,我们可以从中管中窥豹,网络人龙混杂。不喜勿喷!
整体思路
本文以华为交换机为客户端,通过telemetry协议发送数据至接收端(python编写),然后转发至prometheus的pushgateway,通过grafana进行展示
大致过程如下:
1. 配置设备telemetry 静态订阅,(采集内容,推送对象,推送间隔),网络设备为客户端,接收端为服务端
静态订阅为推送模式(网络设备为客户端,向外推送),动态订阅为拉取模式(网络设备本身为服务端,需要设备上开启grpc服务)
2. 官网下载华为设备对应的proto文件(公共服务对应的proto文件,业务层对应的proto文件),编译proto文件得到服务器调用的方法。
3. 配置telemetry接收服务端
4. 数据推送至prometheus网关 -pushgateway
5. grafana 展示
配置过程
1.交换机配置(参考官网)
a.进入telemetry视图
b.配置推送目标
c.配置设备采样数据
d.创建静态订阅
2.proto文件使用
用途:根据proto文件用来解析服务调用及接收方法。
使用run_codegen.py脚本编译proto文件(https://github.com/grpc/grpc/blob/v1.45.0/examples/python/route_guide/run_codegen.py)
解析前环境配置(服务端):
安装解析proto文件依赖
pip3 install grpcio grpcio-tools
run_codegen.py文件(华为proto中需解析huawei-telemetry.proto,huawei-grpc-dialout.proto,这两个文件提供公共的解析方法调用)
# Copyright 2015 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Runs protoc with the gRPC plugin to generate messages and gRPC stubs."""
from grpc_tools import protoc
protoc.main((
'',
'-I./protos',
'--python_out=.',
'--grpc_python_out=.',
'./protos/huawei-ifm.proto',
))
protoc.main((
'',
'-I./protos',
'--python_out=.',
'--grpc_python_out=.',
'./protos/huawei-debug.proto',
))
protoc.main((
'',
'-I./protos',
'--python_out=.',
'--grpc_python_out=.',
'./protos/huawei-telemetry.proto',
))
protoc.main((
'',
'-I./protos',
'--python_out=.',
'--grpc_python_out=.',
'./protos/huawei-grpc-dialout.proto',
))
执行python3 run_codegen.py,同目录生成相应的包文件
3. 服务端配置:
prometheus及相关组件见后续章节:
server.py
#!/usr/bin/python3
# _*_ coding: UTF-8 _*_
# Copyright (c) 2021 GengYu.All rights reserved
# @Create by jerry
# @Create Time :2022/04/10
# @File Name : telemetry
"""
"""
__author__ = 'jerry'
# import doctest
from ast import parse
from email import contentmanager
import requests
import prometheus_client
from prometheus_client import Counter
from prometheus_client import Gauge
from prometheus_client.core import CollectorRegistry
import requests
from concurrent import futures
import time
import importlib
#pip 安装 pip3 install grpcio grpcio-tools
import grpc
#run_codegen.py 参考网站https://github.com/grpc/grpc/blob/v1.45.0/examples/python/route_guide/run_codegen.py)
import huawei_grpc_dialout_pb2_grpc
import huawei_telemetry_pb2 #generate_codes.py生成
registry = CollectorRegistry(auto_describe=False)
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
def tele_server():
#创建一个grpc server对象
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
#注册huawei的telemetry 数据监听服务
huawei_grpc_dialout_pb2_grpc.add_gRPCDataserviceServicer_to_server(
Telemetry_Info(),server)
#设置socket监听端口和PC的IP地址,与交换机中推送目标IP地址一致
server.add_insecure_port('ip:端口')
#启动 grpc server
server.start()
#死循环监听
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
def is_number(s):
try:
float(s)
return True
except ValueError:
pass
try:
import unicodedata
unicodedata.numeric(s)
return True
except (TypeError, ValueError):
pass
return False
#add,用于网关推送
def to_prom_gateway(labelValue,parsedata):
labels=["product_name","subscription_id_str","sensor_path","instance"]
jobName="pushgateway"
url="http://prometheus网关IP:9091/metrics"
param=''
#telemetry数据格式处理
for i in parsedata.split('\n'):
if '{' in i:
str="".join(i.replace('{','_').split())
param+=str
continue
if ':' in i:
key=param+i.split(':')[0].strip()
value=i.split(':')[1].strip()
# print(type(value))
if is_number(value):
g = Gauge(key,"" ,labels ,registry=registry)
g.labels(product_name=labelValue[0],subscription_id_str=labelValue[1],sensor_path=labelValue[2],instance=labelValue[3]).inc(float(value))
requests.post("%s/job/%s" %(url,jobName),data=prometheus_client.generate_latest(registry))
# print(value)
continue
#创建类继承huawei_grpc_dialout_pb2_grpc中的Servicer方法,参考官网
class Telemetry_Info(huawei_grpc_dialout_pb2_grpc.gRPCDataserviceServicer):
def __init__(self):
return
def dataPublish(self, request_iterator, context):
for i in request_iterator:
# print('________________________ start ________________________')
telemetry_data = huawei_telemetry_pb2.Telemetry.FromString(i.data)
# print(telemetry_data)
labels=[telemetry_data.product_name,telemetry_data.subscription_id_str,telemetry_data.sensor_path,telemetry_data.node_id_str]
for row_data in telemetry_data.data_gpb.row:
module_name = telemetry_data.proto_path.split('.')[0]
root_class = telemetry_data.proto_path.split('.')[1]
#动态加载telemetry 获取数据的对应模块.
decode_module = importlib.import_module(module_name + '_pb2')
#定义解码方法:getattr获取动态加载的模块中的属性值,调用此属性的解码方法FromString
decode_func = getattr(decode_module,root_class).FromString
parsedata=decode_func(row_data.content)
to_prom_gateway(labelValue=labels,parsedata=parsedata)
# timestamp=row_data.timestamp
if __name__ == "__main__":
tele_server()
执行server.py
python3 server.py
附:telemetry数据格式如下
_ start -----------
node_id_str: "test-R1"
subscription_id_str: "subscription1"
sensor_path: "huawei-debug:debug/memory-infos/memory-info"
collection_id: 1647801
collection_start_time: 1649657530145
msg_timestamp: 1649657530303
data_gpb {
row {
timestamp: 1649657530287
content: "\032_\n]\n\0011\020Z\030K \201\200\204\010(\X\257E`ah\324\201\001p\225gx\277\032\200\001O\212\001\0230
}
row {
timestamp: 1649657530287
content: "\032_\n]\n\0012\020Z\030K \201\200\210\010(\3X\241Q``h\351\202\001p\327gx\222\033\200\001O\212\001\023
}
row {
timestamp: 1649657530287
content: "\032`\n^\n\0014\020Z\030K \201\200\220\010(\56\252\001`\\h\362\254\001p\303Gx\257e\200\001)\212\001\02
}
row {
timestamp: 1649657530287
content: "\032_\n]\n\0015\020Z\030K \201\200\224\010(\225\301\001`Xh\257yp\254/x\203J\200\001\'\212\001\0230000-
}
}
collection_end_time: 1649657530303
current_period: 1000
except_desc: "OK"
product_name: "NE40E"
proto_path: "huawei_debug.Debug"
________________________
The proto path is :huawei_debug.Debug
________________________
<module 'huawei_debug_pb2' from '/opt/telemetry/huawei_deb
________________________ content is ______________________
memory_infos {
memory_info {
position: "1"
overload_threshold: 90
unoverload_threshold: 75
index: 16842753
os_memory_total: 963496
os_memory_use: 622712
os_memory_free: 340784
os_memory_usage: 64
do_memory_total: 319607
do_memory_use: 310728
do_memory_free: 8879
do_memory_usage: 97
simple_memory_total: 16596
simple_memory_use: 13205
simple_memory_free: 3391
simple_memory_usage: 79
overload_state_change_time: "0000-00-00 00:00:00"
current_overload_state: "Unoverload"
memreli_notice_threshold: 85
memreli_overload_threshold: 90
}
}
________________________ done ________________________
________________________
效果查看:
prometheus 查看指标
4. grafana查看
grafana中添加prometheus数据源
登录grafana->explorer进行验证查看,后续可通过dashboard进行统一展示
后续可根据告警模块设置相应的告警。
部署Prometheus+grafana+pushGateway
docker部署Prometheus
docker 安装略
创建prometheus.yml
mkdir /opt/prom
touch /opt/prom/rules.yml
vi /pot/prom/prometheus.yml
global:
scrape_interval:
external_labels:
monitor: 'codelab-monitor'
# 这里表示抓取对象的配置
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node_exporter'
static_configs:
- targets: ['10.158.1.211:9100']
启动服务器
docker run --name prometheus -p 9090:9090 --restart=always \
-v /opt/prom/prometheus.yml:/etc/prometheus/prometheus.yml \
-v /opt/prom/rules.yml:/etc/prometheus/rules.yml \
-itd prom/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--web.enable-lifecycle
部署node_exporter-客户端安装(可选)
docker run --name=node-exporter -p 9100:9100 -itd prom/node-exporter
部署grafana
docker run --name=grafana -p 3000:3000 -itd grafana/grafana
docker cp grafana:/etc/grafana/grafana.ini /opt/prom/grafana/
docker rm -f grafana
chmod 777 /opt/prom/*
docker run -p 3000:3000 --name grafana --restart=always \
-v /opt/grafana/grafana.ini:/etc/grafana/grafana.ini \
-v /opt/grafana/data:/var/lib/grafana \
-itd grafana/grafana
部署pushgateway
docker run -d --name=pgw -p 9091:9091 prom/pushgateway
服务端修改prometheus.yml文件
添加
- job_name: 'pushgateway'
static_configs:
- targets: ['10.158.1.211:9091']
labels:
instance: telepushgateway
验证
docker部署的组件可用docker ps进行查看容器是否启用。
或通过ip:port进行验证,查看端口等。
至此,基于telemetry协议的数据从采集->处理->展示基本结束,大家有兴趣可以更深一步交流
待改进
接收端侧需添加守护进程
添加通用规则用于处理prometheus的labels
时间的处理。prometheus时间与telemetry中的时间有差异
...
总结
通过对此协议的监控探索,因telemetry可以提供亚秒级数据,监控精度有了质的提升,对于敏感度要求较高的用户比较适用。telemetry同样需要专业的工具支持才能发挥其特长。
对于告警的支持,暂时还是分钟级比较适用点,至于数据存储及性能瓶颈,并没有相关说明,毕竟设备侧重心在如何产生数据,不关心后台存储的问题
总之,从监控侧来看,现在说telemetry的推广应用,除了厂商自己内部产品外,如果要做成通用的,还需要一段路。。。