Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / ejabberd / ejabberd_scanlog @ 193bafb7

Historique | Voir | Annoter | Télécharger (4,1 ko)

1
#!/usr/bin/env ruby
2
require 'yaml'
3

    
4
# ejabberd_scanlog revision 2 (Mar 2012)
5
#
6
# Scans ejabberd 2.1.x log for known error signatures and counts them
7
#
8
# Required privileges: read ejabberd log (user ejabberd or, in some cases, root)
9
#
10
# OS: Unix
11
#
12
# Configuration:
13
# 	env.log: ejabberd log file (defaults to /var...)
14
#
15
# Author: Artem Sheremet <dot.doom@gmail.com>
16

    
17
#
18
# Run with 'debug' argument to initiate full log rescan.
19
# This will also print out unparsed log entries to stderr.
20
# Cache file will be untouched.
21
#
22

    
23
LOG_FILE = ENV['log'] || '/var/log/ejabberd/ejabberd.log'
24
CACHE_FILE = '/tmp/ejabberd_scanlog_cache' # cache file position
25

    
26
DEFAULT_CACHE = { :start => 0 }
27

    
28
$debug_mode = ARGV.first == 'debug'
29

    
30
if $debug_mode
31
	log_info = DEFAULT_CACHE
32
else
33
	begin
34
		log_info = YAML.load IO.read(CACHE_FILE)
35
	rescue
36
		log_info = DEFAULT_CACHE
37
	end
38

    
39
	if File.size(LOG_FILE) < log_info[:start]
40
		# logrotate?
41
		log_info = DEFAULT_CACHE
42
	end
43
end
44

    
45
if ARGV.first == 'reset'
46
	log_info = { :start => File.size(LOG_FILE)-1 }
47
	puts 'Log reset'
48
end
49

    
50
new_data = ''
51
File.open(LOG_FILE, 'rb') do |flog|
52
	flog.seek(log_info[:start])
53
	new_data = flog.read
54
end
55

    
56
KNOWN_LOG_TYPES = [
57
	# each element is an instance of Array. 1st item: error description, others: text to search log for
58
	['EJAB-1482 Crash when waiting for item',
59
		['wait_for_']],
60
	['EJAB-1483 ODBC sup failure (wrong PID?)',
61
 		['ejabberd_odbc_sup']],
62
	['EJAB-1483 ODBC sup wrong PID failure echo',
63
		["mod_pubsub_odbc,'-unsubscribe"]],
64
	['DNS failure',
65
		['You should check your DNS configuration']],
66
	['Database unavailable/too slow',
67
		['Database was not available or too slow']],
68
	['State machine terminated: timeout',
69
		['State machine',
70
		'terminating',
71
		'Reason for',
72
		'timeout']],
73
	['The auth module returned an error',
74
		['The authentication module',
75
		'returned an error']],
76
	['MySQL disconnected',
77
		['mysql',
78
		'Received unknown signal, exiting']],
79
	['Connecting to MySQL: failed',
80
		['mysql',
81
		'Failed connecting to']],
82
	['Timeout while running a hook',
83
		['ejabberd_hooks',
84
		'timeout']],
85
	['SQL transaction restarts exceeded',
86
		['SQL transaction restarts exceeded']],
87
	['Unexpected info',
88
		['nexpected info']],
89
	['Other sql_cmd timeout',
90
		['sql_cmd']],
91
	['System limit hit: ports', # check with length(erlang:ports())., set in ejabberdctl config file
92
		['system_limit',
93
		'open_port']],
94
	['Other system limit hit', # processes? check with erlang:system_info(process_count)., erlang:system_info(process_limit)., set in ejabberdctl cfg
95
		['system_limit']],
96
	['Generic server terminating',
97
		['Generic server',
98
		'terminating']],
99
	['Mnesia table shrinked',
100
		['shrinking table']],
101
	['Admin access failed',
102
		['Access of',
103
		'failed with error']],
104
	['MySQL sock timedout',
105
		['mysql_',
106
		': Socket',
107
		'timedout']],
108
	['Configuration error',
109
		['{badrecord,config}']],
110
	['Strange vCard error (vhost)',
111
		['error found when trying to get the vCard']],
112
	['Mnesia is overloaded',
113
		['Mnesia is overloaded']],
114
	['MySQL: init failed recv data',
115
		['mysql_conn: init failed receiving data']],
116
	['TCP Error',
117
		['Failed TCP']]
118
]
119

    
120
def log_type(text)
121
	KNOWN_LOG_TYPES.find_index { |entry|
122
		entry[1].all? { |substr| text.include? substr }
123
	}
124
end
125

    
126
new_data.split("\n=").each { |report|
127
	next if report.empty?
128
	report =~ /\A(\w+) REPORT==== (.*) ===\n(.*)\z/m
129
	type, time, text = $1, $2, $3
130
	next unless type and time and text
131

    
132
	log_info[type] = (log_info[type] || 0) + 1
133
	if sub_type = log_type(text)
134
		log_info[sub_type] = (log_info[sub_type] || 0) + 1
135
	elsif $debug_mode
136
		warn "Unparsed log entry #{type}: #{text} at #{time}"
137
	end
138
}
139

    
140
log_info[:start] += new_data.size
141
File.open(CACHE_FILE, 'w') { |f| f.write log_info.to_yaml } unless $debug_mode
142

    
143
if ARGV.first == 'config'
144
	puts <<CONFIG
145
graph_title Ejabberd Log
146
graph_vlabel total
147
graph_category jabber
148
graph_args -l 0
149
CONFIG
150
end
151

    
152
(KNOWN_LOG_TYPES + %w(ERROR WARNING INFO DEBUG)).each.with_index { |log_type, index|
153
	label, index = if log_type.is_a? Array
154
					   [log_type.first, index]
155
				   else
156
					   [log_type, log_type]
157
				   end
158
	if ARGV.first == 'config'
159
		puts "T#{index}.label #{label}"
160
		puts "T#{index}.draw LINE"
161
	else
162
		puts "T#{index}.value #{log_info[index] or 0}"
163
	end
164
}