]> git.immae.eu Git - perso/Immae/Projets/Ruby/Monitor.git/commitdiff
initial
authorImmae <immae@immae.eu>
Sun, 8 Jun 2014 12:59:53 +0000 (14:59 +0200)
committerImmae <immae@immae.eu>
Sun, 8 Jun 2014 12:59:53 +0000 (14:59 +0200)
monitor.rb [new file with mode: 0644]
monitorrc [new file with mode: 0644]

diff --git a/monitor.rb b/monitor.rb
new file mode 100644 (file)
index 0000000..5e32cf2
--- /dev/null
@@ -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 (file)
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