gltail 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +66 -0
- data/Manifest.txt +40 -0
- data/README +51 -0
- data/README.txt +376 -0
- data/Rakefile +19 -0
- data/TODO +9 -0
- data/bin/gl_tail +109 -0
- data/dist/config.yaml +101 -0
- data/lib/gl_tail.rb +68 -0
- data/lib/gl_tail/activity.rb +145 -0
- data/lib/gl_tail/blob_store.rb +43 -0
- data/lib/gl_tail/block.rb +130 -0
- data/lib/gl_tail/config.rb +187 -0
- data/lib/gl_tail/config/configurable.rb +51 -0
- data/lib/gl_tail/config/yaml_parser.rb +94 -0
- data/lib/gl_tail/element.rb +194 -0
- data/lib/gl_tail/engine.rb +266 -0
- data/lib/gl_tail/font.bin +0 -0
- data/lib/gl_tail/font_store.rb +165 -0
- data/lib/gl_tail/http_helper.rb +58 -0
- data/lib/gl_tail/item.rb +17 -0
- data/lib/gl_tail/parser.rb +46 -0
- data/lib/gl_tail/parsers/apache.rb +56 -0
- data/lib/gl_tail/parsers/iis.rb +47 -0
- data/lib/gl_tail/parsers/mysql.rb +29 -0
- data/lib/gl_tail/parsers/nginx.rb +46 -0
- data/lib/gl_tail/parsers/pix-fwsm.rb +50 -0
- data/lib/gl_tail/parsers/postfix.rb +119 -0
- data/lib/gl_tail/parsers/postgresql.rb +42 -0
- data/lib/gl_tail/parsers/pureftpd.rb +30 -0
- data/lib/gl_tail/parsers/qmail.rb +30 -0
- data/lib/gl_tail/parsers/rails.rb +41 -0
- data/lib/gl_tail/parsers/squid.rb +25 -0
- data/lib/gl_tail/parsers/tshark.rb +25 -0
- data/lib/gl_tail/resolver.rb +69 -0
- data/lib/gl_tail/server.rb +46 -0
- data/lib/gl_tail/sources/base.rb +44 -0
- data/lib/gl_tail/sources/local.rb +12 -0
- data/lib/gl_tail/sources/ssh.rb +112 -0
- data/test/test_gl_tail.rb +0 -0
- metadata +114 -0
Binary file
|
@@ -0,0 +1,165 @@
|
|
1
|
+
class FontStore
|
2
|
+
@list_base = 0
|
3
|
+
@font = []
|
4
|
+
@buffers = nil
|
5
|
+
|
6
|
+
@font_texture = nil
|
7
|
+
|
8
|
+
def self.generate_textures
|
9
|
+
if @font_texture.nil?
|
10
|
+
@font_texture = glGenTextures(1)[0]
|
11
|
+
|
12
|
+
File.open("#{File.dirname(__FILE__)}/font.bin") do |f|
|
13
|
+
@font = Marshal.load(f)
|
14
|
+
end
|
15
|
+
|
16
|
+
font_data = []
|
17
|
+
|
18
|
+
# Add missing pixels to increase height by 3
|
19
|
+
32.upto(255) do |c|
|
20
|
+
@font[c] += @font[c] + [0,0,0].pack("C*") * 24
|
21
|
+
end
|
22
|
+
|
23
|
+
0.upto(196607) do |i|
|
24
|
+
font_data[i] = 0
|
25
|
+
end
|
26
|
+
|
27
|
+
# Re-order bitmap data into one 256x256 texture
|
28
|
+
32.upto(255) do |c|
|
29
|
+
row = (c - 32) / 16
|
30
|
+
col = (c - 32) % 16
|
31
|
+
|
32
|
+
offset = row * 256*16*3 + col*8*3
|
33
|
+
0.upto(15) do |y|
|
34
|
+
0.upto(7) do |x|
|
35
|
+
font_data[offset + y*256*3 + x*3 +0] = @font[c][y*8*3 + x*3 + 0]
|
36
|
+
font_data[offset + y*256*3 + x*3 +1] = @font[c][y*8*3 + x*3 + 1]
|
37
|
+
font_data[offset + y*256*3 + x*3 +2] = @font[c][y*8*3 + x*3 + 2]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
# File.open("lib/font_256.bin", "wb") do |f|
|
44
|
+
# Marshal.dump(font_data, f)
|
45
|
+
# end
|
46
|
+
|
47
|
+
font_data = font_data.pack("C*")
|
48
|
+
|
49
|
+
glBindTexture(GL_TEXTURE_2D, @font_texture)
|
50
|
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
51
|
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
52
|
+
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
53
|
+
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
54
|
+
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
55
|
+
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
56
|
+
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
|
57
|
+
# glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
|
58
|
+
# glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)
|
59
|
+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, font_data)
|
60
|
+
|
61
|
+
glBindTexture(GL_TEXTURE_2D, 0)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.generate_font
|
66
|
+
self.generate_textures
|
67
|
+
return
|
68
|
+
|
69
|
+
# Ignore the rest for now, used only to create font.bin
|
70
|
+
|
71
|
+
# glPushMatrix
|
72
|
+
# glViewport(0, 0, 8, 15)
|
73
|
+
# glMatrixMode(GL_PROJECTION)
|
74
|
+
# glLoadIdentity()
|
75
|
+
|
76
|
+
# glOrtho(0, 8, 13, 0, -1.0, 1.0)
|
77
|
+
|
78
|
+
# glMatrixMode(GL_MODELVIEW)
|
79
|
+
# glLoadIdentity()
|
80
|
+
# glTranslate(0, 0, 0)
|
81
|
+
|
82
|
+
# glMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ( [1.0, 1.0, 1.0, 1.0] ) )
|
83
|
+
# 32.upto(255) do |c|
|
84
|
+
# glClearColor(0.0, 0.0, 0.0, 1.0)
|
85
|
+
# glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
86
|
+
|
87
|
+
# glRasterPos(0,0)
|
88
|
+
# begin
|
89
|
+
# glutBitmapCharacter(GLUT_BITMAP_8_BY_13, c)
|
90
|
+
# rescue RangeError
|
91
|
+
# glutBitmapCharacterX(c)
|
92
|
+
# end
|
93
|
+
|
94
|
+
# glBindTexture(GL_TEXTURE_2D, @textures[c])
|
95
|
+
# glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 13, 8, 13, 0)
|
96
|
+
|
97
|
+
|
98
|
+
# glBindTexture(GL_TEXTURE_2D, 0)
|
99
|
+
# end
|
100
|
+
# glClearColor(0.0, 0.0, 0.0, 1.0)
|
101
|
+
# glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
102
|
+
|
103
|
+
# glPopMatrix
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.render_char(engine, c, pos)
|
108
|
+
char_size = engine.char_size
|
109
|
+
|
110
|
+
base = c-32
|
111
|
+
|
112
|
+
offsetx = ((base%16) ) / (32.0)
|
113
|
+
offsety = ((base/16) * 16) / (256.0)
|
114
|
+
|
115
|
+
width = 8 / 256.0
|
116
|
+
height = 13 / 256.0
|
117
|
+
|
118
|
+
pos_offset = char_size * pos
|
119
|
+
|
120
|
+
glTexCoord2f(offsetx,offsety)
|
121
|
+
glNormal3f(1.0, 1.0, 0.0)
|
122
|
+
glVertex3f(pos_offset, 0, 0.0)
|
123
|
+
|
124
|
+
glTexCoord2f(offsetx+width,offsety)
|
125
|
+
glNormal3f(1.0, 1.0, 0.0)
|
126
|
+
glVertex3f(pos_offset + char_size, 0.0, 0.0)
|
127
|
+
|
128
|
+
glTexCoord2f(offsetx+width,offsety + height)
|
129
|
+
glNormal3f(1.0, 1.0, 0.0)
|
130
|
+
glVertex3f(pos_offset + char_size, engine.line_size, 0.0)
|
131
|
+
|
132
|
+
glTexCoord2f(offsetx,offsety + height)
|
133
|
+
glNormal3f(1.0, 1.0, 0.0)
|
134
|
+
glVertex3f(pos_offset, engine.line_size, 0.0)
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def self.render_string(engine, txt)
|
139
|
+
glPushMatrix
|
140
|
+
glEnable(GL_BLEND)
|
141
|
+
glBlendFunc(GL_ONE, GL_ONE)
|
142
|
+
glBindTexture(GL_TEXTURE_2D, @font_texture)
|
143
|
+
|
144
|
+
unless BlobStore.has(txt)
|
145
|
+
list = glGenLists(1)
|
146
|
+
glNewList(list, GL_COMPILE)
|
147
|
+
glBegin(GL_QUADS)
|
148
|
+
pos = 0
|
149
|
+
txt.each_byte do |c|
|
150
|
+
self.render_char(engine, c, pos)
|
151
|
+
pos += 1
|
152
|
+
end
|
153
|
+
glEnd
|
154
|
+
glEndList
|
155
|
+
BlobStore.put(txt,list)
|
156
|
+
end
|
157
|
+
glCallList(BlobStore.get(txt))
|
158
|
+
|
159
|
+
glBindTexture(GL_TEXTURE_2D, 0)
|
160
|
+
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
161
|
+
glDisable(GL_BLEND)
|
162
|
+
glPopMatrix
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
@@ -0,0 +1,58 @@
|
|
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 HttpHelper
|
8
|
+
|
9
|
+
def self.parse_useragent(ua)
|
10
|
+
case ua
|
11
|
+
when /MSIE ([^;]+);/
|
12
|
+
"Internet Explorer #{$1}"
|
13
|
+
when /Firefox\/(\S+)/
|
14
|
+
"Firefox #{$1}"
|
15
|
+
when /Iceweasel\/(\S+)/
|
16
|
+
"Firefox #{$1}"
|
17
|
+
when /Camino\/(\S+)/
|
18
|
+
"Camino #{$1}"
|
19
|
+
when /Opera\/(\S+)/
|
20
|
+
"Opera #{$1}"
|
21
|
+
when /Safari\/([\d.]+)/
|
22
|
+
"Safari #{$1}"
|
23
|
+
when /Konqueror\/(\S+);/
|
24
|
+
"Konqueror #{$1}"
|
25
|
+
when /Wget/
|
26
|
+
'Wget'
|
27
|
+
|
28
|
+
when /ia_archiver/
|
29
|
+
"Internet Archive Bot"
|
30
|
+
when /Googlebot/
|
31
|
+
"Google Bot"
|
32
|
+
when /msnbot-media/
|
33
|
+
"Microsoft Media Bot"
|
34
|
+
when /msnbot/
|
35
|
+
"Microsoft Bot"
|
36
|
+
when /Gigabot/
|
37
|
+
'Gigabot'
|
38
|
+
when /Yahoo!/
|
39
|
+
'Yahoo Bot'
|
40
|
+
when "-"
|
41
|
+
"-"
|
42
|
+
else
|
43
|
+
ua
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.generalize_url(url)
|
48
|
+
case url
|
49
|
+
when /^(.*?)\/(\d+)$/
|
50
|
+
"#{$1}/:id"
|
51
|
+
when /^(.*?)\/[a-zA-Z0-9]{32}(.*?)$/
|
52
|
+
"#{$1}/:md5#{$2 if $2}"
|
53
|
+
else
|
54
|
+
url
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/lib/gl_tail/item.rb
ADDED
@@ -0,0 +1,17 @@
|
|
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 Item
|
8
|
+
attr_accessor :message, :size, :color, :type
|
9
|
+
|
10
|
+
def initialize(message, size, color, type)
|
11
|
+
@message = message
|
12
|
+
@size = size
|
13
|
+
@color = color
|
14
|
+
@type = type
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,46 @@
|
|
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
|
+
require 'gl_tail/http_helper'
|
8
|
+
|
9
|
+
class Parser
|
10
|
+
attr_reader :source
|
11
|
+
|
12
|
+
def initialize( source )
|
13
|
+
@source = source
|
14
|
+
end
|
15
|
+
|
16
|
+
# DEPRECATED?
|
17
|
+
def server
|
18
|
+
@source
|
19
|
+
end
|
20
|
+
|
21
|
+
def self::inherited( klass )
|
22
|
+
parser_name = klass.to_s.sub( /Parser$/, '' ).downcase.intern
|
23
|
+
|
24
|
+
@registry ||= {}
|
25
|
+
@registry[ parser_name ] = klass
|
26
|
+
end
|
27
|
+
|
28
|
+
def self::registry
|
29
|
+
return @registry
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse( line )
|
33
|
+
raise NotImplementedError,
|
34
|
+
"Concrete parsers must implement parse()"
|
35
|
+
end
|
36
|
+
|
37
|
+
# dsl-ish helper methods so the parsers don't call server.add_* anymore. That
|
38
|
+
# seems magical now that server isn't be explicitly passed anymore.
|
39
|
+
def add_activity( opts = {} )
|
40
|
+
@source.add_activity( opts )
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_event( opts = {} )
|
44
|
+
@source.add_event( opts )
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,56 @@
|
|
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
|
+
# Parser which handles access_logs in combined format from Apache
|
8
|
+
class ApacheParser < Parser
|
9
|
+
def parse( line )
|
10
|
+
_, host, user, domain, date, url, status, size, referrer, useragent = /([\d\S.]+) (\S+) (\S+) \[([^\]]+)\] \"(.+?)\" (\d+) ([\S]+) \"([^\"]+)\" \"([^\"]+)\"/.match(line).to_a
|
11
|
+
|
12
|
+
unless host
|
13
|
+
_, host, user, domain, date, url, status, size = /([\d\S.]+) (\S+) (\S+) \[([^\]]+)\] \"(.+?)\" (\d+) ([\S]+)/.match(line).to_a
|
14
|
+
end
|
15
|
+
|
16
|
+
if host
|
17
|
+
_, referrer_host, referrer_url = /^http[s]?:\/\/([^\/]+)(\/.*)/.match(referrer).to_a if referrer
|
18
|
+
method, url, http_version = url.split(" ")
|
19
|
+
url = method if url.nil?
|
20
|
+
url, parameters = url.split('?')
|
21
|
+
|
22
|
+
referrer.gsub!(/http:\/\//,'') if referrer
|
23
|
+
|
24
|
+
add_activity(:block => 'sites', :name => server.name, :size => size.to_i) # Size of activity based on size of request
|
25
|
+
add_activity(:block => 'urls', :name => url)
|
26
|
+
add_activity(:block => 'users', :name => host, :size => size.to_i)
|
27
|
+
add_activity(:block => 'referrers', :name => referrer) unless (referrer.nil? || referrer_host.nil? || referrer_host.include?(server.name) || referrer_host.include?(server.host))
|
28
|
+
add_activity(:block => 'user agents', :name => HttpHelper.parse_useragent(useragent), :type => 3) unless useragent.nil?
|
29
|
+
|
30
|
+
if( url.include?('.gif') || url.include?('.jpg') || url.include?('.png') || url.include?('.ico'))
|
31
|
+
type = 'image'
|
32
|
+
elsif url.include?('.css')
|
33
|
+
type = 'css'
|
34
|
+
elsif url.include?('.js')
|
35
|
+
type = 'javascript'
|
36
|
+
elsif url.include?('.swf')
|
37
|
+
type = 'flash'
|
38
|
+
elsif( url.include?('.avi') || url.include?('.ogm') || url.include?('.flv') || url.include?('.mpg') )
|
39
|
+
type = 'movie'
|
40
|
+
elsif( url.include?('.mp3') || url.include?('.wav') || url.include?('.fla') || url.include?('.aac') || url.include?('.ogg'))
|
41
|
+
type = 'music'
|
42
|
+
else
|
43
|
+
type = 'page'
|
44
|
+
end
|
45
|
+
add_activity(:block => 'content', :name => type)
|
46
|
+
add_activity(:block => 'status', :name => status, :type => 3) # don't show a blob
|
47
|
+
|
48
|
+
add_activity(:block => 'warnings', :name => "#{status}: #{url}") if status.to_i > 400
|
49
|
+
|
50
|
+
# Events to pop up
|
51
|
+
add_event(:block => 'info', :name => "Logins", :message => "Login...", :update_stats => true, :color => [1.5, 1.0, 0.5, 1.0]) if method == "POST" && url.include?('login')
|
52
|
+
add_event(:block => 'info', :name => "Sales", :message => "$", :update_stats => true, :color => [1.5, 0.0, 0.0, 1.0]) if method == "POST" && url.include?('/checkout')
|
53
|
+
add_event(:block => 'info', :name => "Signups", :message => "New User...", :update_stats => true, :color => [1.0, 1.0, 1.0, 1.0]) if( method == "POST" && (url.include?('/signup') || url.include?('/users/create')))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,47 @@
|
|
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
|
+
# Parser which handles Internet Information Server (IIS) logs
|
8
|
+
class IISParser < Parser
|
9
|
+
def parse( line )
|
10
|
+
_, date, time,serverip, url, referrer, port, size, host, useragent, status = /^([\d-]+) ([\d:]+) ([\d.]+) (.+? .+?) (\S+) (.+?) (\S+) ([\d.]+) (.+?) (\d+) (.*)$/.match(line).to_a
|
11
|
+
|
12
|
+
if host
|
13
|
+
_, referrer_host, referrer_url = /^http[s]?:\/\/([^\/]+)(\/.*)/.match(referrer).to_a if referrer
|
14
|
+
method, url, http_version = url.split(" ")
|
15
|
+
url, parameters = url.split('?')
|
16
|
+
|
17
|
+
add_activity(:block => 'sites', :name => server.name, :size => size.to_i) # Size of activity based on size of request
|
18
|
+
add_activity(:block => 'urls', :name => url)
|
19
|
+
add_activity(:block => 'users', :name => host, :size => size.to_i)
|
20
|
+
add_activity(:block => 'referrers', :name => referrer) unless (referrer_host.nil? || referrer_host.include?(server.name) || referrer_host.include?(server.host) || referrer == '-')
|
21
|
+
add_activity(:block => 'user agents', :name => useragent, :type => 3)
|
22
|
+
|
23
|
+
if( url.include?('.gif') || url.include?('.jpg') || url.include?('.png') || url.include?('.ico'))
|
24
|
+
type = 'image'
|
25
|
+
elsif url.include?('.css')
|
26
|
+
type = 'css'
|
27
|
+
elsif url.include?('.js')
|
28
|
+
type = 'javascript'
|
29
|
+
elsif url.include?('.swf')
|
30
|
+
type = 'flash'
|
31
|
+
elsif( url.include?('.avi') || url.include?('.ogm') || url.include?('.flv') || url.include?('.mpg') )
|
32
|
+
type = 'movie'
|
33
|
+
elsif( url.include?('.mp3') || url.include?('.wav') || url.include?('.fla') || url.include?('.aac') || url.include?('.ogg'))
|
34
|
+
type = 'music'
|
35
|
+
else
|
36
|
+
type = 'page'
|
37
|
+
end
|
38
|
+
add_activity(:block => 'content', :name => type)
|
39
|
+
add_activity(:block => 'status', :name => status, :type => 3) # don't show a blob
|
40
|
+
|
41
|
+
# Events to pop up
|
42
|
+
add_event(:block => 'info', :name => "Logins", :message => "Login...", :update_stats => true, :color => [1.5, 1.0, 0.5, 1.0]) if method == "POST" && url.include?('login')
|
43
|
+
add_event(:block => 'info', :name => "Sales", :message => "$", :update_stats => true, :color => [1.5, 0.0, 0.0, 1.0]) if method == "POST" && url.include?('/checkout')
|
44
|
+
add_event(:block => 'info', :name => "Signups", :message => "New User...", :update_stats => true, :color => [1.0, 1.0, 1.0, 1.0]) if( method == "POST" && (url.include?('/signup') || url.include?('/users/create')))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,29 @@
|
|
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
|
+
# Parser which handles logs from MySQL
|
8
|
+
class MysqlParser < Parser
|
9
|
+
def parse( line )
|
10
|
+
# 071013 9:43:17 7 Query select * from users where username='test' limit 10
|
11
|
+
|
12
|
+
if line.include? " Query "
|
13
|
+
_, query = /^.* Query\s+(.+)$/.match(line).to_a
|
14
|
+
|
15
|
+
if query
|
16
|
+
add_activity(:block => 'sites', :name => server.name)
|
17
|
+
add_activity(:block => 'database', :name => query)
|
18
|
+
end
|
19
|
+
|
20
|
+
elsif line.include? " Connect "
|
21
|
+
# 8 Connect debian-sys-maint@localhost on
|
22
|
+
_, user = /^.* Connect\s+(.+) on\s+/.match(line).to_a
|
23
|
+
if user
|
24
|
+
add_activity(:block => 'logins', :name => "#{user}/mysql" )
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
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
|
+
# Parser which handles nginx logs
|
8
|
+
class NginxParser < Parser
|
9
|
+
def parse( line )
|
10
|
+
_, remote_addr, remote_user, status, request, size, referrer, http_user_agent, http_x_forwarded_for = /^([^\s]+) - ([^\s]+) \[.*\] (\d+) \"(.+)\" (\d+) \"(.*)\" \"([^\"]*)\" \"(.*)\"/.match(line).to_a
|
11
|
+
|
12
|
+
if request
|
13
|
+
_, referrer_host, referrer_url = /^http[s]?:\/\/([^\/]+)(\/.*)/.match(referrer).to_a if referrer
|
14
|
+
method, full_url, _ = request.split(' ')
|
15
|
+
url, parameters = full_url.split('?')
|
16
|
+
|
17
|
+
add_activity(:block => 'sites', :name => server.name, :size => size.to_i)
|
18
|
+
add_activity(:block => 'urls', :name => url)
|
19
|
+
add_activity(:block => 'users', :name => remote_addr, :size => size.to_i)
|
20
|
+
add_activity(:block => 'referrers', :name => referrer) unless (referrer_host.nil? || referrer_host.include?(server.name) || referrer_host.include?(server.host) || referrer == '-')
|
21
|
+
add_activity(:block => 'user agents', :name => http_user_agent, :type => 3) unless http_user_agent.nil?
|
22
|
+
|
23
|
+
if( url.include?('.gif') || url.include?('.jpg') || url.include?('.png') || url.include?('.ico'))
|
24
|
+
type = 'image'
|
25
|
+
elsif url.include?('.css')
|
26
|
+
type = 'css'
|
27
|
+
elsif url.include?('.js')
|
28
|
+
type = 'javascript'
|
29
|
+
elsif url.include?('.swf')
|
30
|
+
type = 'flash'
|
31
|
+
elsif( url.include?('.avi') || url.include?('.ogm') || url.include?('.flv') || url.include?('.mpg') )
|
32
|
+
type = 'movie'
|
33
|
+
elsif( url.include?('.mp3') || url.include?('.wav') || url.include?('.fla') || url.include?('.aac') || url.include?('.ogg'))
|
34
|
+
type = 'music'
|
35
|
+
else
|
36
|
+
type = 'page'
|
37
|
+
end
|
38
|
+
|
39
|
+
add_activity(:block => 'content', :name => type)
|
40
|
+
add_activity(:block => 'status', :name => status, :type => 3)
|
41
|
+
|
42
|
+
add_event(:block => 'info', :name => "Logins", :message => "Login...", :update_stats => true, :color => [1.5, 1.0, 0.5, 1.0]) if method == "POST" && url.include?('/login')
|
43
|
+
add_event(:block => 'info', :name => "Registration", :message => "Register", :update_stats => true, :color => [1.5, 0.0, 0.0, 1.0]) if method == "POST" && url.include?('/register')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|