gltail 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ class BlobStore
2
+ @store = { }
3
+ @used_keys = { }
4
+ def self.get(key)
5
+ @used_keys[key] = true
6
+ return @store[key]
7
+ end
8
+
9
+ def self.put(key, ob)
10
+ @store[key] = ob
11
+ @used_keys[key] = true
12
+ end
13
+
14
+ def self.has(key)
15
+ @store.include? key
16
+ end
17
+
18
+ def self.size
19
+ @store.size
20
+ end
21
+
22
+ def self.used
23
+ @used_keys.size
24
+ end
25
+
26
+ def self.prune
27
+ @store.keys.each do |k|
28
+ unless @used_keys.include? k
29
+ glDeleteLists(@store[k], 1)
30
+ @store.delete k
31
+ end
32
+ end
33
+ @used_keys = { }
34
+ end
35
+
36
+ def self.empty
37
+ @store.keys.each do |k|
38
+ glDeleteLists(@store[k], 1)
39
+ @store.delete k
40
+ end
41
+ @used_keys = { }
42
+ end
43
+ end
@@ -0,0 +1,130 @@
1
+ # gl_tail.rb - OpenGL visualization of your server traffic
2
+ # Copyright 2007 Erlend Simonsen <mr@fudgie.org>
3
+ #
4
+ # Licensed under the GNU General Public License v2 (see LICENSE)
5
+ #
6
+
7
+ class Block
8
+ include GlTail::Configurable
9
+
10
+ attr_reader :name, :bottom_position
11
+
12
+ config_attribute :color, "FIXME: add description", :type => :color
13
+ config_attribute :order, "FIXME"
14
+ config_attribute :size, "FIXME"
15
+ config_attribute :auto_clean
16
+
17
+ attr_accessor :column
18
+ attr_reader :config
19
+
20
+ def initialize(config, name)
21
+ @config = config
22
+ @name = name
23
+
24
+ @size = 10
25
+ @auto_clean = true
26
+ @order = 100
27
+ # @color = [1.0, 1.0, 1.0, 1.0]
28
+
29
+ @show = 0
30
+
31
+ @header = Element.new(self, @name.upcase)
32
+ @header.color = [1.0, 1.0, 1.0, 1.0]
33
+
34
+ @elements = { }
35
+ @bottom_position = -@config.screen.top
36
+ end
37
+
38
+ def show=(value)
39
+ @show = case value
40
+ when 'rate' then 0
41
+ when 'total' then 1
42
+ when 'average' then 2
43
+ else
44
+ 0
45
+ end
46
+ end
47
+
48
+ attr_reader :show
49
+
50
+ def top
51
+ @config.screen.top
52
+ end
53
+
54
+ def line_size
55
+ @config.screen.line_size
56
+ end
57
+
58
+ def is_right
59
+ column.is_right
60
+ end
61
+
62
+ def alignment
63
+ column.alignment
64
+ end
65
+
66
+ def position
67
+ column.position
68
+ end
69
+
70
+ def width
71
+ column.size
72
+ end
73
+
74
+ def render(engine, num)
75
+ return num if @elements.size == 0
76
+
77
+ @header.wy = top - (num * line_size)
78
+ # @header.y = @header.wy if @header.y == -$CONFIG.top
79
+ @header.render(engine)
80
+ num += 1
81
+
82
+ sorted = case @show
83
+ when 0: @elements.values.sort { |k,v| v.rate <=> k.rate}[0..@size-1]
84
+ when 1: @elements.values.sort { |k,v| v.total <=> k.total}[0..@size-1]
85
+ when 2: @elements.values.sort { |k,v| v.average <=> k.average}[0..@size-1]
86
+ end
87
+
88
+ sorted.each do |e|
89
+ e.wy = top - (num * line_size)
90
+ e.render(engine)
91
+ engine.stats[0] += 1
92
+ if e.rate <= 0.0001 && e.active && e.updates > 59 && @auto_clean
93
+ @elements.delete(e.name)
94
+ end
95
+ num += 1
96
+ end
97
+
98
+ (@elements.values - sorted).each do |e|
99
+ engine.stats[0] += 1
100
+ e.activities.each do |a|
101
+ a.render(engine)
102
+ if a.x > 1.0 || a.x < -1.0 || a.y > @config.screen.aspect
103
+ e.activities.delete a
104
+ end
105
+ end
106
+ if e.activities.size == 0 && @auto_clean && e.updates > 59
107
+ @elements.delete(e.name)
108
+ end
109
+ end
110
+ @elements.delete_if { |k,v| (!sorted.include? v) && v.active && v.activities.size == 0 && v.updates > 29} if @auto_clean
111
+ @bottom_position = top - ((sorted.size > 0 ? (num-1) : num) * line_size)
112
+ num + 1
113
+ end
114
+
115
+ def add_activity(options = { })
116
+ x = @elements[options[:name]] ||= Element.new(self, options[:name])
117
+ x.add_activity(options[:message], @color || options[:color] , options[:size] || 0.01, options[:type] || 0 )
118
+ end
119
+
120
+ def add_event(options = { })
121
+ x = @elements[options[:name]] ||= Element.new(self, options[:name])
122
+ x.add_event(options[:message], options[:color] || @color, options[:update_stats] || false)
123
+ end
124
+
125
+ def update
126
+ @elements.each_value do |e|
127
+ e.update
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,187 @@
1
+
2
+ module GlTail
3
+ CONFIG_OPTIONS = { }
4
+
5
+ COLORS = {
6
+ 'white' => %w{ 255 255 255 255 },
7
+ 'red' => %w{ 255 0 0 255 },
8
+ 'green' => %w{ 0 255 0 255 },
9
+ 'blue' => %w{ 0 0 255 255 },
10
+ 'yellow' => %w{ 255 255 0 255 },
11
+ 'cyan' => %w{ 0 255 255 255 },
12
+ 'magenta' => %w{ 255 0 255 255 },
13
+
14
+ 'purple' => %w{ 128 0 255 255 },
15
+ 'orange' => %w{ 255 128 0 255 },
16
+ 'pink' => %w{ 255 0 128 255 },
17
+ }
18
+
19
+ class Screen
20
+ include Configurable
21
+
22
+ config_attribute :wanted_fps, "FIXME: add description"
23
+
24
+ config_attribute :min_blob_size, "Minimum size of activity indicators [0.0 - 1.0]"
25
+ config_attribute :max_blob_size, "Maximum size of activity indicators [0.0 - 1.0]"
26
+
27
+ # shortcut to set these via dimensions
28
+ config_attribute :window_width, "Width of GlTail window"
29
+ config_attribute :window_height, "Height of GlTail window"
30
+
31
+ config_attribute :mode, "FIXME"
32
+ config_attribute :bounce, "FIXME"
33
+
34
+ config_attribute :highlight_color, "FIXME: add description", :type => :color
35
+
36
+ attr_accessor :aspect, :line_size, :top, :bitmap_mode
37
+
38
+ def initialize(config)
39
+ @config = config
40
+
41
+ @wanted_fps = 0
42
+ @aspect = 0.6
43
+ @bounce = false
44
+
45
+ @top = 0.9
46
+ @line_size = 0.03
47
+ @bitmap_mode = 0
48
+ @mode = 0
49
+ @highlight_color = [1.0, 0.0, 0.0, 1.0]
50
+ end
51
+
52
+ def set_dim(x, y)
53
+ self.window_width = x.to_i
54
+ self.window_height = y.to_i
55
+ end
56
+
57
+
58
+ def dimensions=(dim)
59
+ if dim.is_a?(String)
60
+ case dim
61
+ when /^(\d+)x(\d+)$/
62
+ set_dim $1, $2
63
+ when /^(\d+), (\d+)$/
64
+ set_dim $1, $2
65
+ else
66
+ raise "dimensions not understood #{dim}, please use <width>x<height> or <width>, <height>"
67
+ end
68
+ else
69
+ raise "what are you #{dim.inspect}"
70
+ end
71
+ end
72
+
73
+ def right
74
+ @right ||= Column.new(@config, :right)
75
+ end
76
+
77
+ def left
78
+ @left ||= Column.new(@config, :left)
79
+ end
80
+
81
+ end
82
+
83
+ class Column
84
+ include Configurable
85
+
86
+ config_attribute :size, "FIXME: add description"
87
+ config_attribute :alignment, "FIXME: add description"
88
+
89
+ def initialize(config, which)
90
+ @config = config
91
+ @which = which
92
+ end
93
+
94
+ def is_right
95
+ @which == :right
96
+ end
97
+ end
98
+
99
+ class Config
100
+ class << self
101
+ def parse_yaml(file)
102
+ require 'yaml'
103
+
104
+ YamlParser.new(file).apply(self.new)
105
+ end
106
+ end
107
+
108
+ attr_reader :sources
109
+
110
+ def initialize
111
+ @sources = []
112
+ @blocks = []
113
+ @max_size = 1.0
114
+ end
115
+
116
+ def screen
117
+ @screen ||= Screen.new(self)
118
+ end
119
+
120
+ def blocks
121
+ @blocks
122
+ end
123
+
124
+ def add_block(name)
125
+ @blocks << b = Block.new(self, name)
126
+ b
127
+ end
128
+
129
+ def reshape(w, h)
130
+ screen.aspect = h.to_f / w.to_f
131
+ screen.window_width, screen.window_height = w, h
132
+ end
133
+
134
+ def do_process
135
+ active = 0
136
+
137
+ sources.each do |it|
138
+ active += 1
139
+ it.process
140
+ end
141
+
142
+ active
143
+ end
144
+
145
+ def update
146
+ sources.each { |it| it.update }
147
+ blocks.each { |it| it.update }
148
+ @max_size = @max_size * 0.99 if(@max_size * 0.99 > 1.0)
149
+ end
150
+
151
+ def init
152
+ sources.each { |it| it.init }
153
+
154
+ @blocks_by_name = {}
155
+
156
+ blocks.each do |it|
157
+ @blocks_by_name[it.name] = it
158
+ end
159
+ end
160
+
161
+ #block, message, size
162
+ def add_activity(source, options = { })
163
+ size = screen.min_blob_size
164
+ if options[:size]
165
+ size = options[:size].to_f
166
+ @max_size = size if size > @max_size
167
+ size = screen.min_blob_size + ((size / @max_size) * (screen.max_blob_size - screen.min_blob_size))
168
+ options[:size] = size
169
+ end
170
+
171
+ if block = @blocks_by_name[options[:block]]
172
+ block.add_activity({
173
+ :name => source.name,
174
+ :color => source.color,
175
+ :size => screen.min_blob_size
176
+ }.update(options) )
177
+ end
178
+ end
179
+
180
+ #block, message
181
+ def add_event(source, options = { })
182
+ if block = @blocks_by_name[options[:block]]
183
+ block.add_event( { :name => source.name, :color => source.color, :size => screen.min_blob_size}.update(options) )
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,51 @@
1
+ module GlTail
2
+
3
+ module Configurable
4
+
5
+ module ClassMethods
6
+ def config_attribute(id, description = "", opts = {})
7
+
8
+ rewrite_method = case opts[:type]
9
+ when :color
10
+ "config_rewrite_color"
11
+ else
12
+ ""
13
+ end
14
+
15
+ self.class_eval %{
16
+ def #{id}=(value)
17
+ @#{id} = #{rewrite_method} value
18
+ end
19
+
20
+ def #{id}
21
+ @#{id}
22
+ end
23
+ }
24
+
25
+ doc = GlTail::CONFIG_OPTIONS[self.to_s] ||= {}
26
+ doc[id] = {
27
+ :description => description,
28
+ }.update(opts)
29
+ end
30
+
31
+ end
32
+
33
+ def config_rewrite_color(v)
34
+ case v
35
+ when /(.+),(.+),(.+),(.+)/
36
+ value = v.split(',')
37
+ else
38
+ value = GlTail::COLORS[v.downcase]
39
+ unless value
40
+ raise SyntaxError, "You must use either [#{GlTail::COLORS.keys.sort.join('|')}] or a color in RGBA format."
41
+ end
42
+ value.map! { |x| x.to_i / 255.0 }
43
+ end
44
+ value.map {|x| x.to_f }
45
+ end
46
+
47
+ def self.included(receiver)
48
+ receiver.extend ClassMethods
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,94 @@
1
+ require 'yaml'
2
+
3
+ module GlTail
4
+ class YamlParser
5
+ attr_reader :yaml
6
+
7
+ def initialize file
8
+ file ||= "config.yaml"
9
+ @yaml = YAML.load_file(file)
10
+ end
11
+
12
+ def apply(config)
13
+ @config = config
14
+
15
+ @left = Hash.new
16
+ @right = Hash.new
17
+ @blocks = Array.new
18
+
19
+ parse_servers
20
+ parse_config
21
+ parse_resolver
22
+
23
+ @config
24
+ end
25
+
26
+ def parse_resolver
27
+ if x = self.yaml['resolver']
28
+ x.each do |k, v|
29
+ apply_value(Resolver.instance, k, v )
30
+ end
31
+ end
32
+ end
33
+
34
+ def parse_servers
35
+
36
+ self.yaml['servers'].each do |server|
37
+
38
+ src = GlTail::Source::SSH.new(@config)
39
+
40
+ src.name = server.shift
41
+
42
+ apply_values(src, server.shift)
43
+
44
+ @config.sources << src
45
+ end
46
+ end
47
+
48
+ def apply_values(target, hash)
49
+ hash.each do |key, value|
50
+ apply_value(target, key, value)
51
+ end
52
+ end
53
+
54
+ def apply_value(target, key, value)
55
+ begin
56
+ target.send("#{key}=", value)
57
+ rescue
58
+ puts "FAILED TO APPLY #{key}=#{value} TO #{target}"
59
+ raise
60
+ end
61
+ end
62
+
63
+ def parse_config
64
+ self.yaml['config'].each do |key, config|
65
+ screen = @config.screen
66
+
67
+ case config
68
+ when Hash
69
+ if key =~ /(left|right)_column/
70
+ column = screen.send($1)
71
+ blocks = config.delete('blocks')
72
+
73
+ apply_values(column, config)
74
+ add_blocks(column, blocks)
75
+ else
76
+ target = screen.send(key)
77
+ apply_values(target, config)
78
+ end
79
+ else
80
+ apply_value(screen, key, config)
81
+ end
82
+ end
83
+ end
84
+
85
+ def add_blocks(column, hash)
86
+ hash.each do |key, config|
87
+ block = @config.add_block(key)
88
+ block.column = column
89
+
90
+ apply_values(block, config)
91
+ end
92
+ end
93
+ end
94
+ end