Как описано в комментариях выше, я сделал вам пример кода. Он основан на Redis , и я предлагаю вам запустить Redis на вашем узле менеджера кластера, который, предположительно, находится близко к узлам вашего кластера и всегда работает - так что хороший кандидат на статистику Служба сбора.
Пример кода - это фиктивное задание, написанное на Python , и подпрограмма мониторинга, написанная на bash
, но задание можно так же легко написать на C / C ++, а подпрограмму мониторинга - на Perl - есть все виды привязок для Redis - не зацикливайтесь на языке.
Даже если вы не умеете читать Python , это очень легко понять. Есть 3 потока, которые работают параллельно. Один просто обновляет string
в Redis с общим истекшим временем обработки. Два других обновления Redis lists
с данными временных рядов - синтезированной треугольной волны - одна работает на частоте 5 Гц, а другая - на частоте 1 Гц.
Я использовал строку Redis , где переменные не должны записывать историю, и список Redis , где нужна история. Другие структуры данных доступны.
В приведенном ниже коде только 3 интересные строки:
# Connect to Redis server by IP address/name
r = redis.Redis(host='localhost', port=6379, db=0)
# Set a Redis string called 'processTime' to value `processsTime`
r.set('processTime', processTime)
# Push a value to left end of Redis list
r.lpush(RedisKeyName, value)
Вот фиктивная работа, за которой следят. Начните читать там, где написано
######
# Main
######
Вот код:
#!/usr/local/bin/python3
import redis
import _thread
import time
import os
import random
################################################################################
# Separate thread periodically updating the 'processTime' in Redis
################################################################################
def processTimeThread():
"""Calculate time since we started and update every so often in Redis"""
start = time.time()
while True:
processTime = int(time.time() - start)
r.set('processTime', processTime)
time.sleep(0.2)
################################################################################
# Separate thread generating a times series and storing in Redis with the given
# name and update rate
################################################################################
def generateSeriesThread(RedisKeyName, interval):
"""Generate a saw-tooth time series and log to Redis"""
# Delete any values from previous runs
r.delete(RedisKeyName)
value = 0
inc = 1
while True:
# Generate next value and store in Redis
value = value + inc
r.lpush(RedisKeyName, value)
if value == 0:
inc = 1
if value == 10:
inc = -1
time.sleep(interval)
################################################################################
# Main
################################################################################
# Connect to Redis on local host - but could just as easily be on another machine
r = redis.Redis(host='localhost', port=6379, db=0)
# Get start time of job in RFC2822 format
startTime=time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
# ... and set Redis string "startTime"
r.set('startTime',startTime)
# Get process id (pid)
pid=os.getpid()
# ... and set Redis string "pid""
r.set('pid',pid)
# Start some threads generating data
_thread.start_new_thread( processTimeThread, () )
_thread.start_new_thread( generateSeriesThread, ('seriesA', 0.2) )
_thread.start_new_thread( generateSeriesThread, ('seriesB', 1) )
# Hang around (with threads still running) till user presses a key
key = input("Press Return/Enter to stop.")
Затем я написал сценарий мониторинга в bash
, который подключается к Redis, захватывает значения и отображает их на терминале в TUI (текстовом интерфейсе пользователя). Вы можете в равной степени использовать Python или Perl или PHP и в равной степени написать графический интерфейс или веб-интерфейс.
#!/bin/bash
################################################################################
# drawGraph
################################################################################
drawGraph(){
top=$1 ; shift
data=( "$@" )
for ((row=0;row<10;row++)) ; do
((y=10-row))
((screeny=top+row))
line=""
for ((col=0;col<30;col++)) ; do
char=" "
declare -i v
v=${data[col]}
[ $v -eq $y ] && char="X"
line="${line}${char}"
done
printf "$(tput cup $screeny 0)%s" "${line}"
done
}
# Save screen and clear and make cursor invisible
tput smcup
tput clear
tput civis
# Trap exit
trap 'exit 1' INT TERM
trap 'tput rmcup; tput clear' EXIT
while :; do
# Get processid from Redis and display
pid=$(redis-cli <<< "get pid")
printf "$(tput cup 0 0)ProcessId: $pid"
# Get process start time from Redis and display
startTime=$(redis-cli <<< "get startTime")
printf "$(tput cup 1 0)Start Time: $startTime"
# Get process running time from Redis and display
processTime=$(redis-cli <<< "get processTime")
printf "$(tput cup 2 0)Running Time: $(tput el)$processTime"
# Display seriesA last few values
seriesA=( $(redis-cli <<< "lrange seriesA 0 30") )
printf "$(tput cup 5 0)seriesA latest values: $(tput el)"
printf "%d " "${seriesA[@]}"
# Display seriesB last few values
seriesB=( $(redis-cli <<< "lrange seriesB 0 30") )
printf "$(tput cup 6 0)seriesB latest values: $(tput el)"
printf "%d " "${seriesB[@]}"
drawGraph 8 "${seriesA[@]}"
drawGraph 19 "${seriesB[@]}"
# Put cursor at bottom of screen and tell user how to quit
printf "$(tput cup 30 0)Hit Ctrl-C to quit"
done
Надеюсь, вы увидите, что вы можете очень легко получить структуры данных из Redis. Получается переменная processTime
, установленная в задании на узле кластера:
processTime=$(redis-cli <<< "get processTime")
TUI выглядит так: