Browse Source

support remote cpu stat

master
Ralph Rönnquist 5 months ago
committed by root
parent
commit
5a313cbc1d
  1. 6
      cgroup2report
  2. 130
      cgroups2listener.lsp

6
cgroup2report

@ -0,0 +1,6 @@
#!/bin/bash
#
# Send a cpu.stat reading as udp message to go past dev1nsd_br on nash
echo "$(hostname -s) $(grep usage /sys/fs/cgroup/cpu.stat)" | \
socat - udp-datagram:10.0.10.2:519,broadcast

130
cgroups2listener.lsp

@ -0,0 +1,130 @@
#!/usr/bin/newlisp
#
# Use pcap to sniff out cpu.stat usage messages on an interface, and
# add them into /var/cache/rwhodsnap/loadhistories2.sqlite
(constant
'HOSTS '("borta" "mini")
'IFACE "dev1nsd_br"
'DB "/var/cache/rwhodsnap/loadhistories2.sqlite"
'LOCK "/run/lock/cgroups2listener.lock"
)
(unless (= (! (format "flock -n %d" (open LOCK "w")))) (exit 0))
############################################################
(constant
'ALIAS (filter list? HOSTS)
'HOSTS (union (clean list? HOSTS) (map first ALIAS))
'PCAPLIB "/usr/lib/x86_64-linux-gnu/libpcap.so"
'PCAP_CHAR_ENC_LOCAL 0
'PCAP_CHAR_ENC_UTF_8 1
)
(define (die)
(write-line 2 (join (map string (args)) " "))
(exit 1))
(setf ERRBUF (dup "\0" 356))
;(import PCAPLIB "pcap_init" "int" "int" "char*")
(import PCAPLIB "pcap_open_live" "void*" "char*" "int" "int" "int" "char*")
(import PCAPLIB "pcap_loop" "int" "void*" "int" "void*" "void*")
;; syntax helper
(define (estruct NAME)
(apply struct (cons NAME (map string (flat (args))))))
;; /usr/include/linux/time.h
(struct 'timeval "long" "long" ) ;; (seconds microseconds)
;; /usr/include/pcap/pcap.h
(struct 'bpf_u_int32 "unsigned int")
(struct 'pcap_pkthdr "timeval" "bpf_u_int32" "bpf_u_int32" )
;; = ( time ( capture-length ) ( actual-length ) )
(define (pcap_handling RECEIVER (LIMIT 10) (SNAP 500))
(letn ((RECEIVER_FN RECEIVER)
;; no return value ( userdata struct pcap_pkthdr* unsigned char* )
(CALLBACK (callback RECEIVER_FN "void" "void*" "void*" "void*" )))
(when (= (setf HANDLE (pcap_open_live IFACE SNAP 0 0 ERRBUF)))
(die "pcap_open_live" ERRBUF))
(when (!= (setf RET (pcap_loop HANDLE LIMIT CALLBACK 0)))
(die "pcap_loop" RET))
))
(estruct 'macaddr (dup 'byte 6))
(estruct 'ethertype (dup 'byte 2))
(struct 'ether_head "macaddr" "macaddr" "ethertype" )
;; = ( ( destination-mac ) ( source-mac ) ( ether-type ) )
(estruct 'ipv4addr (dup 'byte 4))
(struct 'byte2 "byte" "byte")
(struct 'uint16 "unsigned short int") ;
(define (ntohs S) (unpack ">u" (address S)))
(struct 'ipv4_head
"byte2" "uint16" ;; Version[4] IHL[4] DSCP[6] ECV[2] Length[16]
"uint16" "uint16" ;; Identification[16] Flags[3] Fragment-offset[13]
"byte" "byte" "uint16" ;; TTL protocol header-checksum
"ipv4addr" ;; source IP
"ipv4addr" ;; destinetion IP
)
(define (sql)
(exec (format "echo \".timeout 5000\n%s\" | sqlite3 %s"
(join (map string (args)) " ") DB)))
;; CREATE TABLE history(host,minute,load,primary key(host,minute));
;; CREATE TABLE measure(host,value,primary key(host));
(define (update HOST NEW)
;(write-line 2 (string (list 'update HOST NEW)))
(letn ((OLDX (sql (format "select value from measure where host='%s'" HOST)))
(OLD (if (null? OLDX) 0 (int (OLDX 0))))
(MINUTE (/ (date-value) 60))
(RATE (* 3 60))
(L (int (div (sub NEW OLD) RATE))) )
;(println (list HOST NEW OLD L))
(sql (format "insert or replace into measure values('%s','%ld');\n"
HOST NEW)
(format "insert into history values('%s','%ld','%ld');\n"
HOST MINUTE L))))
;; Save cpu.stat report
(define (receive_stat BYTES LEN)
;(write-line 2 (string (list 'receive_stat LEN (unpack "s40" BYTES))))
(when (regex "([^ ]+) usage_usec ([0-9]+)" ((unpack "s40" BYTES) 0) 0)
(let ((HOST $1) (VALUE $2))
(when (member HOST HOSTS)
(update HOST (bigint VALUE))))))
(constant 'udp_head ">uuuu"); loading data into host order
;; = ( source-port destination-port payload-length udp-checksum )
(define (receive_udp BYTES LEN)
(let ((HDR (unpack udp_head BYTES)))
;(write-line 2 (string (list 'receive_udp HDR)))
(when (match '(? 519 ? ?) HDR) ;; destport=519
(receive_stat (+ BYTES 8) (- LEN 8)))
))
(define (receive_ipv4 BYTES LEN REAL)
(letn ((HDR (unpack ipv4_head BYTES))
(SZ (* 4 (& (HDR 0 0) 0xf))))
;(write-line 2 (string (list 'receive_ipv4 SZ HDR)))
(when (and (= LEN REAL) (= (HDR 5) 17))
(receive_udp (+ BYTES SZ) (- LEN SZ))
)))
(define (receive_packet USERDATA PKTHDR BYTES)
(let ((HDR (unpack pcap_pkthdr PKTHDR))
(MAC (unpack ether_head BYTES)))
;(write-line 2 (string (list 'receive_packet MAC HDR)))
(when (and (> (HDR 1 0) 34) (= '(8 0) (MAC 2)))
(receive_ipv4 (+ BYTES 14) (- (HDR 1 0) 14) (- (HDR 2 0) 14)))
))
;;; Main program
(pcap_handling 'receive_packet 0)
(exit 0)
Loading…
Cancel
Save