From 8b6154e92b39be265186c82ed0112d0926ae047c Mon Sep 17 00:00:00 2001 From: Immae Date: Sun, 8 Jun 2014 14:59:53 +0200 Subject: [PATCH] initial --- monitor.rb | 405 +++++++++++++++++++++++++++++++++++++++++++++++++++++ monitorrc | 35 +++++ 2 files changed, 440 insertions(+) create mode 100644 monitor.rb create mode 100644 monitorrc diff --git a/monitor.rb b/monitor.rb new file mode 100644 index 0000000..5e32cf2 --- /dev/null +++ b/monitor.rb @@ -0,0 +1,405 @@ +#!/usr/bin/env ruby + +require "time" +require "ncurses" +require "inifile" +require "open3" + +class IO + def readline_nonblock + buffer = "" + buffer << read_nonblock(1) while buffer[-1] != "\n" + buffer + rescue IO::WaitReadable => blocking + if (not buffer.empty?) + ungetc(buffer) + end + raise blocking + end +end + +class List_Win + def initialize(inifile) + @params = inifile + @win = Ncurses::WINDOW.new(0, Ncurses.COLS()/4, 0, 0) + @win.border(*([0]*8)) + @win.keypad(true) + @win.timeout(1000) + @win.refresh() + @entry = 0 + end + + def getch() + @win.getch() + end + def clear() + @win.clear() + end + def resize(x,y) + @win.resize(x,y) + end + def move(x,y) + @win.move(x,y) + end + def refresh() + @win.refresh() + end + + def print_list(entry=nil) + if(not entry.nil?) + @entry = entry + end + i = 0 + @params.each_section do |section| + if(@entry == i) + @win.attron(Ncurses::A_REVERSE) + end + @win.move(i+1,1) + print_line(@win,@params[section]['Name']) + if(@entry == i) + @win.attroff(Ncurses::A_REVERSE) + end + i = i+1 + end + @win.border(*([0]*8)) + @win.move(0,3) + @win.addstr("Menu") + @win.refresh() + end +end + +class Buff_Win + def initialize(winsize,winpos,params) + @params = params + @win = Ncurses::WINDOW.new(0, winsize, 0, winpos) + @panel = Ncurses::Panel::PANEL.new(@win) + if(@params['Type'] == 'oneshot') + @buffer = Buffer.new(0) + else + @buffer = Buffer.new(@params['Buffer'].to_i) + end + @proc = nil + @curr_offset = 0 + @hscroll = 0 + update_date() + + spawn_proc() + print_buffer() + end + + def move_resize(winsize,winpos) + newwin = Ncurses::WINDOW.new(0, winsize, 0, winpos) + Ncurses::Panel.replace_panel(@panel, newwin) + Ncurses.delwin(@win) + @win = newwin + print_buffer() + end + def update_date() + @last_update = Time.now + @date = @last_update.strftime("%F %R:%S") + end + + def win_border() + @win.border(*([0]*8)) + win_header() + end + def win_header() + @win.move(0,3) + @win.addnstr(@params['Name'],@win.getmaxx-@date.length-10) + @win.move(0,@win.getmaxx-@date.length-2) + @win.addstr(@date) + end + def refresh() + @win.refresh() + end + def clear() + @win.clear() + end + + def show_win() + Ncurses::Panel.top_panel(@panel) + Ncurses::Panel.update_panels + end + + def hscroll(scroll=0) + @hscroll += scroll + if(@hscroll < 0) + @hscroll = 0 + end + if(@hscroll > @buffer.maxlen()-@win.getmaxx+3) + @hscroll = @buffer.maxlen()-@win.getmaxx+3 + end + print_buffer() + refresh() + end + def scroll(scroll=0,goto=nil,fact=nil) + if (not fact.nil?) + scroll = (fact * @win.getmaxy.to_f).to_i + elsif (not goto.nil?) + @curr_offset = (goto * @buffer.size()).to_i + scroll = 0 + end + #@curr_offset -= @win.getmaxy/2 + @curr_offset += scroll + if(@curr_offset < 0) + @curr_offset = 0 + end + if(@curr_offset > @buffer.size()-@win.getmaxy+2) + @curr_offset = @buffer.size()-@win.getmaxy+2 + end + print_buffer() + refresh() + end + + def print_buffer() + win_border() + j = 1 + @buffer.yield(@win.getmaxy-2,@curr_offset) { |l,type| + @win.move(j,1) + if(type == 1) then @win.attron(Ncurses.COLOR_PAIR(1)) end + print_line(@win,l,hscroll=@hscroll) + if(type == 1) then @win.attroff(Ncurses.COLOR_PAIR(1)) end + j = j+1 + } + if(@buffer.has_before?) + @win.move(2,@win.getmaxx-1) + @win.attron(Ncurses::A_REVERSE) + @win.addstr("↑") + @win.attroff(Ncurses::A_REVERSE) + end + if(@buffer.has_after?) + @win.move(@win.getmaxy-2,@win.getmaxx-1) + @win.attron(Ncurses::A_REVERSE) + @win.addstr("↓") + @win.attroff(Ncurses::A_REVERSE) + end + end + + def proc_readlines() + begin + while true + @buffer.push(@proc.readline_nonblock) + update_date() + end + rescue IO::WaitReadable + end + end + + def update() + if(@params['Type'] == 'continuous') + proc_readlines() + end + if(@params['Type'] == 'oneshot') + if(Time.now - @last_update > @params['Periodic'].to_i) + @buffer.clear() + spawn_proc() + end + end + print_buffer() + end + + def spawn_proc() + if(@params['Type'] == 'oneshot') + update_date() + Open3.popen3(@params["Command"]) { |i,o,e,t| + while ((not o.eof?) or (not e.eof?)) + rs = IO.select([o,e],nil)[0] + r = (rs[0].eof?)? rs[1] : rs[0] + + if r.fileno == o.fileno + @buffer.push(r.readline) + elsif r.fileno == e.fileno + @buffer.push(r.readline,type=1) + end + end + } + elsif(@params['Type'] == 'continuous') + @proc = IO.popen(@params["Command"]) + proc_readlines() + end + end +end + +class Buffer + def initialize(size) + @size = size + @buff = [] + @buff_type = [] + @current = 0 + @wrap = false + @before = false + @after = false + end + def size() + return @buff.length + end + def maxlen() + maxlen = 0 + @buff.each do |string| + if string.length > maxlen + maxlen = string.length + end + end + return maxlen + end + + def push(string,type=0) + if(string.chomp.empty?) then string = " " end + string.split( /\r?\n/ ).each do |line| + @buff[@current] = line + @buff_type[@current] = type + if(@size > 0) + @current = (1+@current) % @size + else + @current = 1+@current + end + if(@current == 0) then @wrap = true end + end + end + def yield(size,offset=0,&block) + range = Range.new(0,@current-1).to_a + if(@wrap) + range = Range.new(@current,@size-1).to_a + range + end + range = range.last(size+offset)[0,size] + @before = (size+offset < @buff.length) + @after = (offset != 0 and size < @buff.length) + if(block) + range.each do |i| + yield [@buff[i],@buff_type[i]] + end + else + return range.collect{|r| [@buff[r],@buff_type[r]]} + end + end + def has_after?() + return @after + end + def has_before?() + return @before + end + def clear() + @current = 0 + @buff = [] + @buff_type = [] + end +end + +def read_ini() + inifile = IniFile.load('monitorrc') + return inifile +end + +def print_line(win, str, hscroll=0) + if(hscroll > 0) + strcut = str[hscroll,str.length] + if(strcut.nil? or strcut.empty?) + str = "" + else + str = "…"+strcut + end + end + strlen = str.length + winlen = win.getmaxx-win.getcurx-1 + if(strlen <= winlen) + win.addstr(str + " "*(winlen-strlen)) + else + win.addstr(str[0,winlen-1]+"…") + end +end + +def make_bufwins(inifile) + bufwins = [] + inifile.each_section do |section| + bufwin = Buff_Win.new(Ncurses.COLS()-Ncurses.COLS()/4, + Ncurses.COLS()/4, + inifile[section]) + bufwins.push(bufwin) + end + return bufwins +end + +def update_buffers(bufwins) + bufwins.each do |bufwin| + bufwin.update() + end +end + +def redraw_all(list,bufwins,curr_bufwin) + bufwins.each do |bufwin| + bufwin.move_resize(Ncurses.COLS()-Ncurses.COLS()/4,Ncurses.COLS()/4) + end + list.resize(Ncurses.LINES(), Ncurses.COLS()/4) + list.clear() + list.print_list() + list.refresh() + curr_bufwin.refresh() +end +begin + # initialize ncurses + Ncurses.initscr + Ncurses.start_color + Ncurses.cbreak # provide unbuffered input + Ncurses.noecho # turn off input echoing + #Ncurses.nonl # turn off newline translation + #Ncurses.stdscr.intrflush(false) # turn off flush-on-interrupt + Ncurses.stdscr.keypad(true) # turn on keypad mode + Ncurses.init_pair(1, Ncurses::COLOR_RED, Ncurses::COLOR_BLACK) + + + inifile = read_ini() + + list = List_Win.new(inifile) + bufwins = make_bufwins(inifile) + entry = 0 + cur_bufwin = bufwins[entry] + cur_bufwin.show_win() + list.print_list() + while(ch = list.getch()) do + case(ch) + when "n".ord + entry = (entry +1) % bufwins.length + cur_bufwin = bufwins[entry] + cur_bufwin.show_win() + list.print_list(entry=entry) + when "p".ord + entry = (entry -1) % bufwins.length + cur_bufwin = bufwins[entry] + cur_bufwin.show_win() + list.print_list(entry=entry) + when 12 #ctrl+L + redraw_all(list,bufwins,cur_bufwin) + when Ncurses::KEY_RESIZE + redraw_all(list,bufwins,cur_bufwin) + when Ncurses::KEY_LEFT + cur_bufwin.hscroll(scroll=-1) + when Ncurses::KEY_RIGHT + cur_bufwin.hscroll(scroll=1) + when Ncurses::KEY_DOWN + cur_bufwin.scroll(scroll=-1) + when Ncurses::KEY_UP + cur_bufwin.scroll(scroll=1) + when Ncurses::KEY_NPAGE + cur_bufwin.scroll(scroll=0,goto=nil,fact=-0.75) + when Ncurses::KEY_PPAGE + cur_bufwin.scroll(scroll=0,goto=nil,fact=0.75) + when Ncurses::KEY_HOME + cur_bufwin.scroll(scroll=0,goto=1.0) + when Ncurses::KEY_END + cur_bufwin.scroll(scroll=0,goto=0.0) + when Ncurses::ERR + update_buffers(bufwins) + cur_bufwin.show_win() + when "q".ord + break + else + next + end + end + +ensure + Ncurses.echo + Ncurses.nocbreak + Ncurses.nl + Ncurses.endwin +end diff --git a/monitorrc b/monitorrc new file mode 100644 index 0000000..f2f6ca9 --- /dev/null +++ b/monitorrc @@ -0,0 +1,35 @@ +[journalctl] +Name = Journalctl bla bla bla bla bla bla bla +Command = "journalctl --full -f" +Buffer = 100 +Type = continuous + +[tinc_check] +Name = Tinc +Command = "tinc_check_connect" +Type = oneshot +Periodic = 10 + +[test] +Name = Test +Command = "cat monitorrc" +Type = oneshot +Periodic = 10 + +[lsR] +Name = lsR +Command = "ls -1 /var/named /etc/zsh" +Type = oneshot +Periodic = 10 + +[test2] +Name = Test +Command = "cat monitorrc" +Type = oneshot +Periodic = 10 + +[lsR2] +Name = Test bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla +Command = "ls -1 /var/named /etc/zsh" +Type = oneshot +Periodic = 10 -- 2.41.0