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
@@ -0,0 +1,50 @@
|
|
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 Cisco PIX or FWSM firewalls
|
8
|
+
# should also handle ASA logs, with minimal change...
|
9
|
+
# Leif Sawyer (leif@denali.net)
|
10
|
+
#
|
11
|
+
|
12
|
+
class PixParser < Parser
|
13
|
+
def parse( line )
|
14
|
+
if line.include?(': Built')
|
15
|
+
_, firewall, type, direction, srcif, src, srcport, dstif, dst, dstport =
|
16
|
+
/^.* \d+ \d+:\d+:\d+ \[?([a-zA-Z0-9\-]+)\/?\]?.* %(FWSM|PIX)-\d+-\d+: Built (\w+)bound \w+ connection \d+ for (\w+):([a-zA-Z0-9.]+)\/([a-zA-Z0-9.]+) \(.*\) to (\w+):([a-zA-Z0-9.]+)\/([a-zA-Z0-9.]+)/.match(line).to_a
|
17
|
+
|
18
|
+
if firewall
|
19
|
+
add_activity(:block => 'firewall', :name => firewall)
|
20
|
+
if direction == 'out'
|
21
|
+
add_activity(:block => 'hosts', :name => src)
|
22
|
+
add_activity(:block => 'sites', :name => dst)
|
23
|
+
else
|
24
|
+
add_activity(:block => 'hosts', :name => dst)
|
25
|
+
add_activity(:block => 'sites', :name => src)
|
26
|
+
end
|
27
|
+
printf("%sbound from %s firewall '%s', srcif=%s, src=%s, srcport=%s, dstif=%s, dst=%s, dstport=%s...\n", direction, type, firewall, srcif, src, srcport, dstif, dst, dstport ) if $VRB > 0
|
28
|
+
end
|
29
|
+
|
30
|
+
elsif line.include?('Accessed URL')
|
31
|
+
_, firewall, type, client, server, url = /^.* \d+ \d+:\d+:\d+ \[?([a-zA-Z0-9\-]+)\/?\]?.* %(FWSM|PIX)-\d+-\d+: ([a-zA-Z0-9.]+) Accessed URL ([a-zA-Z0-9.]+):(.*)[\?]?/.match(line).to_a
|
32
|
+
if firewall
|
33
|
+
add_activity(:block => 'firewall', :name => firewall)
|
34
|
+
add_activity(:block => 'hosts', :name => client)
|
35
|
+
add_activity(:block => 'sites', :name => server)
|
36
|
+
add_activity(:block => 'urls', :name => url)
|
37
|
+
printf("%s firewall '%s': client %s accessed url %s on host %s\n", type, firewall, client, url, server) if $VRB > 0
|
38
|
+
end
|
39
|
+
|
40
|
+
# elsif line.include?(': Deny')
|
41
|
+
# Deny udp src outside:_SRC_IP_/_SRC_PORT_ dst inside:_DST_IP_/_DST_PORT_ by access-group "_ACL_NAME"
|
42
|
+
# printf("ACL denied access ...\n") if $VRB > 0
|
43
|
+
|
44
|
+
# elsif line.include?('static translation')
|
45
|
+
# Teardown static translation from inside:_SRC_IP_ to dmz-anc-csa:_DST_IP_ duration 0:01:00
|
46
|
+
# printf("static translation ...\n") if $VRB > 0
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,119 @@
|
|
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
|
+
# Parser which handles Postfix logs
|
7
|
+
class PostfixParser < Parser
|
8
|
+
def parse( line )
|
9
|
+
if line.include?(': connect from')
|
10
|
+
_, host, ip = /: connect from ([^\[]+)\[(\d+.\d+.\d+.\d+)\]/.match(line).to_a
|
11
|
+
if host
|
12
|
+
host = ip if host == 'unknown'
|
13
|
+
add_activity(:block => 'smtp', :name => host, :size => 0.03)
|
14
|
+
end
|
15
|
+
elsif line.include?(' sasl_username=')
|
16
|
+
_, username = /, sasl_username=(.*)/.match(line).to_a
|
17
|
+
add_activity(:block => 'logins', :name => "#{username}/sasl", :size => 0.1)
|
18
|
+
elsif line.include?('NOQUEUE: reject:')
|
19
|
+
#
|
20
|
+
# Parse rejection messages, including RBL rejections.
|
21
|
+
# The rejection status could be displayed with the actual error codes if desired.
|
22
|
+
# Change :name => 'rejected'
|
23
|
+
# To :name => status
|
24
|
+
# Or :name => extstatus
|
25
|
+
#
|
26
|
+
_, host, ip, status, extstatus, rejectreason, from, to, proto, helo = /: reject: RCPT from ([^\[]+)\[(\d+.\d+.\d+.\d+)\]: (\d+) (\d.\d.\d) (.*) from=<([^>]+)> to=<([^>]+)> proto=(.*) helo=<([^>]+)>/.match(line).to_a
|
27
|
+
add_activity(:block => 'status', :name => 'rejected', :size => 0.03)
|
28
|
+
host = ip if host == 'unknown'
|
29
|
+
if not rejectreason.nil?
|
30
|
+
if rejectreason.include?(' blocked using ')
|
31
|
+
rbltype = 'rbl'
|
32
|
+
if rejectreason.include?('Sender address')
|
33
|
+
# RHSBL-stle rejection message
|
34
|
+
_, ip, rbl, rbltext = /Sender address \[([^>]+)\] blocked using (.*)\; (.*)\;/.match(rejectreason).to_a
|
35
|
+
rbltype = 'rhsbl'
|
36
|
+
else
|
37
|
+
# Plain RBL rejection message
|
38
|
+
_, ip, rbl, rbltext = /Client host \[(\d+.\d+.\d+.\d+)\] blocked using (.*)\; (.*)\;/.match(rejectreason).to_a
|
39
|
+
end
|
40
|
+
if not rbl.nil?
|
41
|
+
# add_activity(:block => 'rejections', :name => host, :size => 0.03)
|
42
|
+
add_activity(:block => 'rejections', :name => rbltype + ' ' + rbl, :size => 0.03)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
# Generic rejection message, print the whole thing.
|
46
|
+
_, address, reason = /<([^>]+)>\: (.*);/.match(rejectreason).to_a
|
47
|
+
# add_activity(:block => 'rejections', :name => host, :size => 0.03)
|
48
|
+
add_activity(:block => 'rejections', :name => reason, :size => 0.03)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
elsif line.include?(' from=<')
|
52
|
+
_, from, size = /: from=<([^>]+)>, size=(\d+)/.match(line).to_a
|
53
|
+
if from
|
54
|
+
add_activity(:block => 'mail from', :name => from, :size => size.to_f/100000.0)
|
55
|
+
end
|
56
|
+
elsif line.include?(' to=<')
|
57
|
+
if line.include?('relay=local')
|
58
|
+
# Incoming
|
59
|
+
_, to, delay, status = /: to=<([^>]+)>, .*delay=([\d.]+).*status=([^ ]+)/.match(line).to_a
|
60
|
+
add_activity(:block => 'mail to', :name => to, :size => delay.to_f/10.0, :type => 5, :color => [1.0, 0.0, 1.0, 1.0])
|
61
|
+
add_activity(:block => 'status', :name => 'received', :size => delay.to_f/10.0, :type => 3)
|
62
|
+
else
|
63
|
+
# Outgoing
|
64
|
+
_, to, relay_host, delay, status = /: to=<([^>]+)>.*relay=([^\[,]+).*delay=([\d.]+).*status=([^ ]+)/.match(line).to_a
|
65
|
+
add_activity(:block => 'mail from', :name => to, :size => delay.to_f/10.0)
|
66
|
+
add_activity(:block => 'smtp', :name => relay_host, :size => delay.to_f/10.0)
|
67
|
+
add_activity(:block => 'status', :name => status, :size => delay.to_f/10.0, :type => 3)
|
68
|
+
end
|
69
|
+
elsif line.include?('spamd:') and (line.include?('clean message') or line.include?('identified spam'))
|
70
|
+
#
|
71
|
+
# Parse spamd log entries for the result summary, and add the clean/spam status to the status block.
|
72
|
+
#
|
73
|
+
# NOTE/TODO: Much more could be done with this block, including averaging scores and processing times
|
74
|
+
#
|
75
|
+
_, status, score, mailaddr, proctime, size = /: spamd: (\w+ \w+) \((\d+\.\d+)\/.*\) for (.*):.* in (\d+\.\d+) seconds, (\d+) bytes/.match(line).to_a
|
76
|
+
if not status.nil?
|
77
|
+
status = status.include?('clean') ? 'clean' : 'spam'
|
78
|
+
add_activity(:block => 'status', :name => status, :size => proctime.to_f/10.0)
|
79
|
+
end
|
80
|
+
elsif line.include?('clamd[')
|
81
|
+
#
|
82
|
+
# Parse clamd log entries. Print the name of the detected virus.
|
83
|
+
#
|
84
|
+
_, virusname = /clamd\[\d+\]: .*: (.*) FOUND/.match(line).to_a
|
85
|
+
add_activity(:block => 'status', :name => 'virus', :size => 0.03)
|
86
|
+
add_activity(:block => 'viruses', :name => virusname, :size => 0.03)
|
87
|
+
elsif line.include?(': warning:')
|
88
|
+
#
|
89
|
+
# Parse warning messages. If it is a known warning, shorten the message, otherwise print the full text
|
90
|
+
#
|
91
|
+
_, warningtext = /: warning: (.*)/.match(line).to_a
|
92
|
+
if warningtext.include?('malformed domain name')
|
93
|
+
warningtext = 'Malformed Domain Name'
|
94
|
+
elsif warningtext.include?('non-SMTP command')
|
95
|
+
warningtext = 'Non-SMTP Command'
|
96
|
+
elsif warningtext.include?('Non-recoverable failure in name resolution')
|
97
|
+
warningtext = 'DNS Failure'
|
98
|
+
elsif warningtext.include?('hostname nor servname provided')
|
99
|
+
warningtext = 'Host Verification Failure'
|
100
|
+
elsif warningtext.include?('address not listed for hostname')
|
101
|
+
warningtext = 'Hostname Without Address'
|
102
|
+
elsif warningtext.include?('Connection rate limit exceeded')
|
103
|
+
warningtext = 'Per-Host Connection Rate Exceeded'
|
104
|
+
elsif warningtext.include?('Connection concurrency limit exceeded')
|
105
|
+
warningtext = 'Per-Host Connection concurrency Exceeded'
|
106
|
+
elsif warningtext.include?('numeric domain name in resource data')
|
107
|
+
warningtext = 'Numeric Domain Name'
|
108
|
+
elsif warningtext.include?('numeric hostname')
|
109
|
+
warningtext = 'Numeric Host Name'
|
110
|
+
elsif warningtext.include?('valid_hostname: empty hostname')
|
111
|
+
warningtext = 'Empty Hostname'
|
112
|
+
elsif warningtext.include?('Illegal address syntax')
|
113
|
+
warningtext = 'Illegal Address Syntax'
|
114
|
+
end
|
115
|
+
add_activity(:block => 'status', :name => 'warning', :size => 0.03)
|
116
|
+
add_activity(:block => 'warnings', :name => warningtext, :size => 0.03)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,42 @@
|
|
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 PostgreSQL logs
|
8
|
+
class PostgreSQLParser < Parser
|
9
|
+
def parse( line )
|
10
|
+
# here's an example parser for postgres log files; adjust accordingly for different logfile setups.
|
11
|
+
#
|
12
|
+
# postgresql.conf:
|
13
|
+
# log_line_prefix = '[%d, %t] '
|
14
|
+
# log_connections = on
|
15
|
+
# log_disconnections = on
|
16
|
+
# log_duration = on
|
17
|
+
# log_statement = 'all'
|
18
|
+
|
19
|
+
_, database, datetime, activity, description = /^\[(.*), (.* .* .*)\] LOG: ([a-zA-Z0-9\s]*): (.*)/.match(line).to_a
|
20
|
+
|
21
|
+
if database
|
22
|
+
add_activity(:block => 'database', :name => database, :size => 0.2)
|
23
|
+
else
|
24
|
+
_, datetime, activity, description = /^(.* .* .*) LOG: ([a-zA-Z0-9\s]*): (.*)/.match(line).to_a
|
25
|
+
end
|
26
|
+
|
27
|
+
if activity
|
28
|
+
activity = 'vacuum' if(description.include?('vacuum') || activity == 'autovacuum')
|
29
|
+
case activity
|
30
|
+
when 'duration'
|
31
|
+
add_activity(:block => 'database', :name => 'duration', :size => description.to_f / 100.0)
|
32
|
+
when 'statement'
|
33
|
+
add_activity(:block => 'database', :name => 'activity', :size => 0.2)
|
34
|
+
when 'connection authorized', 'disconnection'
|
35
|
+
add_activity(:block => 'database', :name => 'login/logout', :size => 0.2)
|
36
|
+
when 'vacuum'
|
37
|
+
add_event(:block => 'database', :name => 'vacuum', :message => description, :update_stats => true, :color => [1.0, 1.0, 0.0, 1.0])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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 PureFTPD
|
8
|
+
class PureftpdParser < Parser
|
9
|
+
def parse( line )
|
10
|
+
_, host, domain, user, date, url, status, size = /^([\d\S.]+) (\S+) (\S+) \[([^\]]+)\] \"(.+?)\" (\d+) ([\S]+)/.match(line).to_a
|
11
|
+
|
12
|
+
if host
|
13
|
+
user = host if user == 'ftp'
|
14
|
+
|
15
|
+
method, url = url.split(" ")
|
16
|
+
url = method if url.nil?
|
17
|
+
|
18
|
+
if method == "PUT"
|
19
|
+
add_activity(:block => 'urls', :name => url, :size => size.to_i, :type => 5)
|
20
|
+
else
|
21
|
+
add_activity(:block => 'urls', :name => url, :size => size.to_i)
|
22
|
+
end
|
23
|
+
add_activity(:block => 'sites', :name => server.name, :size => size.to_i) # Size of activity based on size of request
|
24
|
+
add_activity(:block => 'users', :name => user, :size => size.to_i)
|
25
|
+
|
26
|
+
add_activity(:block => 'content', :name => 'file')
|
27
|
+
add_activity(:block => 'status', :name => status, :type => 3) # don't show a blob
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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 qmail logs
|
8
|
+
class QmailParser < Parser
|
9
|
+
def parse( line )
|
10
|
+
if line.include?(' logged in from ')
|
11
|
+
_, user, host, ip = /: User \'([^']+)\' of \'([^']+)\' logged in from (\d+.\d+.\d+.\d+)/.match(line).to_a
|
12
|
+
if host
|
13
|
+
add_activity(:block => 'logins', :name => user+'@'+host, :size => 0.05)
|
14
|
+
add_activity(:block => 'sites', :name => server.name, :size => 0.05)
|
15
|
+
end
|
16
|
+
elsif line.include?(' to local ')
|
17
|
+
_, prefix, host = / to local ([^@]+)@(.*)/.match(line).to_a
|
18
|
+
if host
|
19
|
+
add_activity(:block => 'mail to', :name => host, :size => 0.05)
|
20
|
+
add_activity(:block => 'sites', :name => server.name, :size => 0.05)
|
21
|
+
end
|
22
|
+
elsif line.include?(' to remote ')
|
23
|
+
_, prefix, host = / to remote ([^@]+)@(.*)/.match(line).to_a
|
24
|
+
if host
|
25
|
+
add_activity(:block => 'mail from', :name => host, :size => 0.05)
|
26
|
+
add_activity(:block => 'sites', :name => server.name, :size => 0.05)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,41 @@
|
|
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 Rails access logs
|
8
|
+
class RailsParser < Parser
|
9
|
+
def parse( line )
|
10
|
+
#Completed in 0.02100 (47 reqs/sec) | Rendering: 0.01374 (65%) | DB: 0.00570 (27%) | 200 OK [http://example.com/whatever/whatever]
|
11
|
+
_, ms, url = /^Completed in ([\d.]+) .* \[([^\]]+)\]/.match(line).to_a
|
12
|
+
|
13
|
+
if url
|
14
|
+
_, host, url = /^http[s]?:\/\/([^\/]+)(.*)/.match(url).to_a
|
15
|
+
|
16
|
+
add_activity(:block => 'sites', :name => host, :size => ms.to_f) # Size of activity based on request time.
|
17
|
+
add_activity(:block => 'urls', :name => HttpHelper.generalize_url(url), :size => ms.to_f)
|
18
|
+
add_activity(:block => 'slow requests', :name => url, :size => ms.to_f)
|
19
|
+
add_activity(:block => 'content', :name => 'page')
|
20
|
+
|
21
|
+
# Events to pop up
|
22
|
+
add_event(:block => 'info', :name => "Logins", :message => "Login...", :update_stats => true, :color => [0.5, 1.0, 0.5, 1.0]) if url.include?('/login')
|
23
|
+
add_event(:block => 'info', :name => "Sales", :message => "$", :update_stats => true, :color => [1.5, 0.0, 0.0, 1.0]) if url.include?('/checkout')
|
24
|
+
add_event(:block => 'info', :name => "Signups", :message => "New User...", :update_stats => true, :color => [1.0, 1.0, 1.0, 1.0]) if(url.include?('/signup') || url.include?('/users/create'))
|
25
|
+
elsif line.include?('Processing ')
|
26
|
+
#Processing TasksController#update_sheet_info (for 123.123.123.123 at 2007-10-05 22:34:33) [POST]
|
27
|
+
_, host = /^Processing .* \(for (\d+.\d+.\d+.\d+) at .*\).*$/.match(line).to_a
|
28
|
+
if host
|
29
|
+
add_activity(:block => 'users', :name => host)
|
30
|
+
end
|
31
|
+
elsif line.include?('Error (')
|
32
|
+
_, error, msg = /^([^ ]+Error) \((.*)\):/.match(line).to_a
|
33
|
+
if error
|
34
|
+
add_event(:block => 'info', :name => "Exceptions", :message => error, :update_stats => true, :color => [1.0, 0.0, 0.0, 1.0])
|
35
|
+
add_event(:block => 'info', :name => "Exceptions", :message => msg, :update_stats => false, :color => [1.0, 0.0, 0.0, 1.0])
|
36
|
+
add_activity(:block => 'warnings', :name => msg)
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,25 @@
|
|
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 squid logs
|
8
|
+
class SquidParser < Parser
|
9
|
+
def parse( line )
|
10
|
+
_, delay, host, size, method, uri, user = /\d+.\d+ +(\d+) +(\d+.\d+.\d+.\d+.\d+).+ (\d+) (.+) (.+) (.+) .+ .+/.match(line).to_a
|
11
|
+
if host
|
12
|
+
if method != 'ICP_QUERY'
|
13
|
+
size = size.to_f / 100000.0
|
14
|
+
#Uncomment if you authenticate to use the proxy
|
15
|
+
#add_activity(:block => 'users', :name => user, :size => size)
|
16
|
+
add_activity(:block => 'hosts', :name => host, :size => size)
|
17
|
+
add_activity(:block => 'types', :name => method, :size => size) if method
|
18
|
+
_, site = /http:\/\/(.+?)\/.+/.match(uri).to_a
|
19
|
+
if site:
|
20
|
+
add_activity(:block => 'sites', :name => site, :size => size)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
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 tshark logs
|
8
|
+
class TSharkParser < Parser
|
9
|
+
|
10
|
+
def parse( line )
|
11
|
+
if(line.include?('->'))
|
12
|
+
time, srcip, arrow, destip, type, = line.split(" ")
|
13
|
+
add_activity(:block => 'users', :name => srcip)
|
14
|
+
add_activity(:block => 'types', :name => type)
|
15
|
+
end
|
16
|
+
|
17
|
+
if(line.include?('DNS Standard query A'))
|
18
|
+
foo, name = line.split(" A ")
|
19
|
+
if(name != nil)
|
20
|
+
add_event(:block => 'status', :name => "DNS Queries", :message => "DNS Request: " + name, :update_stats => true, :color => [1.5, 1.0, 0.5, 1.0])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'resolv-replace'
|
2
|
+
|
3
|
+
class Resolver
|
4
|
+
include GlTail::Configurable
|
5
|
+
|
6
|
+
config_attribute :reverse_ip_lookups, "Lookup Hostnames"
|
7
|
+
config_attribute :reverse_timeout, "Wait how long for DNS reply [s]"
|
8
|
+
|
9
|
+
def self.instance
|
10
|
+
@@instance ||= Resolver.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@cache = { }
|
15
|
+
@thread = nil
|
16
|
+
@reverse_ip_lookups = true
|
17
|
+
@reverse_timeout = 1.5
|
18
|
+
@queue = Queue.new
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :queue, :cache
|
22
|
+
|
23
|
+
def start
|
24
|
+
@thread = Thread.new {
|
25
|
+
while @reverse_ip_lookups
|
26
|
+
ip, element = @queue.pop
|
27
|
+
if @cache.include? ip
|
28
|
+
element.name = @cache[ip]
|
29
|
+
else
|
30
|
+
begin
|
31
|
+
timeout(@reverse_timeout.to_f) {
|
32
|
+
puts "[Resolver] Looking for #{ip}" if $DBG > 0
|
33
|
+
hostname = Resolv.getname(ip)
|
34
|
+
puts "[Resolver] Got #{hostname}[#{ip}]" if $DBG > 0
|
35
|
+
@cache[ip] = hostname
|
36
|
+
element.name = hostname
|
37
|
+
}
|
38
|
+
rescue Timeout::Error
|
39
|
+
puts "[Resolver] Timeout!" if $DBG > 0
|
40
|
+
rescue Resolv::ResolvError
|
41
|
+
# No result, don't bother retrying
|
42
|
+
@cache[ip] = ip
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def lookup(ip, element)
|
50
|
+
return ip if not @reverse_ip_lookups
|
51
|
+
|
52
|
+
if name = cache[ip]
|
53
|
+
return name
|
54
|
+
else
|
55
|
+
puts "[Resolver] Pushing #{ip} for lookup" if $DBG > 0
|
56
|
+
queue.push([ip, element])
|
57
|
+
end
|
58
|
+
|
59
|
+
return ip
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.resolv(ip, element)
|
64
|
+
instance.lookup(ip, element)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
Resolver.instance.start
|
@@ -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
|
+
class Server
|
8
|
+
attr_reader :name, :host, :color, :parser
|
9
|
+
|
10
|
+
|
11
|
+
def initialize(options)
|
12
|
+
@name = options[:name] || options[:host]
|
13
|
+
@host = options[:host]
|
14
|
+
@color = options[:color] || [1.0, 1.0, 1.0, 1.0]
|
15
|
+
@parser = Parser.registry[ options[:parser] ] || Parser.registry[ :apache ]
|
16
|
+
@blocks = options[:blocks]
|
17
|
+
@max_size = 1.0
|
18
|
+
|
19
|
+
# instantiate the parser
|
20
|
+
@parser = @parser.new( self )
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
#block, message, size
|
25
|
+
def add_activity(options = { })
|
26
|
+
size = $CONFIG.min_blob_size
|
27
|
+
if options[:size]
|
28
|
+
size = options[:size].to_f
|
29
|
+
@max_size = size if size > @max_size
|
30
|
+
size = $CONFIG.min_blob_size + ((size / @max_size) * ($CONFIG.max_blob_size - $CONFIG.min_blob_size))
|
31
|
+
options[:size] = size
|
32
|
+
end
|
33
|
+
|
34
|
+
block = @blocks[options[:block]].add_activity( { :name => @name, :color => @color, :size => $CONFIG.min_blob_size }.update(options) ) if (options[:block] && @blocks[options[:block]])
|
35
|
+
end
|
36
|
+
|
37
|
+
#block, message
|
38
|
+
def add_event(options = { })
|
39
|
+
block = @blocks[options[:block]].add_event( { :name => @name, :color => @color, :size => $CONFIG.min_blob_size}.update(options) ) if (options[:block] && @blocks[options[:block]])
|
40
|
+
end
|
41
|
+
|
42
|
+
def update
|
43
|
+
@max_size = @max_size * 0.99 if(@max_size * 0.99 > 1.0)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|