line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Perl Module |
2
|
|
|
|
|
|
|
# Purpose: One Module to provide Syslog functionality |
3
|
|
|
|
|
|
|
# Provide log parser, sender, receiver |
4
|
|
|
|
|
|
|
# Author sparsons@cpan.org |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# Version |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
# 0.8.0 - initial test release |
10
|
|
|
|
|
|
|
# 0.8.1 - modify listener to make report and verbose > 1 independent |
11
|
|
|
|
|
|
|
# 0.8.2 - add counters for parse, filter, error |
12
|
|
|
|
|
|
|
# 0.9.0 - db storage is indexed |
13
|
|
|
|
|
|
|
# 0.9.1 - single quoted all hash index |
14
|
|
|
|
|
|
|
# 0.9.2 - modify parse engine |
15
|
|
|
|
|
|
|
# 1.0.0 - modify parse engine, user defined TAGS, forwarder in listen object |
16
|
|
|
|
|
|
|
# |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
package Net::Dev::Tools::Syslog; |
19
|
|
|
|
|
|
|
|
20
|
1
|
|
|
1
|
|
46118
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
115
|
|
21
|
1
|
|
|
1
|
|
1409
|
use Time::Local; |
|
1
|
|
|
|
|
3995
|
|
|
1
|
|
|
|
|
87
|
|
22
|
1
|
|
|
1
|
|
2137
|
use IO::Socket; |
|
1
|
|
|
|
|
63947
|
|
|
1
|
|
|
|
|
5
|
|
23
|
1
|
|
|
1
|
|
2874
|
use Sys::Hostname; |
|
1
|
|
|
|
|
1939
|
|
|
1
|
|
|
|
|
66
|
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
BEGIN { |
27
|
1
|
|
|
1
|
|
6
|
use Exporter(); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
38
|
|
28
|
1
|
|
|
1
|
|
15
|
our @ISA = qw(Exporter); |
29
|
1
|
|
|
|
|
68617
|
our $VERSION = 1.0.0; |
30
|
|
|
|
|
|
|
} |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# |
33
|
|
|
|
|
|
|
# Tags |
34
|
|
|
|
|
|
|
# |
35
|
|
|
|
|
|
|
our @PARSER_func = qw( |
36
|
|
|
|
|
|
|
parse_syslog_line |
37
|
|
|
|
|
|
|
parse_syslog_msg |
38
|
|
|
|
|
|
|
parse_tag |
39
|
|
|
|
|
|
|
syslog_stats_epoch2datestr |
40
|
|
|
|
|
|
|
); |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
our @TIME_func = qw( |
43
|
|
|
|
|
|
|
epoch_to_syslog_timestamp |
44
|
|
|
|
|
|
|
epoch_to_datestr |
45
|
|
|
|
|
|
|
make_timeslots |
46
|
|
|
|
|
|
|
epoch_timeslot_index |
47
|
|
|
|
|
|
|
date_filter_to_epoch |
48
|
|
|
|
|
|
|
); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
our @SYSLOG_func = qw( |
51
|
|
|
|
|
|
|
normalize_facility |
52
|
|
|
|
|
|
|
normalize_severity |
53
|
|
|
|
|
|
|
decode_PRI |
54
|
|
|
|
|
|
|
); |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
our @REFERENCE_func = qw( |
57
|
|
|
|
|
|
|
syslog_stats_href |
58
|
|
|
|
|
|
|
syslog_device_aref |
59
|
|
|
|
|
|
|
syslog_facility_aref |
60
|
|
|
|
|
|
|
syslog_severity_aref |
61
|
|
|
|
|
|
|
syslog_tag_aref |
62
|
|
|
|
|
|
|
syslog_timeslot_aref |
63
|
|
|
|
|
|
|
); |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
our @COUNTERS = qw( |
66
|
|
|
|
|
|
|
syslog_error_count |
67
|
|
|
|
|
|
|
syslog_filter_count |
68
|
|
|
|
|
|
|
syslog_parse_count |
69
|
|
|
|
|
|
|
); |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
our @EXPORT = ('syslog_error', @PARSER_func, @TIME_func, @SYSLOG_func, @REFERENCE_func, @COUNTERS ); |
76
|
|
|
|
|
|
|
our @EXPORT_OK = qw(); |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( |
79
|
|
|
|
|
|
|
parser => [@PARSER_func], |
80
|
|
|
|
|
|
|
time => [@TIME_func], |
81
|
|
|
|
|
|
|
syslog => [@SYSLOG_func], |
82
|
|
|
|
|
|
|
counter => [@COUNTERS], |
83
|
|
|
|
|
|
|
); |
84
|
|
|
|
|
|
|
# |
85
|
|
|
|
|
|
|
# Global variables |
86
|
|
|
|
|
|
|
# |
87
|
|
|
|
|
|
|
our $SYSLOG_href; |
88
|
|
|
|
|
|
|
our $ERROR; |
89
|
|
|
|
|
|
|
our $ERROR_count; |
90
|
|
|
|
|
|
|
our $FILTER_count; |
91
|
|
|
|
|
|
|
our $PARSE_count; |
92
|
|
|
|
|
|
|
our $DEBUG; |
93
|
|
|
|
|
|
|
our %FH; |
94
|
|
|
|
|
|
|
our %STATS; |
95
|
|
|
|
|
|
|
our @DEVICES; |
96
|
|
|
|
|
|
|
our @TAGS; |
97
|
|
|
|
|
|
|
our @FACILITYS; |
98
|
|
|
|
|
|
|
our @SEVERITYS; |
99
|
|
|
|
|
|
|
our @TIMESLOTS; |
100
|
|
|
|
|
|
|
our %LASTMSG; |
101
|
|
|
|
|
|
|
our $NOTAG = 'noTag'; |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
our $YEAR = ((localtime)[5]) + 1900; |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
our %WDAY = ( |
106
|
|
|
|
|
|
|
'0' => 'Sun', |
107
|
|
|
|
|
|
|
'1' => 'Mon', |
108
|
|
|
|
|
|
|
'2' => 'Tue', |
109
|
|
|
|
|
|
|
'3' => 'Wed', |
110
|
|
|
|
|
|
|
'4' => 'Thu', |
111
|
|
|
|
|
|
|
'5' => 'Fri', |
112
|
|
|
|
|
|
|
'6' => 'Sat', |
113
|
|
|
|
|
|
|
); |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
our %MON = ( |
116
|
|
|
|
|
|
|
1 => 'Jan', 2 => 'Feb', 3 => 'Mar', |
117
|
|
|
|
|
|
|
4 => 'Apr', 5 => 'May', 6 => 'Jun', |
118
|
|
|
|
|
|
|
7 => 'Jul', 8 => 'Aug', 9 => 'Sep', |
119
|
|
|
|
|
|
|
10 => 'Oct', 11 => 'Nov', 12 => 'Dec', |
120
|
|
|
|
|
|
|
); |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
our %MON_index = ( |
124
|
|
|
|
|
|
|
'JAN' => 1, 'Jan' => 1, 'jan' => 1, |
125
|
|
|
|
|
|
|
'FEB' => 2, 'Feb' => 2, 'feb' => 2, |
126
|
|
|
|
|
|
|
'MAR' => 3, 'Mar' => 3, 'mar' => 3, |
127
|
|
|
|
|
|
|
'APR' => 4, 'Apr' => 4, 'apr' => 4, |
128
|
|
|
|
|
|
|
'MAY' => 5, 'May' => 5, 'may' => 5, |
129
|
|
|
|
|
|
|
'JUN' => 6, 'Jun' => 6, 'jun' => 6, |
130
|
|
|
|
|
|
|
'JUL' => 7, 'Jul' => 7, 'jul' => 7, |
131
|
|
|
|
|
|
|
'AUG' => 8, 'Aug' => 8, 'aug' => 8, |
132
|
|
|
|
|
|
|
'SEP' => 9, 'Sep' => 9, 'sep' => 9, |
133
|
|
|
|
|
|
|
'OCT' => 10, 'Oct' => 10, 'oct' => 10, |
134
|
|
|
|
|
|
|
'NOV' => 11, 'Nov' => 11, 'nov' => 11, |
135
|
|
|
|
|
|
|
'DEC' => 12, 'Dec' => 12, 'dec' => 12, |
136
|
|
|
|
|
|
|
); |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
our %Syslog_Facility = ( |
140
|
|
|
|
|
|
|
'kern' => 0, 'kernel' => 0, |
141
|
|
|
|
|
|
|
'user' => 1, |
142
|
|
|
|
|
|
|
'mail' => 2, |
143
|
|
|
|
|
|
|
'daemon' => 3, |
144
|
|
|
|
|
|
|
'auth' => 4, |
145
|
|
|
|
|
|
|
'syslog' => 5, |
146
|
|
|
|
|
|
|
'lpr' => 6, |
147
|
|
|
|
|
|
|
'news' => 7, |
148
|
|
|
|
|
|
|
'uucp' => 8, |
149
|
|
|
|
|
|
|
'cron' => 9, |
150
|
|
|
|
|
|
|
'authpriv' => 10, |
151
|
|
|
|
|
|
|
'ftp' => 11, |
152
|
|
|
|
|
|
|
'ntp' => 12, |
153
|
|
|
|
|
|
|
'audit' => 13, |
154
|
|
|
|
|
|
|
'alert' => 14, |
155
|
|
|
|
|
|
|
'at' => 15, |
156
|
|
|
|
|
|
|
'local0' => 16, |
157
|
|
|
|
|
|
|
'local1' => 17, |
158
|
|
|
|
|
|
|
'local2' => 18, |
159
|
|
|
|
|
|
|
'local3' => 19, |
160
|
|
|
|
|
|
|
'local4' => 20, |
161
|
|
|
|
|
|
|
'local5' => 21, |
162
|
|
|
|
|
|
|
'local6' => 22, |
163
|
|
|
|
|
|
|
'local7' => 23, |
164
|
|
|
|
|
|
|
); |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
our %Facility_Index = ( |
168
|
|
|
|
|
|
|
0 => 'kern', |
169
|
|
|
|
|
|
|
1 => 'user', |
170
|
|
|
|
|
|
|
2 => 'mail', |
171
|
|
|
|
|
|
|
3 => 'daemon', |
172
|
|
|
|
|
|
|
4 => 'auth', |
173
|
|
|
|
|
|
|
5 => 'syslog', |
174
|
|
|
|
|
|
|
6 => 'lpr', |
175
|
|
|
|
|
|
|
7 => 'news', |
176
|
|
|
|
|
|
|
8 => 'uucp', |
177
|
|
|
|
|
|
|
9 => 'cron', |
178
|
|
|
|
|
|
|
10 => 'authpriv', |
179
|
|
|
|
|
|
|
11 => 'ftp', |
180
|
|
|
|
|
|
|
12 => 'ntp', |
181
|
|
|
|
|
|
|
13 => 'audit', |
182
|
|
|
|
|
|
|
14 => 'alert', |
183
|
|
|
|
|
|
|
15 => 'at', |
184
|
|
|
|
|
|
|
16 => 'local0', |
185
|
|
|
|
|
|
|
17 => 'local1', |
186
|
|
|
|
|
|
|
18 => 'local2', |
187
|
|
|
|
|
|
|
19 => 'local3', |
188
|
|
|
|
|
|
|
20 => 'local4', |
189
|
|
|
|
|
|
|
21 => 'local5', |
190
|
|
|
|
|
|
|
22 => 'local6', |
191
|
|
|
|
|
|
|
23 => 'local7', |
192
|
|
|
|
|
|
|
); |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
our %Severity_Index = ( |
195
|
|
|
|
|
|
|
0 => 'emerg', |
196
|
|
|
|
|
|
|
1 => 'alert', |
197
|
|
|
|
|
|
|
2 => 'crit', |
198
|
|
|
|
|
|
|
3 => 'err', |
199
|
|
|
|
|
|
|
4 => 'warn', |
200
|
|
|
|
|
|
|
5 => 'notice', |
201
|
|
|
|
|
|
|
6 => 'info', |
202
|
|
|
|
|
|
|
7 => 'debug' |
203
|
|
|
|
|
|
|
); |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
our %Syslog_Severity = ( |
209
|
|
|
|
|
|
|
'emerg' => 0, 'emergency' => 0, |
210
|
|
|
|
|
|
|
'alert' => 1, |
211
|
|
|
|
|
|
|
'crit' => 2, 'critical' => 2, |
212
|
|
|
|
|
|
|
'err' => 3, 'error' => 3, |
213
|
|
|
|
|
|
|
'warn' => 4, 'warning' => 4, |
214
|
|
|
|
|
|
|
'notice' => 5, |
215
|
|
|
|
|
|
|
'info' => 6, 'information' => 6, 'informational' => 6, |
216
|
|
|
|
|
|
|
'debug' => 7, |
217
|
|
|
|
|
|
|
); |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
our @FACILITY = qw( kern user mail daemon |
221
|
|
|
|
|
|
|
auth syslog lpr news |
222
|
|
|
|
|
|
|
uucp cron authpriv ftp |
223
|
|
|
|
|
|
|
ntp audit alert at |
224
|
|
|
|
|
|
|
local0 local1 local2 local3 |
225
|
|
|
|
|
|
|
local4 local5 local6 local7 |
226
|
|
|
|
|
|
|
); |
227
|
|
|
|
|
|
|
our @SEVERITY = qw( emerg alert crit err warn notice info debug); |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
# |
230
|
|
|
|
|
|
|
# syslog message |
231
|
|
|
|
|
|
|
# PRI HEADER MSG |
232
|
|
|
|
|
|
|
# PRI: <0-161> |
233
|
|
|
|
|
|
|
# HEADER: TIMESTAMP HOST |
234
|
|
|
|
|
|
|
# TIMESTAMP Xxx dd hh:mm:ss |
235
|
|
|
|
|
|
|
# Xxx d hh:mm:ss |
236
|
|
|
|
|
|
|
# HOST hostname or ip |
237
|
|
|
|
|
|
|
# MSG: TAG Content |
238
|
|
|
|
|
|
|
# TAG no more than 32 chars |
239
|
|
|
|
|
|
|
# |
240
|
|
|
|
|
|
|
# |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
# |
243
|
|
|
|
|
|
|
# Define Reg expr strings |
244
|
|
|
|
|
|
|
# |
245
|
|
|
|
|
|
|
# PRI |
246
|
|
|
|
|
|
|
# $1 = decimal value of PRI |
247
|
|
|
|
|
|
|
# |
248
|
|
|
|
|
|
|
our $PRI = '<(\d{1,3})>'; |
249
|
|
|
|
|
|
|
# |
250
|
|
|
|
|
|
|
# Timestamp |
251
|
|
|
|
|
|
|
# $1 = whole timestamp |
252
|
|
|
|
|
|
|
# $2 = Month string |
253
|
|
|
|
|
|
|
# $3 = Month day (decimal) |
254
|
|
|
|
|
|
|
# $4 = hh:mm::ss |
255
|
|
|
|
|
|
|
# |
256
|
|
|
|
|
|
|
our $TIMESTAMP_strict = '(([JFMASOND]\w\w) {1,2}(\d+) (\d{2}:\d{2}:\d{2}))'; |
257
|
|
|
|
|
|
|
our $TIMESTAMP = '(([JFMASONDjfmasond]\w\w) {1,2}(\d+) (\d{2}:\d{2}:\d{2}))'; |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
# |
260
|
|
|
|
|
|
|
# Hostname |
261
|
|
|
|
|
|
|
# alphanumeric string including '_', '.' |
262
|
|
|
|
|
|
|
# $1 = hostname |
263
|
|
|
|
|
|
|
# |
264
|
|
|
|
|
|
|
our $HOSTNAME = '([a-zA-Z0-9_\.\-]+)'; |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
# |
268
|
|
|
|
|
|
|
# let user define TAG patterns |
269
|
|
|
|
|
|
|
# |
270
|
|
|
|
|
|
|
# $TAG_1 $1 = tag, $2 = pid, $3 = content |
271
|
|
|
|
|
|
|
# $TAG_2 $1 = tag, $2 = content no pid |
272
|
|
|
|
|
|
|
# $TAG_3 $1 = tag, $2 = pid, $3 = content |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
our $TAG_1 = ''; |
276
|
|
|
|
|
|
|
our $TAG_2 = ''; |
277
|
|
|
|
|
|
|
our $TAG_3 = ''; |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
# |
281
|
|
|
|
|
|
|
# Content |
282
|
|
|
|
|
|
|
# $1 = message |
283
|
|
|
|
|
|
|
our $MESSAGE = '(.+)$'; |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
our $SYSLOG_pattern = sprintf("^%s{1} %s %s", $TIMESTAMP, $HOSTNAME, $MESSAGE); |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
# |
292
|
|
|
|
|
|
|
#============================================================================= |
293
|
|
|
|
|
|
|
# |
294
|
|
|
|
|
|
|
# Methods and Functions |
295
|
|
|
|
|
|
|
# |
296
|
|
|
|
|
|
|
# |
297
|
|
|
|
|
|
|
# Syslog Constructor |
298
|
|
|
|
|
|
|
# |
299
|
|
|
|
|
|
|
# Use the anonymous hash to hold info for rest of module |
300
|
|
|
|
|
|
|
# |
301
|
|
|
|
|
|
|
# Arguments |
302
|
|
|
|
|
|
|
# dump 0|1 (0) write to file |
303
|
|
|
|
|
|
|
# append 0|1 (1) append to existing report |
304
|
|
|
|
|
|
|
# ext extension (.slp) |
305
|
|
|
|
|
|
|
# report 0|1 (1) create report |
306
|
|
|
|
|
|
|
# interval report time slot interval |
307
|
|
|
|
|
|
|
# rx_time 0|1 determine if we should use msg time or preamble time |
308
|
|
|
|
|
|
|
# lastmsg 0|1 (0) do not use last message values |
309
|
|
|
|
|
|
|
# moreTime 0|1 (0) parse and calculate more time info |
310
|
|
|
|
|
|
|
# parseTag 0|1 (0) parse TAG from SYSLOG MESSAGE |
311
|
|
|
|
|
|
|
# debug 0-3 (0) debug level |
312
|
|
|
|
|
|
|
# format (bsd) syslog format line |
313
|
|
|
|
|
|
|
# filters |
314
|
|
|
|
|
|
|
# tag string in tag to filter |
315
|
|
|
|
|
|
|
# min_date min date mm/dd/yyyy hh:mm:ss |
316
|
|
|
|
|
|
|
# min_date_epoch filter_min_date => epoch |
317
|
|
|
|
|
|
|
# max_date max date mm/dd/yyyy hh:mm:ss |
318
|
|
|
|
|
|
|
# max_date_epoch max_date => epoch |
319
|
|
|
|
|
|
|
# device |
320
|
|
|
|
|
|
|
# format format of expected syslog message |
321
|
|
|
|
|
|
|
# bsd (timestamp, host, tag, content) |
322
|
|
|
|
|
|
|
# noHost (timestamp, tag, content) |
323
|
|
|
|
|
|
|
# |
324
|
|
|
|
|
|
|
# |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
sub parse { |
327
|
|
|
|
|
|
|
# create object |
328
|
0
|
|
|
0
|
1
|
|
my $_proto = shift; |
329
|
0
|
|
0
|
|
|
|
my $_class = ref($_proto) || $_proto; |
330
|
0
|
|
|
|
|
|
my $_this = {}; |
331
|
|
|
|
|
|
|
# bless object |
332
|
0
|
|
|
|
|
|
bless($_this, $_class); |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
# get object arguments |
335
|
0
|
|
|
|
|
|
my %_arg = @_; |
336
|
0
|
|
|
|
|
|
my $_a; |
337
|
|
|
|
|
|
|
|
338
|
0
|
|
|
|
|
|
$ERROR = ''; |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
#rg{$_a}); define defaults |
341
|
0
|
|
|
|
|
|
$_this->{'ext'} = 'slp'; |
342
|
0
|
|
|
|
|
|
$_this->{'dump'} = 0; # default not to dump |
343
|
0
|
|
|
|
|
|
$_this->{'report'} = 1; # default to report |
344
|
0
|
|
|
|
|
|
$_this->{'append'} = 0; # default not to append |
345
|
0
|
|
|
|
|
|
$_this->{'interval'} = 3600; # default timeslot interval |
346
|
0
|
|
|
|
|
|
$_this->{'rx_time'} = 0; # default to not use time stamp from preamble |
347
|
0
|
|
|
|
|
|
$_this->{'lastmsg'} = 0; # default to not redo last message when 'last msg' line |
348
|
0
|
|
|
|
|
|
$_this->{'debug'} = 0; |
349
|
0
|
|
|
|
|
|
$_this->{'filter'} = 0; # default no filtering |
350
|
0
|
|
|
|
|
|
$_this->{'format'} = 'bsd'; # default syslog message string to bsd |
351
|
0
|
|
|
|
|
|
$_this->{'moreTime'} = 0; # default time analysis |
352
|
0
|
|
|
|
|
|
$_this->{'parseTag'} = 0; # default tha parsing of TAGs |
353
|
|
|
|
|
|
|
|
354
|
0
|
|
|
|
|
|
foreach $_a (keys %_arg) { |
355
|
0
|
0
|
|
|
|
|
if ($_a =~ /^-?dump$/i) {$_this->{'dump'} = delete($_arg{$_a}); } |
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
356
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?append$/i) {$_this->{'append'} = delete($_arg{$_a}); } |
357
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?ext$/i) {$_this->{'ext'} = delete($_arg{$_a}); } |
358
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?report$/i) {$_this->{'report'} = delete($_arg{$_a}); } |
359
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?interval$/i) {$_this->{'interval'} = delete($_arg{$_a}); } |
360
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?rx_time$/i) {$_this->{'rx_time'} = delete($_arg{$_a}); } |
361
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?lastmsg$/i) {$_this->{'lastmsg'} = delete($_arg{$_a}); } |
362
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?debug$/i) {$_this->{'debug'} = delete($_arg{$_a}); } |
363
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?min_date$/i) {$_this->{'filter_min_date'} = delete($_arg{$_a}); } |
364
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?max_date$/i) {$_this->{'filter_max_date'} = delete($_arg{$_a}); } |
365
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?device$/i) {$_this->{'filter_device'} = delete($_arg{$_a}); } |
366
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?tag$/i) {$_this->{'filter_tag'} = delete($_arg{$_a}); } |
367
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?message$/i) {$_this->{'filter_message'} = delete($_arg{$_a}); } |
368
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?format$/i) {$_this->{'format'} = delete($_arg{$_a}); } |
369
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?moreTime$/i) {$_this->{'moreTime'} = delete($_arg{$_a}); } |
370
|
|
|
|
|
|
|
elsif ($_a =~ /^-?parseTag$/i) {$_this->{'parseTag'} = delete($_arg{$_a}); } |
371
|
|
|
|
|
|
|
else { |
372
|
0
|
|
|
|
|
|
$ERROR = "unsupported option $_a => $_arg{$_a}"; |
373
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
374
|
|
|
|
|
|
|
} |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
# set globals |
378
|
0
|
|
|
|
|
|
$DEBUG = $_this->{'debug'}; |
379
|
0
|
|
|
|
|
|
$ERROR_count = 0; |
380
|
0
|
|
|
|
|
|
$FILTER_count = 0; |
381
|
0
|
|
|
|
|
|
$PARSE_count = 0; |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
# init stat hash |
384
|
0
|
0
|
|
|
|
|
if ($_this->{'report'}) {%STATS = ();} |
|
0
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
# check format |
388
|
0
|
0
|
0
|
|
|
|
if ($_this->{'format'} ne 'bsd' && $_this->{'format'} ne 'noHost') { |
389
|
0
|
|
|
|
|
|
$ERROR = "unsupported format [$_this->{'format'}]"; |
390
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
391
|
|
|
|
|
|
|
} |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
# |
394
|
|
|
|
|
|
|
# check arguments |
395
|
|
|
|
|
|
|
# |
396
|
|
|
|
|
|
|
# if dump is enabled, |
397
|
0
|
0
|
|
|
|
|
if ($_this->{'dump'}) { |
398
|
0
|
|
|
|
|
|
$_this->{'repository'} = $_this->{'dump'}; |
399
|
|
|
|
|
|
|
# make sure we have trailing '/' or '\' |
400
|
0
|
0
|
|
|
|
|
if ($^O eq 'MSWin32') { |
401
|
0
|
0
|
|
|
|
|
if ($_this->{'repository'} !~ /\\$/) |
|
0
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
{$_this->{'repository'} = $_this->{'repository'} . '\\';} |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
else { |
405
|
0
|
0
|
|
|
|
|
if ($_this->{'repository'} !~ /\/$/) |
|
0
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
{$_this->{'repository'} = $_this->{'repository'} . '/';} |
407
|
|
|
|
|
|
|
} |
408
|
|
|
|
|
|
|
# check if writable |
409
|
0
|
0
|
|
|
|
|
if (!-w $_this->{'repository'}) { |
410
|
0
|
|
|
|
|
|
$ERROR = "dump site not writeable"; |
411
|
0
|
|
|
|
|
|
$_this = undef; |
412
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
} |
415
|
|
|
|
|
|
|
# |
416
|
|
|
|
|
|
|
# interval can not be less than 1 min (60 sec), since the index |
417
|
|
|
|
|
|
|
# only goes down to the minute |
418
|
|
|
|
|
|
|
# |
419
|
0
|
0
|
|
|
|
|
if ($_this->{'interval'} < 60) { |
420
|
0
|
|
|
|
|
|
$_this->{'interval'} = 60; |
421
|
0
|
|
|
|
|
|
log_debug(3, "NOTICE: interval changed to 60 seconds\n"); |
422
|
|
|
|
|
|
|
} |
423
|
|
|
|
|
|
|
# filtering may need other settings enabled |
424
|
0
|
0
|
0
|
|
|
|
if ($_this->{'filter_min_date'} || $_this->{'filter_max_date'}) {$_this->{'moreTime'} = 1;} |
|
0
|
|
|
|
|
|
|
425
|
0
|
0
|
|
|
|
|
if ($_this->{'filter_device'}) {$_this->{'format'} = 'bsd';} |
|
0
|
|
|
|
|
|
|
426
|
0
|
0
|
|
|
|
|
if ($_this->{'filter_tag'}) {$_this->{'parseTag'} = 1;} |
|
0
|
|
|
|
|
|
|
427
|
0
|
0
|
|
|
|
|
if ($_this->{'report'}) {$_this->{'moreTime'} = 1;} |
|
0
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
# |
430
|
|
|
|
|
|
|
# if we have any filters defined, then enable filtering |
431
|
|
|
|
|
|
|
# |
432
|
0
|
0
|
0
|
|
|
|
$_this->{'filter'} = 1 if $_this->{'filter_min_date'} || $_this->{'filter_max_date'} || |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
433
|
|
|
|
|
|
|
$_this->{'filter_device'} || $_this->{'filter_tag'} || |
434
|
|
|
|
|
|
|
$_this->{'filter_message'}; |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
# check min and max date |
437
|
0
|
0
|
|
|
|
|
if ($_this->{'filter_min_date'}) { |
438
|
0
|
|
|
|
|
|
log_debug(3, "convert min date: [%s]\n", $_this->{'filter_min_date'}); |
439
|
0
|
|
|
|
|
|
$_this->{'filter_min_date_epoch'} = date_filter_to_epoch($_this->{'filter_min_date'}); |
440
|
0
|
0
|
|
|
|
|
unless($_this->{'filter_min_date_epoch'}) { |
441
|
0
|
|
|
|
|
|
$ERROR = "min date filter epoch undefined"; |
442
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
443
|
|
|
|
|
|
|
} |
444
|
0
|
|
|
|
|
|
log_debug(3, "converted min date to: [%s]\n", $_this->{'filter_min_date_epoch'}, |
445
|
|
|
|
|
|
|
epoch_to_datestr($_this->{'filter_min_date_epoch'}), |
446
|
|
|
|
|
|
|
); |
447
|
|
|
|
|
|
|
} |
448
|
0
|
0
|
|
|
|
|
if ($_this->{'filter_max_date'}) { |
449
|
0
|
|
|
|
|
|
log_debug(3, "convert max date: [%s]\n", $_this->{'filter_max_date'}); |
450
|
0
|
|
|
|
|
|
$_this->{'filter_max_date_epoch'} = date_filter_to_epoch($_this->{'filter_max_date'}); |
451
|
0
|
0
|
|
|
|
|
unless($_this->{'filter_max_date_epoch'}) { |
452
|
0
|
|
|
|
|
|
$ERROR = "max date filter epoch undefined"; |
453
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
454
|
|
|
|
|
|
|
} |
455
|
0
|
|
|
|
|
|
log_debug(3, "converted max date to: [%s]\n", $_this->{'filter_max_date_epoch'}, |
456
|
|
|
|
|
|
|
epoch_to_datestr($_this->{'filter_max_date_epoch'}) |
457
|
|
|
|
|
|
|
); |
458
|
|
|
|
|
|
|
} |
459
|
|
|
|
|
|
|
|
460
|
0
|
0
|
0
|
|
|
|
if ($_this->{'filter_min_date'} && $_this->{'filter_max_date'}) { |
461
|
0
|
|
|
|
|
|
log_debug(3, "check min and max date range\n"); |
462
|
0
|
0
|
|
|
|
|
if ($_this->{'filter_min_date_epoch'} >= $_this->{'filter_max_date_epoch'}) { |
463
|
0
|
|
|
|
|
|
$ERROR = sprintf("filter_min_date >= filter_max_date: %s >= %s", |
464
|
|
|
|
|
|
|
_commify($_this->{'filter_min_date_epoch'}), |
465
|
|
|
|
|
|
|
_commify($_this->{'filter_max_date_epoch'}), |
466
|
|
|
|
|
|
|
); |
467
|
0
|
|
|
|
|
|
log_debug(2, "%s\n", $ERROR); |
468
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
469
|
|
|
|
|
|
|
} |
470
|
0
|
|
|
|
|
|
log_debug(3, "min max date range: [%s] => [%s]\n", |
471
|
|
|
|
|
|
|
$_this->{'filter_min_date'}, $_this->{'filter_max_date'}, |
472
|
|
|
|
|
|
|
); |
473
|
0
|
|
|
|
|
|
log_debug(3, "min max date range: [%s] => [%s]\n", |
474
|
|
|
|
|
|
|
_commify($_this->{'filter_min_date_epoch'}), _commify($_this->{'filter_max_date_epoch'}) |
475
|
|
|
|
|
|
|
); |
476
|
|
|
|
|
|
|
} |
477
|
|
|
|
|
|
|
|
478
|
0
|
0
|
|
|
|
|
if ($DEBUG) { |
479
|
0
|
|
|
|
|
|
foreach (sort keys %{$_this}) { |
|
0
|
|
|
|
|
|
|
480
|
0
|
|
|
|
|
|
log_debug(2, "parse object properties: %-12s => [%s]\n", $_, $_this->{$_}); |
481
|
|
|
|
|
|
|
} |
482
|
|
|
|
|
|
|
} |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
# return reference to object |
485
|
0
|
0
|
|
|
|
|
return(wantarray ? ($_this, $ERROR) : $_this); |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
} # end sub parse |
488
|
|
|
|
|
|
|
# |
489
|
|
|
|
|
|
|
#............................................................................. |
490
|
|
|
|
|
|
|
# |
491
|
|
|
|
|
|
|
# Function to parse syslog line and populate hash ref $SYSLOG_href |
492
|
|
|
|
|
|
|
# |
493
|
|
|
|
|
|
|
# $SYSLOG_href->{'line'} current line from syslog file |
494
|
|
|
|
|
|
|
# {'timestamp'} timestamp from syslog message |
495
|
|
|
|
|
|
|
# {'device'} device name from syslog message |
496
|
|
|
|
|
|
|
# {'message'} syslog message, from after devname |
497
|
|
|
|
|
|
|
# |
498
|
|
|
|
|
|
|
# {'month_str'} month from syslog message timestamp (Jan, Feb, ..) |
499
|
|
|
|
|
|
|
# {'month'} month index 0->11 |
500
|
|
|
|
|
|
|
# {'day'} day from syslog message timestamp |
501
|
|
|
|
|
|
|
# {'time_str'} hh:mm:ss from syslog message timestamp |
502
|
|
|
|
|
|
|
# {'hour'} hh from syslog message timestamp |
503
|
|
|
|
|
|
|
# {'min'} mm from syslog message timestamp |
504
|
|
|
|
|
|
|
# {'sec'} ss from syslog message timestamp |
505
|
|
|
|
|
|
|
# {'year'} year assumed from localtime |
506
|
|
|
|
|
|
|
# {'epoch'} epoch time converted from syslog message timestamp |
507
|
|
|
|
|
|
|
# {'wday'} wday integer derived from epoch (0-6) = (Sun-Sat) |
508
|
|
|
|
|
|
|
# {'wday_str'} wday string converted, (Sun, Mon, ...) |
509
|
|
|
|
|
|
|
# {'date_str'} syslog message {'epoch'} convert to common format |
510
|
|
|
|
|
|
|
# |
511
|
|
|
|
|
|
|
# {'tag'} syslog message content tag |
512
|
|
|
|
|
|
|
# {'pid'} syslog message content tag pid |
513
|
|
|
|
|
|
|
# {'content'} syslog message content after tag parsed out |
514
|
|
|
|
|
|
|
# |
515
|
|
|
|
|
|
|
# {'preamble'} |
516
|
|
|
|
|
|
|
# {'rx_epoch'} extra info: rx time epoch |
517
|
|
|
|
|
|
|
# {'rx_timestamp'} extra info: rx timestamp |
518
|
|
|
|
|
|
|
# {'rx_priority'} extra info: priority (text) |
519
|
|
|
|
|
|
|
# {'rx_facility'} extra info: syslog facility (text) |
520
|
|
|
|
|
|
|
# {'rx_severity'} extra info: syslog severity (text) |
521
|
|
|
|
|
|
|
# {'srcIP'} extra info: src IP address |
522
|
|
|
|
|
|
|
# |
523
|
|
|
|
|
|
|
# {'rx_epoch'} extra info: rx time epoch |
524
|
|
|
|
|
|
|
# {'rx_date_str'} extra info: rx time date string |
525
|
|
|
|
|
|
|
# {'rx_time_str'} extra info: rx time (hh:mm:ss) |
526
|
|
|
|
|
|
|
# {'rx_year'} extra info: rx time year value |
527
|
|
|
|
|
|
|
# {'rx_month'} extra info: rx time month value |
528
|
|
|
|
|
|
|
# {'rx_month_str'} extra info: rx time month value string (Jan, Feb,..) |
529
|
|
|
|
|
|
|
# {'rx_day'} extra info: rx time day value |
530
|
|
|
|
|
|
|
# {'rx_wday'} extra info: rx time weekday (0-6) (Sun, Mon,..) |
531
|
|
|
|
|
|
|
# {'rx_hour'} extra info: rx time hour value |
532
|
|
|
|
|
|
|
# {'rx_min'} extra info: rx time minute value |
533
|
|
|
|
|
|
|
# {'rx_sec'} extra info: rx time second value |
534
|
|
|
|
|
|
|
# Arg |
535
|
|
|
|
|
|
|
# $_[0] - line from syslog file |
536
|
|
|
|
|
|
|
# |
537
|
|
|
|
|
|
|
sub parse_syslog_line { |
538
|
0
|
|
|
0
|
1
|
|
my $_obj = shift; |
539
|
0
|
|
0
|
|
|
|
my $_line = shift || $_; |
540
|
|
|
|
|
|
|
|
541
|
0
|
|
|
|
|
|
my ($_preamble, $_msg, $_ok, $_last); |
542
|
0
|
|
|
|
|
|
my @_pre = (); |
543
|
|
|
|
|
|
|
|
544
|
0
|
|
|
|
|
|
%{$SYSLOG_href} = (); |
|
0
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
|
546
|
0
|
|
|
|
|
|
$SYSLOG_href->{'device'} = ''; |
547
|
0
|
|
|
|
|
|
$SYSLOG_href->{'format'} = $_obj->{'format'}; |
548
|
|
|
|
|
|
|
|
549
|
0
|
|
|
|
|
|
$PARSE_count++; |
550
|
0
|
|
|
|
|
|
$_line =~ s/\n$//; |
551
|
0
|
|
|
|
|
|
$SYSLOG_href->{'line'} = $_line; |
552
|
|
|
|
|
|
|
|
553
|
0
|
|
|
|
|
|
log_debug(2, "func: parse_syslog_line\n"); |
554
|
0
|
|
|
|
|
|
log_debug(1, "[%s]: [%s]\n", $., $_line); |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
# if given line is blank ignore it, |
557
|
|
|
|
|
|
|
# it can throw off the stats |
558
|
0
|
0
|
|
|
|
|
if ($_line =~ /^\s*$/) { |
559
|
0
|
|
|
|
|
|
$ERROR = 'disregarding current line: blank line'; |
560
|
0
|
|
|
|
|
|
$ERROR_count++; |
561
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
562
|
|
|
|
|
|
|
} |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
# |
565
|
|
|
|
|
|
|
# Set syslog message parser |
566
|
|
|
|
|
|
|
# |
567
|
0
|
0
|
|
|
|
|
if ($_obj->{'format'} eq "bsd") |
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
568
|
0
|
|
|
|
|
|
{$SYSLOG_pattern = sprintf("%s{1} %s %s", $TIMESTAMP,$HOSTNAME,$MESSAGE);} |
569
|
|
|
|
|
|
|
elsif ($_obj->{'format'} eq "noHost") |
570
|
|
|
|
|
|
|
{$SYSLOG_pattern = sprintf("%s{1} %s", $TIMESTAMP, $MESSAGE);} |
571
|
|
|
|
|
|
|
elsif ($_obj->{'format'} eq "self") |
572
|
0
|
|
|
|
|
|
{ 1; } |
573
|
|
|
|
|
|
|
else { |
574
|
0
|
|
|
|
|
|
$ERROR = "unsupported syslog message format: $_obj->{'format'}"; |
575
|
0
|
|
|
|
|
|
$ERROR_count++; |
576
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
577
|
|
|
|
|
|
|
} |
578
|
0
|
|
|
|
|
|
log_debug(3, "pattern [%s]: %s\n", $_obj->{'format'}, $SYSLOG_pattern); |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
# see if we have more than just the syslog message |
582
|
0
|
0
|
|
|
|
|
if ($_line =~ /^(\<\d{1,3}\>)?($SYSLOG_pattern)/) {$_preamble = $1; $_msg = $2} |
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
583
|
0
|
|
|
|
|
|
elsif ($_line =~ /^(.+)\s+($SYSLOG_pattern)/) {$_preamble = $1; $_msg = $2} |
|
0
|
|
|
|
|
|
|
584
|
0
|
|
|
|
|
|
elsif ($_line =~ /^(.+),($SYSLOG_pattern)/) {$_preamble = $1; $_msg = $2, |
|
0
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
$_preamble =~ s/\,/ /g; |
586
|
|
|
|
|
|
|
} |
587
|
0
|
|
|
|
|
|
else {$_preamble = undef; $_msg = $_line;} |
588
|
|
|
|
|
|
|
|
589
|
0
|
|
0
|
|
|
|
log_debug(2, "syslog preamble: %s\n", $_preamble || 'none'); |
590
|
0
|
|
0
|
|
|
|
log_debug(2, "syslog message: %s\n", $_msg || 'NO MESSAGE'); |
591
|
|
|
|
|
|
|
# |
592
|
|
|
|
|
|
|
# parse syslog message |
593
|
|
|
|
|
|
|
# |
594
|
0
|
|
|
|
|
|
parse_syslog_msg($_msg, $_obj->{'moreTime'}, $_obj->{'parseTag'}, 1); |
595
|
0
|
0
|
0
|
|
|
|
if ($SYSLOG_href->{'device'} eq '' && $_obj->{'format'} ne 'noHost') { |
596
|
0
|
|
|
|
|
|
$ERROR = 'no device name parsed from line'; |
597
|
0
|
|
|
|
|
|
$ERROR_count++; |
598
|
|
|
|
|
|
|
#return(wantarray ? (undef, $ERROR) : undef); |
599
|
|
|
|
|
|
|
} |
600
|
|
|
|
|
|
|
# |
601
|
|
|
|
|
|
|
# if we have a preamble, parse it out |
602
|
|
|
|
|
|
|
# |
603
|
0
|
0
|
|
|
|
|
if ($_preamble) { |
604
|
0
|
|
|
|
|
|
$_preamble =~ s/UTC//; |
605
|
0
|
|
|
|
|
|
log_debug(2, "syslog line contains preamble:\n"); |
606
|
|
|
|
|
|
|
# preamble: yyyy-mm-dd hh:mm:ss prio ip |
607
|
0
|
|
|
|
|
|
parse_preamble($_preamble); |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
# determine what time we want to keep |
610
|
0
|
0
|
|
|
|
|
if ($_obj->{'rx_time'}) { |
611
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'timestamp'} = $SYSLOG_href->{'rx_timestamp'} || $SYSLOG_href->{'timestamp'}; |
612
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'epoch'} = $SYSLOG_href->{'rx_epoch'} || $SYSLOG_href->{'epoch'}; |
613
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'month'} = $SYSLOG_href->{'rx_month'} || $SYSLOG_href->{'month'}; |
614
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'month_str'} = $SYSLOG_href->{'rx_month_str'} || $SYSLOG_href->{'month_str'}; |
615
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'day'} = $SYSLOG_href->{'rx_day'} || $SYSLOG_href->{'day'}; |
616
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'time_str'} = $SYSLOG_href->{'rx_time_str'} || $SYSLOG_href->{'time_str'}; |
617
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'hour'} = $SYSLOG_href->{'rx_hour'} || $SYSLOG_href->{'hour'}; |
618
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'min'} = $SYSLOG_href->{'rx_min'} || $SYSLOG_href->{'min'}; |
619
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'sec'} = $SYSLOG_href->{'rx_sec'} || $SYSLOG_href->{'sec'}; |
620
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'year'} = $SYSLOG_href->{'rx_year'} || $SYSLOG_href->{'year'}; |
621
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'wday'} = $SYSLOG_href->{'rx_wday'} || $SYSLOG_href->{'wday'}; |
622
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'wday_str'} = $SYSLOG_href->{'rx_wday_str'} || $SYSLOG_href->{'wday_str'}; |
623
|
0
|
|
0
|
|
|
|
$SYSLOG_href->{'date_str'} = $SYSLOG_href->{'rx_date_str'} || $SYSLOG_href->{'date_str'}; |
624
|
|
|
|
|
|
|
|
625
|
0
|
|
|
|
|
|
log_debug(2, "INFO: using rx_time info instead of message timestamp info\n"); |
626
|
|
|
|
|
|
|
} |
627
|
|
|
|
|
|
|
} |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
# |
630
|
|
|
|
|
|
|
# make sure we have device name from the syslog line |
631
|
|
|
|
|
|
|
# |
632
|
0
|
|
|
|
|
|
log_debug(2, "device name check: dev: [%s] srcIP: [%s] \n", |
633
|
|
|
|
|
|
|
$SYSLOG_href->{'device'}, $SYSLOG_href->{'rx_srcIP'} |
634
|
|
|
|
|
|
|
); |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
# check we have device name |
637
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'device'}) { |
|
|
0
|
|
|
|
|
|
638
|
0
|
|
|
|
|
|
log_debug(2, "device name check: keep syslog message device name: %s\n", $SYSLOG_href->{'device'}); |
639
|
|
|
|
|
|
|
} |
640
|
|
|
|
|
|
|
elsif ( $SYSLOG_href->{'rx_srcIP'} ) { |
641
|
0
|
|
|
|
|
|
log_debug(2, "device name change dev: [%s] <= srcIP [%s]\n", |
642
|
|
|
|
|
|
|
$SYSLOG_href->{'device'}, $SYSLOG_href->{'rx_srcIP'}, |
643
|
|
|
|
|
|
|
); |
644
|
0
|
|
|
|
|
|
$SYSLOG_href->{'device'} = $SYSLOG_href->{'rx_srcIP'}; |
645
|
|
|
|
|
|
|
} |
646
|
|
|
|
|
|
|
else { |
647
|
0
|
|
|
|
|
|
log_debug(2, "device name change: no device name or srcIP, change to noHost\n"); |
648
|
0
|
|
|
|
|
|
$SYSLOG_href->{'device'} = 'noHost'; |
649
|
|
|
|
|
|
|
} |
650
|
0
|
|
|
|
|
|
log_debug(2, "device name: set to [%s]\n", $SYSLOG_href->{'device'}); |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
# |
655
|
|
|
|
|
|
|
# check filters |
656
|
|
|
|
|
|
|
# |
657
|
0
|
0
|
|
|
|
|
if ($_obj->{'filter'}) { |
658
|
|
|
|
|
|
|
# check min date filter |
659
|
0
|
0
|
|
|
|
|
if ($_obj->{'filter_min_date_epoch'}) { |
660
|
0
|
|
|
|
|
|
log_debug(3, "INFO: MIN filter: min_date_epoch [%s] [%s]\n", |
661
|
|
|
|
|
|
|
_commify($_obj->{'filter_min_date_epoch'}), $_obj->{'filter_min_date'}, |
662
|
|
|
|
|
|
|
); |
663
|
0
|
0
|
0
|
|
|
|
if ($SYSLOG_href->{'rx_epoch'} && $_obj->{'rx_time'}) { |
|
|
0
|
|
|
|
|
|
664
|
0
|
|
|
|
|
|
log_debug(3, "rx_epoch and rx_time : true\n"); |
665
|
0
|
|
|
|
|
|
log_debug(3, "is %s < %s\n", _commify($SYSLOG_href->{'rx_epoch'}), |
666
|
|
|
|
|
|
|
_commify($_obj->{'filter_min_date_epoch'}) |
667
|
|
|
|
|
|
|
); |
668
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'rx_epoch'} < $_obj->{'filter_min_date_epoch'}) { |
669
|
0
|
|
|
|
|
|
$ERROR = sprintf("FILTER: rx date %s less than min filter date %s", |
670
|
|
|
|
|
|
|
$SYSLOG_href->{'rx_date_str'}, $_obj->{'filter_min_date'} |
671
|
|
|
|
|
|
|
); |
672
|
0
|
|
|
|
|
|
log_debug(3, "%s\n", $ERROR); |
673
|
0
|
|
|
|
|
|
$FILTER_count++; |
674
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
675
|
|
|
|
|
|
|
} |
676
|
|
|
|
|
|
|
} |
677
|
|
|
|
|
|
|
elsif ($SYSLOG_href->{'epoch'}) { |
678
|
0
|
|
|
|
|
|
log_debug(3, "examine message timestamp epoch: %s\n", _commify($SYSLOG_href->{'epoch'})); |
679
|
0
|
|
|
|
|
|
log_debug(3, "check %s < %s\n", |
680
|
|
|
|
|
|
|
_commify($SYSLOG_href->{'epoch'}), _commify($_obj->{'filter_min_date_epoch'}) |
681
|
|
|
|
|
|
|
); |
682
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'epoch'} < $_obj->{'filter_min_date_epoch'}) { |
683
|
0
|
|
|
|
|
|
$ERROR = sprintf("FILTER: message date %s less than min filter date %s", |
684
|
|
|
|
|
|
|
$SYSLOG_href->{'date_str'}, $_obj->{'filter_min_date'} |
685
|
|
|
|
|
|
|
); |
686
|
0
|
|
|
|
|
|
log_debug(3, "NULL line: %s\n", $ERROR); |
687
|
0
|
|
|
|
|
|
$FILTER_count++; |
688
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
689
|
|
|
|
|
|
|
} |
690
|
0
|
|
|
|
|
|
log_debug(3, "keep line\n"); |
691
|
|
|
|
|
|
|
} |
692
|
|
|
|
|
|
|
else { |
693
|
0
|
|
|
|
|
|
$ERROR = sprintf("assert min date filter: no date from message"); |
694
|
0
|
|
|
|
|
|
log_debug(3, "%s\n", $ERROR); |
695
|
0
|
|
|
|
|
|
$FILTER_count++; |
696
|
0
|
|
|
|
|
|
$ERROR_count++; |
697
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
698
|
|
|
|
|
|
|
} |
699
|
|
|
|
|
|
|
} |
700
|
|
|
|
|
|
|
# check max date filter |
701
|
0
|
0
|
|
|
|
|
if ($_obj->{'filter_max_date_epoch'}) { |
702
|
0
|
|
|
|
|
|
log_debug(3, "INFO: MAX filter: max_date_epoch [%s]\n", |
703
|
|
|
|
|
|
|
_commify($_obj->{'filter_max_date_epoch'}), $_obj->{'filter_max_date'}, |
704
|
|
|
|
|
|
|
); |
705
|
0
|
0
|
0
|
|
|
|
if ($SYSLOG_href->{'rx_epoch'} && $_obj->{'rx_time'}) { |
|
|
0
|
|
|
|
|
|
706
|
0
|
|
|
|
|
|
log_debug(3, "rx_epoch and rx_time : true\n"); |
707
|
0
|
|
|
|
|
|
log_debug(3, "is %s < %s\n", _commify($SYSLOG_href->{'rx_epoch'}), |
708
|
|
|
|
|
|
|
_commify($_obj->{'filter_max_date_epoch'}) |
709
|
|
|
|
|
|
|
); |
710
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'rx_epoch'} > $_obj->{'filter_max_date_epoch'}) { |
711
|
0
|
|
|
|
|
|
$ERROR = sprintf("FILTER: rx date %s greater than than max filter date %s", |
712
|
|
|
|
|
|
|
$SYSLOG_href->{'rx_date_str'}, $_obj->{'filter_max_date'} |
713
|
|
|
|
|
|
|
); |
714
|
0
|
|
|
|
|
|
log_debug(3, "%s\n", $ERROR); |
715
|
0
|
|
|
|
|
|
$FILTER_count++; |
716
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
717
|
|
|
|
|
|
|
} |
718
|
|
|
|
|
|
|
} |
719
|
|
|
|
|
|
|
elsif ($SYSLOG_href->{'epoch'}) { |
720
|
0
|
|
|
|
|
|
log_debug(3, "examine message timestamp epoch: %s\n", _commify($SYSLOG_href->{'epoch'})); |
721
|
0
|
|
|
|
|
|
log_debug(3, "check %s < %s\n", |
722
|
|
|
|
|
|
|
_commify($SYSLOG_href->{'epoch'}), _commify($_obj->{'filter_max_date_epoch'}) |
723
|
|
|
|
|
|
|
); |
724
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'epoch'} > $_obj->{'filter_max_date_epoch'}) { |
725
|
0
|
|
|
|
|
|
$ERROR = sprintf("FILTER: message date %s greater than max filter date %s", |
726
|
|
|
|
|
|
|
$SYSLOG_href->{'date_str'}, $_obj->{'filter_max_date'} |
727
|
|
|
|
|
|
|
); |
728
|
0
|
|
|
|
|
|
log_debug(3, "NULL line: %s\n", $ERROR); |
729
|
0
|
|
|
|
|
|
$FILTER_count++; |
730
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
731
|
|
|
|
|
|
|
} |
732
|
0
|
|
|
|
|
|
log_debug(3, "keep line\n"); |
733
|
|
|
|
|
|
|
} |
734
|
|
|
|
|
|
|
else { |
735
|
0
|
|
|
|
|
|
$ERROR = sprintf("assert min date filter: no date from message"); |
736
|
0
|
|
|
|
|
|
log_debug(3, "%s\n", $ERROR); |
737
|
0
|
|
|
|
|
|
$FILTER_count++; |
738
|
0
|
|
|
|
|
|
$ERROR_count++; |
739
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
740
|
|
|
|
|
|
|
} |
741
|
|
|
|
|
|
|
} |
742
|
|
|
|
|
|
|
# check device filter |
743
|
0
|
0
|
|
|
|
|
if ($_obj->{'filter_device'}) { |
744
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'device'} !~ /$_obj->{'filter_device'}/) { |
745
|
0
|
|
|
|
|
|
$ERROR = sprintf("FILTER: device [%s] not match filter [%s]", |
746
|
|
|
|
|
|
|
$SYSLOG_href->{'device'}, $_obj->{'filter_device'} |
747
|
|
|
|
|
|
|
); |
748
|
0
|
|
|
|
|
|
$FILTER_count++; |
749
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
750
|
|
|
|
|
|
|
} |
751
|
|
|
|
|
|
|
} |
752
|
|
|
|
|
|
|
# check tag filter |
753
|
0
|
0
|
|
|
|
|
if ($_obj->{'filter_tag'}) { |
754
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'tag'} !~ /$_obj->{'filter_tag'}/) { |
755
|
0
|
|
|
|
|
|
$ERROR = sprintf("FILTER: tag [%s] not match filter [%s]", |
756
|
|
|
|
|
|
|
$SYSLOG_href->{'tag'}, $_obj->{'filter_tag'} |
757
|
|
|
|
|
|
|
); |
758
|
0
|
|
|
|
|
|
$FILTER_count++; |
759
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
760
|
|
|
|
|
|
|
} |
761
|
|
|
|
|
|
|
} |
762
|
|
|
|
|
|
|
# check message filter |
763
|
0
|
0
|
|
|
|
|
if ($_obj->{'filter_message'}) { |
764
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'message'} !~ /$_obj->{'filter_message'}/) { |
765
|
0
|
|
|
|
|
|
$ERROR = sprintf("FILTER: message not match filter [%s]", $_obj->{'filter_message'}); |
766
|
0
|
|
|
|
|
|
$FILTER_count++; |
767
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
768
|
|
|
|
|
|
|
} |
769
|
|
|
|
|
|
|
} |
770
|
|
|
|
|
|
|
} # end filtering |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
# |
773
|
|
|
|
|
|
|
# Dump and/or Report line |
774
|
|
|
|
|
|
|
# |
775
|
|
|
|
|
|
|
# if a 'last message line' |
776
|
0
|
0
|
0
|
|
|
|
if ($_obj->{'lastmsg'} && $SYSLOG_href->{'line'} =~ /last message repeated (\d+) time/) { |
777
|
0
|
|
|
|
|
|
$_last = $1; |
778
|
0
|
|
|
|
|
|
$SYSLOG_href = undef; |
779
|
0
|
|
|
|
|
|
%{$SYSLOG_href} = %LASTMSG; |
|
0
|
|
|
|
|
|
|
780
|
0
|
|
|
|
|
|
log_debug(2, "syslog line repeated: [%s] times\n", $_last); |
781
|
0
|
|
|
|
|
|
foreach (1..$_last) { |
782
|
0
|
|
|
|
|
|
log_debug(3, "syslog line repeat: [%s]\n", $_); |
783
|
0
|
0
|
|
|
|
|
if ($_obj->{'dump'}) |
|
0
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
{&dump_line_to_file($_obj, $SYSLOG_href->{'device'}, $SYSLOG_href->{'line'});} |
785
|
0
|
0
|
|
|
|
|
if ($_obj->{'report'}) |
|
0
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
{&syslog_stats;} |
787
|
|
|
|
|
|
|
} |
788
|
|
|
|
|
|
|
} |
789
|
|
|
|
|
|
|
else { |
790
|
|
|
|
|
|
|
# see if we want to dump file |
791
|
0
|
0
|
0
|
|
|
|
if ($_obj->{'dump'} && $SYSLOG_href->{'device'}) { |
792
|
0
|
|
|
|
|
|
($_ok, $ERROR) = &dump_line_to_file($_obj, $SYSLOG_href->{'device'}, $_line); |
793
|
0
|
0
|
|
|
|
|
unless ($_ok) |
|
0
|
0
|
|
|
|
|
|
794
|
|
|
|
|
|
|
{return(wantarray ? (undef, $ERROR) : undef);} |
795
|
|
|
|
|
|
|
} |
796
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
# see if we want a report |
798
|
0
|
0
|
|
|
|
|
if ($_obj->{'report'}) |
|
0
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
{&syslog_stats;} |
800
|
|
|
|
|
|
|
} |
801
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
# store this line for next iteration |
803
|
0
|
|
|
|
|
|
%LASTMSG = %{$SYSLOG_href}; |
|
0
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
|
805
|
0
|
0
|
|
|
|
|
{return(wantarray ? ($SYSLOG_href, $ERROR) : $SYSLOG_href);} |
|
0
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
} # end parse_syslog_line |
808
|
|
|
|
|
|
|
# |
809
|
|
|
|
|
|
|
#............................................................................. |
810
|
|
|
|
|
|
|
# |
811
|
|
|
|
|
|
|
# Function/method to parse portion of syslog line thought to contain |
812
|
|
|
|
|
|
|
# the syslog message |
813
|
|
|
|
|
|
|
# |
814
|
|
|
|
|
|
|
# Break syslog line into parts |
815
|
|
|
|
|
|
|
# timestamp device message |
816
|
|
|
|
|
|
|
# message = tag content |
817
|
|
|
|
|
|
|
# |
818
|
|
|
|
|
|
|
# $_[0] - syslog line or rfc 3164 portion |
819
|
|
|
|
|
|
|
# $_[1] - more time info |
820
|
|
|
|
|
|
|
# 0 - do not derive more time info |
821
|
|
|
|
|
|
|
# 1 - derive more time info |
822
|
|
|
|
|
|
|
# $_[2] - parse tag |
823
|
|
|
|
|
|
|
# 0 - do not try to parse tag info from messag |
824
|
|
|
|
|
|
|
# 1 - parse tag and content |
825
|
|
|
|
|
|
|
# $_[3] - undef | 1 |
826
|
|
|
|
|
|
|
# 1 set if called internally, populate hash |
827
|
|
|
|
|
|
|
# 0 returns has reference |
828
|
|
|
|
|
|
|
# |
829
|
|
|
|
|
|
|
# Return |
830
|
|
|
|
|
|
|
# (timestamp, host, message, $ERROR) : \%hash |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
sub parse_syslog_msg { |
834
|
|
|
|
|
|
|
|
835
|
0
|
|
|
0
|
1
|
|
my $_msg = shift; |
836
|
0
|
|
0
|
|
|
|
my $_moretime = shift || 0; |
837
|
0
|
|
0
|
|
|
|
my $_parsetag = shift || 0; |
838
|
0
|
|
0
|
|
|
|
my $_ret = shift || 0; |
839
|
|
|
|
|
|
|
|
840
|
0
|
|
|
|
|
|
my ($_ok, $_err, |
841
|
|
|
|
|
|
|
$_x1, $_x2, |
842
|
|
|
|
|
|
|
); |
843
|
|
|
|
|
|
|
|
844
|
0
|
|
|
|
|
|
log_debug(2, "func parse_syslog_msg:\n"); |
845
|
0
|
|
|
|
|
|
log_debug(3, "format: [%s] pattern: %s\n", $SYSLOG_href->{'format'}, $SYSLOG_pattern); |
846
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
# |
848
|
|
|
|
|
|
|
# Match Sylog pattern and extract parts for desired format |
849
|
|
|
|
|
|
|
# |
850
|
0
|
0
|
|
|
|
|
if ($_msg =~ /$SYSLOG_pattern/) { |
851
|
0
|
|
|
|
|
|
log_debug(1, "matched syslog_pattern\n"); |
852
|
|
|
|
|
|
|
# bsd format |
853
|
0
|
0
|
0
|
|
|
|
if ($SYSLOG_href->{'format'} eq 'bsd' or $SYSLOG_href->{'format'} eq 'self') { |
|
|
0
|
|
|
|
|
|
854
|
|
|
|
|
|
|
# timstamp anchors |
855
|
0
|
|
|
|
|
|
$SYSLOG_href->{'timestamp'} = $1; |
856
|
0
|
|
|
|
|
|
$SYSLOG_href->{'month_str'} = $2; |
857
|
0
|
|
|
|
|
|
$SYSLOG_href->{'day'} = $3; |
858
|
0
|
|
|
|
|
|
$SYSLOG_href->{'time_str'} = $4; |
859
|
|
|
|
|
|
|
# hostname |
860
|
0
|
|
|
|
|
|
$SYSLOG_href->{'device'} = $5; |
861
|
|
|
|
|
|
|
# Message |
862
|
0
|
|
|
|
|
|
$SYSLOG_href->{'message'} = $6; |
863
|
|
|
|
|
|
|
} |
864
|
|
|
|
|
|
|
# noHost format |
865
|
|
|
|
|
|
|
elsif ($SYSLOG_href->{'format'} eq 'noHost') { |
866
|
|
|
|
|
|
|
# timstamp anchors |
867
|
0
|
|
|
|
|
|
$SYSLOG_href->{'timestamp'} = $1; |
868
|
0
|
|
|
|
|
|
$SYSLOG_href->{'month_str'} = $2; |
869
|
0
|
|
|
|
|
|
$SYSLOG_href->{'day'} = $3; |
870
|
0
|
|
|
|
|
|
$SYSLOG_href->{'time_str'} = $4; |
871
|
|
|
|
|
|
|
# Message |
872
|
0
|
|
|
|
|
|
$SYSLOG_href->{'message'} = $5; |
873
|
|
|
|
|
|
|
} |
874
|
|
|
|
|
|
|
else { |
875
|
0
|
|
|
|
|
|
$ERROR = "unmatched syslog_pattern: $SYSLOG_href->{'format'}"; |
876
|
0
|
|
|
|
|
|
log_debug(1, "%s\n", $ERROR); |
877
|
0
|
0
|
|
|
|
|
if ($_ret) {return(undef);} |
|
0
|
|
|
|
|
|
|
878
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, undef, undef, $ERROR) : undef); |
879
|
|
|
|
|
|
|
} |
880
|
|
|
|
|
|
|
} |
881
|
|
|
|
|
|
|
else { |
882
|
0
|
|
|
|
|
|
$ERROR = 'syslog message line does not match syslog_pattern'; |
883
|
0
|
|
|
|
|
|
log_debug(1, " %s\n", $ERROR); |
884
|
0
|
0
|
|
|
|
|
if ($_ret) {return(undef);} |
|
0
|
|
|
|
|
|
|
885
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, undef, undef, $ERROR) : undef); |
886
|
|
|
|
|
|
|
} |
887
|
0
|
0
|
|
|
|
|
if ($DEBUG) { |
888
|
0
|
|
|
|
|
|
log_debug(1, "timestamp: [%s]\n", $SYSLOG_href->{'timestamp'}); |
889
|
0
|
|
|
|
|
|
log_debug(1, "device: [%s]\n", $SYSLOG_href->{'device'}); |
890
|
0
|
|
|
|
|
|
log_debug(1, "message: [%s]\n", $SYSLOG_href->{'message'}); |
891
|
|
|
|
|
|
|
} |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
# |
894
|
|
|
|
|
|
|
# see if device has been substituted with ip:port info [a.a.a.a.p.p] |
895
|
|
|
|
|
|
|
# such as 10.1.1.1.4.0 |
896
|
|
|
|
|
|
|
# convert last two octets to srcPort |
897
|
|
|
|
|
|
|
# convert decimal octet to hex, join together, convert hex to decimal |
898
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'device'} =~ /(\d+\.\d+\.\d+\.\d+)\.(\d+)\.(\d+)/) { |
899
|
0
|
|
|
|
|
|
$SYSLOG_href->{'device'} = $1; |
900
|
0
|
|
|
|
|
|
$SYSLOG_href->{'device_port'} = hex( join('', sprintf("%02x", $2), sprintf("%02x", $3))); |
901
|
|
|
|
|
|
|
} |
902
|
|
|
|
|
|
|
else { |
903
|
0
|
|
|
|
|
|
$SYSLOG_href->{'device_port'} = '?'; |
904
|
|
|
|
|
|
|
} |
905
|
|
|
|
|
|
|
|
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
# |
908
|
|
|
|
|
|
|
# Get more info from timestamp |
909
|
|
|
|
|
|
|
# |
910
|
0
|
0
|
|
|
|
|
if ($_moretime) { |
911
|
0
|
0
|
|
|
|
|
if ( defined($SYSLOG_href->{'timestamp'}) ) { |
912
|
|
|
|
|
|
|
# Mmm d hh:mm:ss mmm d hh:mm:ss |
913
|
|
|
|
|
|
|
# Mmm dd hh:mm:ss mmm dd hh:mm:ss |
914
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'timestamp'} =~ /[JFMASOND]\w\w\s+\d+\s(\d\d):(\d\d):(\d\d)/i) { |
915
|
0
|
|
|
|
|
|
$SYSLOG_href->{'hour'} = $1; |
916
|
0
|
|
|
|
|
|
$SYSLOG_href->{'min'} = $2; |
917
|
0
|
|
|
|
|
|
$SYSLOG_href->{'sec'} = $3; |
918
|
|
|
|
|
|
|
|
919
|
0
|
|
|
|
|
|
$SYSLOG_href->{'month'} = $MON_index{$SYSLOG_href->{'month_str'}}; |
920
|
0
|
|
|
|
|
|
$SYSLOG_href->{'year'} = $YEAR; |
921
|
0
|
|
|
|
|
|
log_debug(2, |
922
|
|
|
|
|
|
|
"syslog message timestamp values: Mmm: [%s] [%s] dd: [%s] hh: [%s] mm: [%s] ss: [%s]\n", |
923
|
|
|
|
|
|
|
$SYSLOG_href->{'month_str'}, $SYSLOG_href->{'month'}, |
924
|
|
|
|
|
|
|
$SYSLOG_href->{'day'}, $SYSLOG_href->{'hour'}, |
925
|
|
|
|
|
|
|
$SYSLOG_href->{'min'}, $SYSLOG_href->{'sec'} |
926
|
|
|
|
|
|
|
); |
927
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
# determine some time info |
929
|
|
|
|
|
|
|
# year, epoch seconds, weekday |
930
|
|
|
|
|
|
|
# |
931
|
0
|
|
|
|
|
|
($SYSLOG_href->{'epoch'}, $SYSLOG_href->{'wday'}) = &_extra_time_values( |
932
|
|
|
|
|
|
|
$SYSLOG_href->{'sec'}, $SYSLOG_href->{'min'}, $SYSLOG_href->{'hour'}, |
933
|
|
|
|
|
|
|
$SYSLOG_href->{'day'}, $SYSLOG_href->{'month'}, |
934
|
|
|
|
|
|
|
); |
935
|
0
|
|
|
|
|
|
$SYSLOG_href->{'wday_str'} = $WDAY{$SYSLOG_href->{'wday'}}; |
936
|
0
|
|
|
|
|
|
$SYSLOG_href->{'date_str'} = &epoch_to_datestr($SYSLOG_href->{'epoch'}); |
937
|
|
|
|
|
|
|
|
938
|
0
|
|
|
|
|
|
log_debug(2, "syslog message timestamp extra: yyyy: [%s] epoch: [%s] wday: [%s] [%s]\n", |
939
|
|
|
|
|
|
|
$SYSLOG_href->{'year'}, $SYSLOG_href->{'epoch'}, $SYSLOG_href->{'wday'}, |
940
|
|
|
|
|
|
|
$SYSLOG_href->{'wday_str'} |
941
|
|
|
|
|
|
|
); |
942
|
|
|
|
|
|
|
} |
943
|
|
|
|
|
|
|
} |
944
|
|
|
|
|
|
|
else { |
945
|
0
|
|
|
|
|
|
$ERROR = "unsupported timestamp syntax: $SYSLOG_href->{'timestamp'}"; |
946
|
0
|
|
|
|
|
|
log_debug(1, "%s\n", $ERROR); |
947
|
0
|
0
|
|
|
|
|
if ($_ret) {return(undef);} |
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
948
|
|
|
|
|
|
|
else {return(wantarray ? (undef, undef, undef, $ERROR) : undef) } |
949
|
|
|
|
|
|
|
} |
950
|
|
|
|
|
|
|
} |
951
|
|
|
|
|
|
|
|
952
|
|
|
|
|
|
|
# |
953
|
|
|
|
|
|
|
# Check if we got a TAG, if try to find one |
954
|
|
|
|
|
|
|
# |
955
|
0
|
0
|
|
|
|
|
if ($_parsetag) { |
956
|
0
|
0
|
|
|
|
|
if (defined($SYSLOG_href->{'message'})) { |
957
|
0
|
|
|
|
|
|
($SYSLOG_href->{'tag'}, $SYSLOG_href->{'pid'}, $SYSLOG_href->{'content'}) = |
958
|
|
|
|
|
|
|
parse_tag($SYSLOG_href->{'message'} |
959
|
|
|
|
|
|
|
); |
960
|
0
|
|
|
|
|
|
log_debug(2, "syslog message tag: [%s] pid: [%s]\n", |
961
|
|
|
|
|
|
|
$SYSLOG_href->{'tag'}, $SYSLOG_href->{'pid'} |
962
|
|
|
|
|
|
|
); |
963
|
0
|
|
|
|
|
|
log_debug(2, "syslog message content: %s\n", $SYSLOG_href->{'content'}); |
964
|
|
|
|
|
|
|
} |
965
|
|
|
|
|
|
|
else { |
966
|
0
|
|
|
|
|
|
log_debug(2, 'no message to parse tag from'); |
967
|
|
|
|
|
|
|
} |
968
|
|
|
|
|
|
|
} |
969
|
|
|
|
|
|
|
else { |
970
|
0
|
|
|
|
|
|
$SYSLOG_href->{'content'} = $SYSLOG_href->{'message'}; |
971
|
0
|
|
|
|
|
|
log_debug(2, "parseTag [$_parsetag], content = message\n"); |
972
|
|
|
|
|
|
|
} |
973
|
|
|
|
|
|
|
|
974
|
|
|
|
|
|
|
|
975
|
|
|
|
|
|
|
# return some values |
976
|
0
|
0
|
|
|
|
|
if ($_ret) {return(1);} |
|
0
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
else { |
978
|
0
|
0
|
|
|
|
|
return(wantarray ? ($SYSLOG_href->{'timestamp'}, |
979
|
|
|
|
|
|
|
$SYSLOG_href->{'device'}, |
980
|
|
|
|
|
|
|
$SYSLOG_href->{'message'}, |
981
|
|
|
|
|
|
|
undef, |
982
|
|
|
|
|
|
|
) |
983
|
|
|
|
|
|
|
: $SYSLOG_href |
984
|
|
|
|
|
|
|
); |
985
|
|
|
|
|
|
|
} |
986
|
|
|
|
|
|
|
} # end parse_syslog_msg |
987
|
|
|
|
|
|
|
# |
988
|
|
|
|
|
|
|
#............................................................................. |
989
|
|
|
|
|
|
|
# |
990
|
|
|
|
|
|
|
# function to parse preamble |
991
|
|
|
|
|
|
|
# yyyy-mm-dd hh:mm::ss facility.severity src_ip |
992
|
|
|
|
|
|
|
# mm-dd-yyyy hh:mm::ss facility.severity src_ip |
993
|
|
|
|
|
|
|
# |
994
|
|
|
|
|
|
|
# Arg |
995
|
|
|
|
|
|
|
# $_[0] preamble |
996
|
|
|
|
|
|
|
# |
997
|
|
|
|
|
|
|
# Return |
998
|
|
|
|
|
|
|
# (epoch, date, facility, severity, srcIP) |
999
|
|
|
|
|
|
|
# |
1000
|
|
|
|
|
|
|
sub parse_preamble { |
1001
|
|
|
|
|
|
|
|
1002
|
0
|
|
|
0
|
1
|
|
my @_tokens = (); |
1003
|
0
|
|
|
|
|
|
my ($_t, $_epoch, $_timestamp, $_date, $_time, |
1004
|
|
|
|
|
|
|
$_yr, $_mon, $_day, |
1005
|
|
|
|
|
|
|
$_hr, $_min, $_sec, |
1006
|
|
|
|
|
|
|
$_prio, $_fac, $_sev, $_srcIp |
1007
|
|
|
|
|
|
|
); |
1008
|
|
|
|
|
|
|
|
1009
|
0
|
0
|
|
|
|
|
if ($_[0] =~ /^<(\d+)>$/) { |
1010
|
0
|
|
|
|
|
|
$_prio = $1; |
1011
|
0
|
|
|
|
|
|
@_tokens= decode_PRI($_prio); |
1012
|
0
|
|
|
|
|
|
$_prio = $_tokens[3]; |
1013
|
0
|
|
|
|
|
|
$_fac = $_tokens[4]; |
1014
|
0
|
|
|
|
|
|
$_sev = $_tokens[5]; |
1015
|
|
|
|
|
|
|
} |
1016
|
|
|
|
|
|
|
else { |
1017
|
0
|
|
|
|
|
|
@_tokens = split(/\s+/, $_[0]); |
1018
|
0
|
|
|
|
|
|
foreach $_t (@_tokens) { |
1019
|
|
|
|
|
|
|
# yyyy-mm-dd |
1020
|
0
|
0
|
|
|
|
|
if ($_t =~ /(\d\d\d\d)\-(\d\d)\-(\d\d)/) { |
1021
|
0
|
|
|
|
|
|
$_yr = $1; $_mon = $2; $_day = $3; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1022
|
0
|
|
|
|
|
|
$_date = $_t; |
1023
|
|
|
|
|
|
|
} |
1024
|
|
|
|
|
|
|
# mm-dd-yyyy |
1025
|
0
|
0
|
|
|
|
|
if ($_t =~ /(\d\d)\-(\d\d)\-(\d\d\d\d)/) { |
1026
|
0
|
|
|
|
|
|
$_mon = $1; $_day = $2; $_yr = $3; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1027
|
0
|
|
|
|
|
|
$_date = $_t; |
1028
|
|
|
|
|
|
|
} |
1029
|
|
|
|
|
|
|
# hh:mm::ss |
1030
|
0
|
0
|
|
|
|
|
if ($_t =~ /(\d\d):(\d\d):(\d\d)/) { |
1031
|
0
|
|
|
|
|
|
$_hr = $1; $_min = $2; $_sec = $3; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1032
|
0
|
|
|
|
|
|
$_time = $_t; |
1033
|
|
|
|
|
|
|
} |
1034
|
|
|
|
|
|
|
# facility.severity |
1035
|
0
|
0
|
|
|
|
|
if ($_t =~ /([a-zA-Z0-9]+)\.([a-zA-Z]+)/) |
|
0
|
|
|
|
|
|
|
1036
|
0
|
|
|
|
|
|
{$_fac = $1; $_sev = $2; $_prio = $_t;} |
|
0
|
|
|
|
|
|
|
1037
|
|
|
|
|
|
|
# source IP |
1038
|
0
|
0
|
|
|
|
|
if ($_t =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/) |
|
0
|
|
|
|
|
|
|
1039
|
|
|
|
|
|
|
{$_srcIp = $1;} |
1040
|
|
|
|
|
|
|
} |
1041
|
0
|
|
|
|
|
|
$_timestamp = sprintf("%s %s", $_date, $_time); |
1042
|
0
|
|
|
|
|
|
$_timestamp =~ s/^\s+//; |
1043
|
0
|
|
|
|
|
|
$_timestamp =~ s/\s+$//; |
1044
|
|
|
|
|
|
|
|
1045
|
0
|
0
|
0
|
|
|
|
if (defined($_hr) && defined($_day) ) { |
1046
|
0
|
|
|
|
|
|
$_epoch = timelocal($_sec, $_min, $_hr, $_day, $_mon-1, $_yr); |
1047
|
|
|
|
|
|
|
} |
1048
|
|
|
|
|
|
|
else { |
1049
|
0
|
|
|
|
|
|
$_epoch = '??'; |
1050
|
|
|
|
|
|
|
} |
1051
|
|
|
|
|
|
|
} |
1052
|
|
|
|
|
|
|
|
1053
|
0
|
|
|
|
|
|
$SYSLOG_href->{'preamble'} = $_[0]; |
1054
|
|
|
|
|
|
|
|
1055
|
0
|
0
|
|
|
|
|
if ($_prio) { |
1056
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_priority'} = $_prio; |
1057
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_facility'} = $_fac; |
1058
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_severity'} = $_sev; |
1059
|
|
|
|
|
|
|
} |
1060
|
|
|
|
|
|
|
|
1061
|
0
|
0
|
|
|
|
|
if ($_timestamp) { |
1062
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_timestamp'} = $_timestamp; |
1063
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_epoch'} = $_epoch; |
1064
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_date_str'} = epoch_to_datestr($SYSLOG_href->{'rx_epoch'}); |
1065
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_year'} = $_yr; |
1066
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_month'} = $_mon-1; |
1067
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_month_str'} = $MON{$_mon-1}; |
1068
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_day'} = $_day; |
1069
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_wday'} = (localtime($SYSLOG_href->{'rx_epoch'}))[6]; |
1070
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_wday_str'} = $WDAY{$SYSLOG_href->{'rx_wday'}}; |
1071
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_time_str'} = $_time; |
1072
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_hour'} = $_hr; |
1073
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_min'} = $_min; |
1074
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_sec'} = $_sec; |
1075
|
|
|
|
|
|
|
} |
1076
|
|
|
|
|
|
|
|
1077
|
0
|
0
|
|
|
|
|
if ($_srcIp) { |
1078
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_srcIP'} = $_srcIp; |
1079
|
|
|
|
|
|
|
} |
1080
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
# normalize facility and severity strings |
1082
|
0
|
0
|
|
|
|
|
if (!defined($Syslog_Facility{$SYSLOG_href->{'rx_facility'}})) { |
1083
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_facility'} = normalize_facility($SYSLOG_href->{'rx_facility'}); |
1084
|
0
|
|
|
|
|
|
log_debug(3, "normalized facility string to [%s]\n",$SYSLOG_href->{'rx_facility'}); |
1085
|
|
|
|
|
|
|
} |
1086
|
0
|
0
|
|
|
|
|
if (!defined($Syslog_Severity{$SYSLOG_href->{'rx_severity'}})) { |
1087
|
0
|
|
|
|
|
|
$SYSLOG_href->{'rx_severity'} = normalize_severity($SYSLOG_href->{'rx_severity'}); |
1088
|
0
|
|
|
|
|
|
log_debug(3, "normalized severity string to [%s]\n", $SYSLOG_href->{'rx_severity'}); |
1089
|
|
|
|
|
|
|
} |
1090
|
|
|
|
|
|
|
|
1091
|
|
|
|
|
|
|
|
1092
|
0
|
0
|
|
|
|
|
if ($DEBUG) { |
1093
|
0
|
|
|
|
|
|
log_debug(2, "syslog line preamble: timestamp: [%s] priority: [%s] srcIP: [%s]\n", |
1094
|
|
|
|
|
|
|
$SYSLOG_href->{'rx_timestamp'}, $SYSLOG_href->{'rx_priority'}, |
1095
|
|
|
|
|
|
|
$SYSLOG_href->{'rx_srcIP'} |
1096
|
|
|
|
|
|
|
); |
1097
|
0
|
|
|
|
|
|
log_debug(3, "syslog line preamble: epoch: [%s] facility: [%s] severity: [%s]\n", |
1098
|
|
|
|
|
|
|
$SYSLOG_href->{'rx_epoch'}, $SYSLOG_href->{'rx_facility'}, $SYSLOG_href->{'rx_severity'} |
1099
|
|
|
|
|
|
|
); |
1100
|
0
|
|
|
|
|
|
log_debug(3, "syslog line preamble: datestr: [%s]\n", |
1101
|
|
|
|
|
|
|
$SYSLOG_href->{'rx_date_str'} |
1102
|
|
|
|
|
|
|
); |
1103
|
|
|
|
|
|
|
} |
1104
|
|
|
|
|
|
|
|
1105
|
0
|
|
|
|
|
|
1; |
1106
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
} # parse_preamble |
1108
|
|
|
|
|
|
|
|
1109
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
# |
1111
|
|
|
|
|
|
|
#............................................................................. |
1112
|
|
|
|
|
|
|
# |
1113
|
|
|
|
|
|
|
# function to parse tag/pid |
1114
|
|
|
|
|
|
|
# Argument |
1115
|
|
|
|
|
|
|
# $_[0] string to find tag in |
1116
|
|
|
|
|
|
|
# Return |
1117
|
|
|
|
|
|
|
# (tag,pid) |
1118
|
|
|
|
|
|
|
# |
1119
|
|
|
|
|
|
|
sub parse_tag { |
1120
|
|
|
|
|
|
|
|
1121
|
0
|
|
|
0
|
1
|
|
my $_tag = ''; |
1122
|
0
|
|
|
|
|
|
my $_pid = ''; |
1123
|
0
|
|
|
|
|
|
my $_content = ''; |
1124
|
0
|
|
|
|
|
|
my $_match = 0; |
1125
|
|
|
|
|
|
|
|
1126
|
0
|
|
|
|
|
|
log_debug(2, "parse tag from: [%s]\n", $_[0]); |
1127
|
|
|
|
|
|
|
|
1128
|
|
|
|
|
|
|
# |
1129
|
|
|
|
|
|
|
# see if match a user defined pattern |
1130
|
|
|
|
|
|
|
# |
1131
|
0
|
0
|
0
|
|
|
|
if ($TAG_1 || $TAG_2 || $TAG_3) { |
|
|
|
0
|
|
|
|
|
1132
|
0
|
0
|
|
|
|
|
log_debug(3, "tag match: user defined %s %s %s\n", |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
defined($TAG_1) ? 1 : '-', |
1134
|
|
|
|
|
|
|
defined($TAG_2) ? 2 : '-', |
1135
|
|
|
|
|
|
|
defined($TAG_3) ? 3 : '-', |
1136
|
|
|
|
|
|
|
); |
1137
|
0
|
0
|
0
|
|
|
|
if ($TAG_1 && $_[0] =~ /$TAG_1/) { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
1138
|
0
|
|
|
|
|
|
$_tag = $1; |
1139
|
0
|
|
|
|
|
|
$_pid = $2; |
1140
|
0
|
|
|
|
|
|
$_content = $3; |
1141
|
0
|
|
|
|
|
|
log_debug(3, "tag match: TAG_1 tag: [%s] pid: [%s]\n", |
1142
|
|
|
|
|
|
|
$_tag, $_pid |
1143
|
|
|
|
|
|
|
); |
1144
|
|
|
|
|
|
|
} |
1145
|
|
|
|
|
|
|
elsif ($TAG_2 && $_[0] =~ /$TAG_2/) { |
1146
|
0
|
|
|
|
|
|
$_tag = $1; |
1147
|
0
|
|
|
|
|
|
$_pid = ''; |
1148
|
0
|
|
|
|
|
|
$_content = $2; |
1149
|
0
|
|
|
|
|
|
log_debug(3, "tag match: TAG_2 tag: [%s] pid: [%s]\n", |
1150
|
|
|
|
|
|
|
$_tag, $_pid |
1151
|
|
|
|
|
|
|
); |
1152
|
|
|
|
|
|
|
} |
1153
|
|
|
|
|
|
|
elsif ($TAG_3 && $_[0] =~ /$TAG_3/) { |
1154
|
0
|
|
|
|
|
|
$_tag = $1; |
1155
|
0
|
|
|
|
|
|
$_pid = $2; |
1156
|
0
|
|
|
|
|
|
$_content = $3; |
1157
|
0
|
|
|
|
|
|
log_debug(3, "tag match: TAG_3 tag: [%s] pid: [%s]\n", |
1158
|
|
|
|
|
|
|
$_tag, $_pid |
1159
|
|
|
|
|
|
|
); |
1160
|
|
|
|
|
|
|
} |
1161
|
|
|
|
|
|
|
else { |
1162
|
0
|
|
|
|
|
|
log_debug(3, "tag match: user defined not matched\n"); |
1163
|
|
|
|
|
|
|
} |
1164
|
|
|
|
|
|
|
#$_content =~ s/^ +//; |
1165
|
0
|
|
|
|
|
|
return($_tag, $_pid, $_content); |
1166
|
|
|
|
|
|
|
} |
1167
|
|
|
|
|
|
|
|
1168
|
|
|
|
|
|
|
# |
1169
|
|
|
|
|
|
|
# If we are this point, try to match some of these common ones |
1170
|
|
|
|
|
|
|
# |
1171
|
|
|
|
|
|
|
# |
1172
|
|
|
|
|
|
|
# tag[pid]: content pid delimited with [] |
1173
|
0
|
0
|
|
|
|
|
if ($_[0] =~ /^(([\w\d]+)\[([\w\d]+)\]:){1,32}? *(\w+.+)/) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1174
|
0
|
|
|
|
|
|
$_tag = $2; |
1175
|
0
|
|
|
|
|
|
$_pid = $3; |
1176
|
0
|
|
|
|
|
|
$_content = $4; |
1177
|
0
|
|
|
|
|
|
$_match = 1; |
1178
|
|
|
|
|
|
|
} |
1179
|
|
|
|
|
|
|
# |
1180
|
|
|
|
|
|
|
# tag[pid]: content pid delimited with non-alphnumeric |
1181
|
|
|
|
|
|
|
elsif ($_[0] =~ /^(([\w\d\-_]+)\W([\w\d]+)\W:){1,32}? *(\w+.+)/) { |
1182
|
0
|
|
|
|
|
|
$_tag = $2; |
1183
|
0
|
|
|
|
|
|
$_pid = $3; |
1184
|
0
|
|
|
|
|
|
$_content = $4; |
1185
|
0
|
|
|
|
|
|
$_match = 2; |
1186
|
|
|
|
|
|
|
} |
1187
|
|
|
|
|
|
|
# tag[pid] content pid delimited with non-alphnumeric no colon |
1188
|
|
|
|
|
|
|
elsif ($_[0] =~ /^(([\w\d\-_]+)\W([\w\d]+)\W){1,32}? *(\w+.+)/) { |
1189
|
0
|
|
|
|
|
|
$_tag = $2; |
1190
|
0
|
|
|
|
|
|
$_pid = $3; |
1191
|
0
|
|
|
|
|
|
$_content = $4; |
1192
|
0
|
|
|
|
|
|
$_match = 3; |
1193
|
|
|
|
|
|
|
} |
1194
|
|
|
|
|
|
|
elsif ($_[0] =~ /^(([\w\d\-_]+)\W([\w\d]+)\W){1,32}? *(.+)/) { |
1195
|
0
|
|
|
|
|
|
$_tag = $2; |
1196
|
0
|
|
|
|
|
|
$_pid = $3; |
1197
|
0
|
|
|
|
|
|
$_content = $4; |
1198
|
0
|
|
|
|
|
|
$_match = 4; |
1199
|
|
|
|
|
|
|
} |
1200
|
|
|
|
|
|
|
|
1201
|
|
|
|
|
|
|
# last message |
1202
|
|
|
|
|
|
|
elsif ($_[0] =~ /last message repeated (\d+) time/) { |
1203
|
0
|
|
|
|
|
|
$_tag = 'lastmsg'; |
1204
|
0
|
|
|
|
|
|
$_pid = $1; |
1205
|
0
|
|
|
|
|
|
$_content = ''; |
1206
|
0
|
|
|
|
|
|
$_match = 'last'; |
1207
|
|
|
|
|
|
|
} |
1208
|
|
|
|
|
|
|
else { |
1209
|
0
|
|
|
|
|
|
$_tag = 'NOTAG'; |
1210
|
0
|
|
|
|
|
|
$_pid = 'NOPID'; |
1211
|
0
|
|
|
|
|
|
$_content = $_[0]; |
1212
|
0
|
|
|
|
|
|
log_debug(3, "tag match: none, set content = message\n"); |
1213
|
|
|
|
|
|
|
} |
1214
|
|
|
|
|
|
|
|
1215
|
0
|
|
|
|
|
|
log_debug(3, "tag match: pattern [%s] tag: [%s] pid: [%s]\n", |
1216
|
|
|
|
|
|
|
$_match, $_tag, $_pid |
1217
|
|
|
|
|
|
|
); |
1218
|
|
|
|
|
|
|
#$_content =~ s/^ +//; |
1219
|
0
|
|
|
|
|
|
return($_tag, $_pid, $_content); |
1220
|
|
|
|
|
|
|
} |
1221
|
|
|
|
|
|
|
|
1222
|
|
|
|
|
|
|
|
1223
|
|
|
|
|
|
|
# |
1224
|
|
|
|
|
|
|
#............................................................................. |
1225
|
|
|
|
|
|
|
# |
1226
|
|
|
|
|
|
|
# Init the object |
1227
|
|
|
|
|
|
|
sub init { |
1228
|
|
|
|
|
|
|
#$SYSLOG_href = {}; |
1229
|
0
|
|
|
0
|
1
|
|
%{$SYSLOG_href} = (); |
|
0
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
} |
1231
|
|
|
|
|
|
|
# |
1232
|
|
|
|
|
|
|
#======================================================================= |
1233
|
|
|
|
|
|
|
# |
1234
|
|
|
|
|
|
|
# Syslog Send Message |
1235
|
|
|
|
|
|
|
# |
1236
|
|
|
|
|
|
|
#======================================================================= |
1237
|
|
|
|
|
|
|
# |
1238
|
|
|
|
|
|
|
# |
1239
|
|
|
|
|
|
|
#........................................................................ |
1240
|
|
|
|
|
|
|
# |
1241
|
|
|
|
|
|
|
# Syslog Send message constructor |
1242
|
|
|
|
|
|
|
# |
1243
|
|
|
|
|
|
|
# Args |
1244
|
|
|
|
|
|
|
# server => |
1245
|
|
|
|
|
|
|
# port => (514) |
1246
|
|
|
|
|
|
|
# facility => |
1247
|
|
|
|
|
|
|
# severity => |
1248
|
|
|
|
|
|
|
# tag => |
1249
|
|
|
|
|
|
|
# timestamp => # timestamp value to use in syslog message |
1250
|
|
|
|
|
|
|
# device => # device name to use in syslog message |
1251
|
|
|
|
|
|
|
# tag => # tag string to use in syslog message |
1252
|
|
|
|
|
|
|
# pid => # pid to append to tag enclosed in [] |
1253
|
|
|
|
|
|
|
# message => # message to send |
1254
|
|
|
|
|
|
|
# content => # content of message |
1255
|
|
|
|
|
|
|
# strict => 0|1 # enforce message syntax rules |
1256
|
|
|
|
|
|
|
# noHost => 0|1 # whether we should put HOSTNAME in message |
1257
|
|
|
|
|
|
|
# noTag => 0|1 # hether we should put TAG in message |
1258
|
|
|
|
|
|
|
# debug => 0-5 # debug |
1259
|
|
|
|
|
|
|
|
1260
|
|
|
|
|
|
|
sub send { |
1261
|
|
|
|
|
|
|
|
1262
|
|
|
|
|
|
|
# create object |
1263
|
0
|
|
|
0
|
1
|
|
my $_proto = shift; |
1264
|
0
|
|
0
|
|
|
|
my $_class = ref($_proto) || $_proto; |
1265
|
0
|
|
|
|
|
|
my $_send = {}; |
1266
|
|
|
|
|
|
|
# bless object |
1267
|
0
|
|
|
|
|
|
bless($_send, $_class); |
1268
|
|
|
|
|
|
|
|
1269
|
0
|
|
|
|
|
|
$ERROR = ''; |
1270
|
|
|
|
|
|
|
|
1271
|
0
|
|
|
|
|
|
my %_arg = @_; |
1272
|
0
|
|
|
|
|
|
my $_a; |
1273
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
# default some values |
1275
|
0
|
|
|
|
|
|
$_send->{'server'} = '127.0.0.1'; |
1276
|
0
|
|
|
|
|
|
$_send->{'port'} = '514'; |
1277
|
0
|
|
|
|
|
|
$_send->{'proto'} = 'udp'; |
1278
|
0
|
|
|
|
|
|
$_send->{'facility'} = 'user'; |
1279
|
0
|
|
|
|
|
|
$_send->{'severity'} = 'debug'; |
1280
|
0
|
|
|
|
|
|
$_send->{'strict'} = 1; |
1281
|
0
|
|
|
|
|
|
$_send->{'noHost'} = 0; |
1282
|
0
|
|
|
|
|
|
$_send->{'noTag'} = 0; |
1283
|
0
|
|
|
|
|
|
$_send->{'debug'} = 0; |
1284
|
|
|
|
|
|
|
|
1285
|
|
|
|
|
|
|
# check arguments |
1286
|
0
|
|
|
|
|
|
foreach $_a (keys %_arg) { |
1287
|
0
|
0
|
|
|
|
|
if ($_a =~ /^-?server/) { $_send->{'server'} = delete($_arg{$_a}); } |
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1288
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?port/) { $_send->{'port'} = delete($_arg{$_a}); } |
1289
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?proto/) { $_send->{'proto'} = delete($_arg{$_a}); } |
1290
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?facility/) { $_send->{'facility'} = delete($_arg{$_a}); } |
1291
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?severity/) { $_send->{'severity'} = delete($_arg{$_a}); } |
1292
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?timestamp/) { $_send->{'timestamp'} = delete($_arg{$_a}); } |
1293
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?device/) { $_send->{'device'} = delete($_arg{$_a}); } |
1294
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?tag/) { $_send->{'tag'} = delete($_arg{$_a}); } |
1295
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?pid/) { $_send->{'pid'} = delete($_arg{$_a}); } |
1296
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?content/) { $_send->{'content'} = delete($_arg{$_a}); } |
1297
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?message/) { $_send->{'message'} = delete($_arg{$_a}); } |
1298
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?strict/) { $_send->{'strict'} = delete($_arg{$_a}); } |
1299
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?noHost/) { $_send->{'noHost'} = delete($_arg{$_a}); } |
1300
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?hostname/) { $_send->{'hostname'} = delete($_arg{$_a}); } |
1301
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?noTag/) { $_send->{'noTag'} = delete($_arg{$_a}); } |
1302
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?debug/) { $_send->{'debug'} = delete($_arg{$_a}); } |
1303
|
|
|
|
|
|
|
else { |
1304
|
0
|
|
|
|
|
|
$ERROR = sprintf("unsupported argument: %s => %s", $_a, $_arg{$_a}); |
1305
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1306
|
|
|
|
|
|
|
} |
1307
|
|
|
|
|
|
|
} |
1308
|
0
|
0
|
|
|
|
|
return(wantarray ? ($_send, $ERROR) : $_send); |
1309
|
|
|
|
|
|
|
} |
1310
|
|
|
|
|
|
|
|
1311
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
# |
1313
|
|
|
|
|
|
|
#............................................................................. |
1314
|
|
|
|
|
|
|
# |
1315
|
|
|
|
|
|
|
# send message |
1316
|
|
|
|
|
|
|
# max length = 1024 |
1317
|
|
|
|
|
|
|
# PRI HEADER MSG |
1318
|
|
|
|
|
|
|
# PRI 3,4 or 5 char bounded by '<' '>' |
1319
|
|
|
|
|
|
|
# <#> |
1320
|
|
|
|
|
|
|
# |
1321
|
|
|
|
|
|
|
sub send_message { |
1322
|
|
|
|
|
|
|
|
1323
|
0
|
|
|
0
|
1
|
|
my $_send = shift; |
1324
|
0
|
|
|
|
|
|
my ($_facility, $_severity, |
1325
|
|
|
|
|
|
|
$_timestamp, $_devname, $_tag, $_pid, $_message, |
1326
|
|
|
|
|
|
|
$_pri, $_content, $tx_msg, $msg_l, $tag_l, |
1327
|
|
|
|
|
|
|
$_sock, |
1328
|
|
|
|
|
|
|
); |
1329
|
|
|
|
|
|
|
|
1330
|
0
|
|
|
|
|
|
$ERROR = ''; |
1331
|
|
|
|
|
|
|
|
1332
|
0
|
|
|
|
|
|
my %_arg = @_; |
1333
|
0
|
|
|
|
|
|
my $_a; |
1334
|
0
|
|
|
|
|
|
my $_format = ''; |
1335
|
|
|
|
|
|
|
|
1336
|
|
|
|
|
|
|
# check arguments |
1337
|
0
|
|
|
|
|
|
foreach $_a (keys %_arg) { |
1338
|
0
|
0
|
|
|
|
|
if ($_a =~ /^-?server/) { $_send->{'server'} = delete($_arg{$_a}); } |
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1339
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?port/) { $_send->{'port'} = delete($_arg{$_a}); } |
1340
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?facility/) { $_send->{'facility'} = delete($_arg{$_a}); } |
1341
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?severity/) { $_send->{'severity'} = delete($_arg{$_a}); } |
1342
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?timestamp/) { $_send->{'timestamp'} = delete($_arg{$_a}); } |
1343
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?device/) { $_send->{'device'} = delete($_arg{$_a}); } |
1344
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?tag/) { $_send->{'tag'} = delete($_arg{$_a}); } |
1345
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?pid/) { $_send->{'pid'} = delete($_arg{$_a}); } |
1346
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?content/) { $_send->{'content'} = delete($_arg{$_a}); } |
1347
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?message/) { $_send->{'message'} = delete($_arg{$_a}); } |
1348
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?strict/) { $_send->{'strict'} = delete($_arg{$_a}); } |
1349
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?noHost/) { $_send->{'noHost'} = delete($_arg{$_a}); } |
1350
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?hostname/) { $_send->{'hostname'} = delete($_arg{$_a}); } |
1351
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?noTag/) { $_send->{'noTag'} = delete($_arg{$_a}); } |
1352
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?debug/) { $_send->{'debug'} = delete($_arg{$_a}); } |
1353
|
|
|
|
|
|
|
else { |
1354
|
0
|
|
|
|
|
|
$ERROR = sprintf("unsupported argument: %s => %s", $_a, $_arg{$_a}); |
1355
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1356
|
|
|
|
|
|
|
} |
1357
|
|
|
|
|
|
|
} |
1358
|
|
|
|
|
|
|
|
1359
|
|
|
|
|
|
|
# error check facility and severity value |
1360
|
0
|
0
|
|
|
|
|
if (!defined($Syslog_Facility{$_send->{'facility'}})) { |
1361
|
0
|
|
|
|
|
|
$ERROR = "unsupported argument: facility => $_send->{'facility'}"; |
1362
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1363
|
|
|
|
|
|
|
} |
1364
|
0
|
0
|
|
|
|
|
if (!defined($Syslog_Severity{$_send->{'severity'}})) { |
1365
|
0
|
|
|
|
|
|
$ERROR = "unsupported argument: severity => $_send->{'severity'}"; |
1366
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1367
|
|
|
|
|
|
|
} |
1368
|
|
|
|
|
|
|
|
1369
|
0
|
|
|
|
|
|
$_tag = undef; |
1370
|
0
|
|
|
|
|
|
$_message = ''; |
1371
|
|
|
|
|
|
|
|
1372
|
0
|
|
|
|
|
|
$DEBUG = $_send->{'debug'}; |
1373
|
|
|
|
|
|
|
|
1374
|
|
|
|
|
|
|
|
1375
|
0
|
|
|
|
|
|
$_facility = $Syslog_Facility{$_send->{'facility'}}; |
1376
|
0
|
|
|
|
|
|
$_severity = $Syslog_Severity{$_send->{'severity'}}; |
1377
|
|
|
|
|
|
|
# PRI = (facility x 8) + severity |
1378
|
0
|
|
|
|
|
|
$_pri = ($_facility * 8) + $_severity; |
1379
|
|
|
|
|
|
|
|
1380
|
|
|
|
|
|
|
# |
1381
|
|
|
|
|
|
|
# TIMESTAMP |
1382
|
|
|
|
|
|
|
# |
1383
|
|
|
|
|
|
|
# use timestamp given |
1384
|
0
|
0
|
|
|
|
|
if ($_send->{'timestamp'}) { |
1385
|
0
|
0
|
|
|
|
|
if (!validate_timestamp_syntax($_send->{'timestamp'})) { |
1386
|
0
|
|
|
|
|
|
$ERROR = "invalid timestamp: $_send->{'timestamp'}"; |
1387
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1388
|
|
|
|
|
|
|
} |
1389
|
0
|
|
|
|
|
|
$_timestamp = $_send->{'timestamp'}; |
1390
|
|
|
|
|
|
|
} |
1391
|
|
|
|
|
|
|
# use system time |
1392
|
|
|
|
|
|
|
else { |
1393
|
0
|
|
|
|
|
|
$_timestamp = epoch_to_syslog_timestamp(); |
1394
|
|
|
|
|
|
|
} |
1395
|
0
|
|
|
|
|
|
$_format = 'T'; |
1396
|
|
|
|
|
|
|
# |
1397
|
|
|
|
|
|
|
# HOSTNAME (not required) |
1398
|
|
|
|
|
|
|
# if noHost=0 meaning populate hostname |
1399
|
0
|
0
|
|
|
|
|
unless ( $_send->{'noHost'} ) { |
1400
|
0
|
0
|
|
|
|
|
if ($_send->{'device'}) { $_devname = $_send->{'device'}; } |
|
0
|
0
|
|
|
|
|
|
1401
|
0
|
|
|
|
|
|
elsif ($_send->{'hostname'}) { $_devname = hostname();} |
1402
|
0
|
|
|
|
|
|
else { $_devname = 'netdevsyslog';} |
1403
|
0
|
|
|
|
|
|
$_format = 'TH'; |
1404
|
|
|
|
|
|
|
} |
1405
|
|
|
|
|
|
|
# |
1406
|
|
|
|
|
|
|
# MESSAGE or (TAG CONTENT) |
1407
|
|
|
|
|
|
|
# |
1408
|
0
|
0
|
|
|
|
|
if ( defined($_send->{'message'}) ) { |
|
|
0
|
|
|
|
|
|
1409
|
0
|
|
|
|
|
|
$_content = $_send->{'message'}; |
1410
|
0
|
|
|
|
|
|
$_format = $_format . 'M'; |
1411
|
|
|
|
|
|
|
} |
1412
|
|
|
|
|
|
|
elsif ( defined($_send->{'content'}) ) { |
1413
|
|
|
|
|
|
|
# -noTag = 0 |
1414
|
0
|
0
|
|
|
|
|
unless ($_send->{'noTag'}) { |
1415
|
0
|
0
|
0
|
|
|
|
if ( defined($_send->{'tag'}) && $_send->{'pid'} ) { |
|
|
0
|
|
|
|
|
|
1416
|
0
|
|
|
|
|
|
$_tag = sprintf("%s[%s]:", $_send->{'tag'}, $_send->{'pid'}); |
1417
|
|
|
|
|
|
|
} |
1418
|
|
|
|
|
|
|
elsif ( defined($_send->{'tag'}) ) { |
1419
|
0
|
|
|
|
|
|
$_tag = $_send->{'tag'}; |
1420
|
|
|
|
|
|
|
} |
1421
|
|
|
|
|
|
|
else { |
1422
|
0
|
0
|
|
|
|
|
if ( defined($_send->{'pid'}) ) {$_tag = sprintf("NetDevSyslog[%s]:", $_send->{'pid'});} |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1423
|
|
|
|
|
|
|
else {$_tag = sprintf("NetDevSyslogp[%s]:", $$);} |
1424
|
|
|
|
|
|
|
} |
1425
|
0
|
|
|
|
|
|
$_format = $_format . 'T'; # THT or TT |
1426
|
|
|
|
|
|
|
} |
1427
|
0
|
|
|
|
|
|
$_content = $_send->{'content'}; |
1428
|
0
|
|
|
|
|
|
$_format = $_format . 'C'; |
1429
|
|
|
|
|
|
|
} |
1430
|
|
|
|
|
|
|
else { |
1431
|
0
|
|
|
|
|
|
$_content = sprintf("Net::Dev::Syslog TEST Message: facility: %s [%s] severity: %s [%s]", |
1432
|
|
|
|
|
|
|
$_send->{'facility'}, $_facility, |
1433
|
|
|
|
|
|
|
$_send->{'severity'}, $_severity, |
1434
|
|
|
|
|
|
|
); |
1435
|
0
|
|
|
|
|
|
$_format = $_format . 'C'; |
1436
|
|
|
|
|
|
|
} |
1437
|
|
|
|
|
|
|
|
1438
|
|
|
|
|
|
|
# |
1439
|
|
|
|
|
|
|
# SYSLOG MESSAGE |
1440
|
|
|
|
|
|
|
# |
1441
|
|
|
|
|
|
|
# timestamp hostname tag content |
1442
|
0
|
0
|
|
|
|
|
if ( $_format eq "THTC") { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1443
|
0
|
|
|
|
|
|
$_message = sprintf("%s %s %s %s", $_timestamp, $_devname, $_tag, $_content); |
1444
|
|
|
|
|
|
|
} |
1445
|
|
|
|
|
|
|
# timestamp hostname content |
1446
|
|
|
|
|
|
|
elsif ( $_format eq "THC") { |
1447
|
0
|
|
|
|
|
|
$_message = sprintf("%s %s %s", $_timestamp, $_devname, $_content); |
1448
|
|
|
|
|
|
|
} |
1449
|
|
|
|
|
|
|
# timestamp tag content |
1450
|
|
|
|
|
|
|
elsif ( $_format eq "TTC") { |
1451
|
0
|
|
|
|
|
|
$_message = sprintf("%s %s %s", $_timestamp, $_tag, $_content); |
1452
|
|
|
|
|
|
|
} |
1453
|
|
|
|
|
|
|
# timestamp content |
1454
|
|
|
|
|
|
|
elsif ( $_format eq "TC") { |
1455
|
0
|
|
|
|
|
|
$_message = sprintf("%s %s", $_timestamp, $_content); |
1456
|
|
|
|
|
|
|
} |
1457
|
|
|
|
|
|
|
# timestamp hostname message |
1458
|
|
|
|
|
|
|
elsif ( $_format eq "THM") { |
1459
|
0
|
|
|
|
|
|
$_message = sprintf("%s %s %s", $_timestamp, $_devname, $_content); |
1460
|
|
|
|
|
|
|
} |
1461
|
|
|
|
|
|
|
# timestamp message |
1462
|
|
|
|
|
|
|
elsif ( $_format eq "TM") { |
1463
|
0
|
|
|
|
|
|
$_message = sprintf("%s %s", $_timestamp, $_content); |
1464
|
|
|
|
|
|
|
} |
1465
|
|
|
|
|
|
|
# ??? |
1466
|
|
|
|
|
|
|
else { |
1467
|
0
|
|
|
|
|
|
$ERROR = sprintf("unknown format: [%s] [%s] [%s] [%s]", |
1468
|
|
|
|
|
|
|
$_timestamp, $_devname, $_tag, $_content |
1469
|
|
|
|
|
|
|
); |
1470
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1471
|
|
|
|
|
|
|
} |
1472
|
|
|
|
|
|
|
|
1473
|
|
|
|
|
|
|
# |
1474
|
|
|
|
|
|
|
# MESSAGE to transmit |
1475
|
|
|
|
|
|
|
# |
1476
|
0
|
|
|
|
|
|
$tx_msg = sprintf("<%s>%s", $_pri, $_message); |
1477
|
0
|
|
|
|
|
|
$msg_l = length($tx_msg); |
1478
|
|
|
|
|
|
|
|
1479
|
|
|
|
|
|
|
# check allowed lengths |
1480
|
0
|
|
|
|
|
|
$msg_l = length($tx_msg); |
1481
|
0
|
0
|
|
|
|
|
if ($_tag =~ /(.+)\[/) |
|
0
|
|
|
|
|
|
|
1482
|
0
|
|
|
|
|
|
{$tag_l = length($1);} |
1483
|
|
|
|
|
|
|
else |
1484
|
|
|
|
|
|
|
{$tag_l = length($_tag);} |
1485
|
|
|
|
|
|
|
|
1486
|
0
|
0
|
|
|
|
|
if ($_send->{'strict'}) { |
1487
|
|
|
|
|
|
|
# syslog message length can not exceed 1024 |
1488
|
0
|
0
|
|
|
|
|
if ($msg_l > 1024) { |
1489
|
0
|
|
|
|
|
|
$ERROR = "syslog message length $msg_l greater than 1024"; |
1490
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1491
|
|
|
|
|
|
|
} |
1492
|
|
|
|
|
|
|
# syslog tag length can not exceed 32 |
1493
|
0
|
0
|
|
|
|
|
if ($tag_l > 32) { |
1494
|
0
|
|
|
|
|
|
$ERROR = "syslog message tag length $tag_l greater than 32"; |
1495
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1496
|
|
|
|
|
|
|
} |
1497
|
|
|
|
|
|
|
} |
1498
|
|
|
|
|
|
|
|
1499
|
0
|
0
|
|
|
|
|
if ($_send->{'debug'}){ |
1500
|
0
|
|
|
|
|
|
log_debug(1, "sendto: %s port %s proto %s\n", |
1501
|
|
|
|
|
|
|
$_send->{'server'}, $_send->{'port'}, $_send->{'proto'} |
1502
|
|
|
|
|
|
|
); |
1503
|
0
|
|
|
|
|
|
log_debug(2, "pri: %s facility: %s [%s] severity: %s [%s]\n", |
1504
|
|
|
|
|
|
|
$_pri, |
1505
|
|
|
|
|
|
|
$_send->{'facility'}, $_facility, |
1506
|
|
|
|
|
|
|
$_send->{'severity'}, $_severity, |
1507
|
|
|
|
|
|
|
); |
1508
|
0
|
|
|
|
|
|
log_debug(3, "format: %s\n", $_format); |
1509
|
0
|
|
0
|
|
|
|
log_debug(3, "timestamp: %s [%s]\n", $_send->{'timestamp'} || 'localtime', $_timestamp); |
1510
|
0
|
|
0
|
|
|
|
log_debug(3, "device: %s [%s]\n", $_send->{'device'} || 'none', $_devname); |
1511
|
0
|
|
0
|
|
|
|
log_debug(3, "tag: %s [%s] [%s]\n", $_tag || 'noTag', $_send->{'tag'}||'-', $_send->{'pid'}||'-'); |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
1512
|
0
|
|
|
|
|
|
log_debug(4, "content: %s\n", $_content); |
1513
|
0
|
|
|
|
|
|
log_debug(4, "message: %s\n", $_message); |
1514
|
0
|
|
|
|
|
|
log_debug(5, "tx msg: %s\n", $tx_msg); |
1515
|
|
|
|
|
|
|
} |
1516
|
|
|
|
|
|
|
|
1517
|
|
|
|
|
|
|
# send the message |
1518
|
0
|
|
|
|
|
|
$_sock = IO::Socket::INET->new( |
1519
|
|
|
|
|
|
|
PeerAddr => $_send->{'server'}, |
1520
|
|
|
|
|
|
|
PeerPort => $_send->{'port'}, |
1521
|
|
|
|
|
|
|
Proto => $_send->{'proto'} |
1522
|
|
|
|
|
|
|
); |
1523
|
0
|
0
|
|
|
|
|
unless ($_sock) { |
1524
|
0
|
|
|
|
|
|
$ERROR = sprintf("could not open socket to %s:%s [%s]", |
1525
|
|
|
|
|
|
|
$_send->{'server'}, $_send->{'port'}, $! |
1526
|
|
|
|
|
|
|
); |
1527
|
0
|
0
|
|
|
|
|
return( wantarray ? (undef, $ERROR) : undef) ; |
1528
|
|
|
|
|
|
|
} |
1529
|
0
|
|
|
|
|
|
print $_sock $tx_msg; |
1530
|
|
|
|
|
|
|
|
1531
|
0
|
|
|
|
|
|
$_sock->close(); |
1532
|
0
|
0
|
|
|
|
|
return(wantarray ? (1, '') : 1); |
1533
|
|
|
|
|
|
|
|
1534
|
|
|
|
|
|
|
} # end send_message |
1535
|
|
|
|
|
|
|
|
1536
|
|
|
|
|
|
|
# |
1537
|
|
|
|
|
|
|
#======================================================================= |
1538
|
|
|
|
|
|
|
# |
1539
|
|
|
|
|
|
|
# Syslog Receive Message |
1540
|
|
|
|
|
|
|
# |
1541
|
|
|
|
|
|
|
#======================================================================= |
1542
|
|
|
|
|
|
|
# |
1543
|
|
|
|
|
|
|
# |
1544
|
|
|
|
|
|
|
#........................................................................ |
1545
|
|
|
|
|
|
|
# |
1546
|
|
|
|
|
|
|
# Syslog Receive message constructor |
1547
|
|
|
|
|
|
|
# |
1548
|
|
|
|
|
|
|
# port => port to listen on (514) |
1549
|
|
|
|
|
|
|
# proto => protocol (udp) |
1550
|
|
|
|
|
|
|
# maxlength => max length of packet (1024) |
1551
|
|
|
|
|
|
|
# verbose => 0|1|2|3 verbose level (0) |
1552
|
|
|
|
|
|
|
# 0 - pure message |
1553
|
|
|
|
|
|
|
# 1 - bsd format |
1554
|
|
|
|
|
|
|
# 2 - bsd_plus format |
1555
|
|
|
|
|
|
|
# |
1556
|
|
|
|
|
|
|
sub listen { |
1557
|
|
|
|
|
|
|
|
1558
|
|
|
|
|
|
|
# create object |
1559
|
0
|
|
|
0
|
1
|
|
my $_proto = shift; |
1560
|
0
|
|
0
|
|
|
|
my $_class = ref($_proto) || $_proto; |
1561
|
0
|
|
|
|
|
|
my $_listen = {}; |
1562
|
|
|
|
|
|
|
# bless object |
1563
|
0
|
|
|
|
|
|
bless($_listen, $_class); |
1564
|
|
|
|
|
|
|
|
1565
|
0
|
|
|
|
|
|
$ERROR = ''; |
1566
|
|
|
|
|
|
|
|
1567
|
|
|
|
|
|
|
# define CTRL-C |
1568
|
0
|
|
|
|
|
|
$SIG{INT} = \&interupt_listen; |
1569
|
|
|
|
|
|
|
|
1570
|
0
|
|
|
|
|
|
my %_arg = @_; |
1571
|
0
|
|
|
|
|
|
my ($_a, $_err, |
1572
|
|
|
|
|
|
|
$_sock, $_port, $ipaddr, $_ipaddr_packed, $_rhost, |
1573
|
|
|
|
|
|
|
$_msg, $_msg_count, |
1574
|
|
|
|
|
|
|
$_parse_obj, $_parse, |
1575
|
|
|
|
|
|
|
$_report, |
1576
|
|
|
|
|
|
|
$_fwd_sock, $_fwd, |
1577
|
|
|
|
|
|
|
); |
1578
|
|
|
|
|
|
|
|
1579
|
|
|
|
|
|
|
|
1580
|
|
|
|
|
|
|
# set defaults |
1581
|
0
|
|
|
|
|
|
$_listen->{'port'} = 514; |
1582
|
0
|
|
|
|
|
|
$_listen->{'proto'} = 'udp'; |
1583
|
0
|
|
|
|
|
|
$_listen->{'maxlength'} = '1024'; |
1584
|
0
|
|
|
|
|
|
$_listen->{'verbose'} = 0; |
1585
|
0
|
|
|
|
|
|
$_listen->{'packets'} = -1; |
1586
|
|
|
|
|
|
|
|
1587
|
0
|
|
|
|
|
|
$_listen->{'report'} = 0; |
1588
|
0
|
|
|
|
|
|
$_listen->{'format'} = 'bsd'; |
1589
|
0
|
|
|
|
|
|
$_listen->{'moreTime'} = 0; |
1590
|
0
|
|
|
|
|
|
$_listen->{'parseTag'} = 0; |
1591
|
|
|
|
|
|
|
|
1592
|
0
|
|
|
|
|
|
$_listen->{'fwd_port'} = '514'; |
1593
|
0
|
|
|
|
|
|
$_listen->{'fwd_proto'} = 'udp'; |
1594
|
|
|
|
|
|
|
|
1595
|
0
|
|
|
|
|
|
$_fwd = 0; |
1596
|
|
|
|
|
|
|
|
1597
|
|
|
|
|
|
|
|
1598
|
0
|
|
|
|
|
|
foreach $_a (keys %_arg) { |
1599
|
0
|
0
|
|
|
|
|
if ($_a =~ /^-?port$/) { $_listen->{'port'} = delete($_arg{$_a}); } |
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1600
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?proto$/) { $_listen->{'proto'} = delete($_arg{$_a}); } |
1601
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?maxlength$/) { $_listen->{'maxlength'} = delete($_arg{$_a}); } |
1602
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?packets$/) { $_listen->{'packets'} = delete($_arg{$_a}); } |
1603
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?verbose$/) { $_listen->{'verbose'} = delete($_arg{$_a}); } |
|
0
|
|
|
|
|
|
|
1604
|
|
|
|
|
|
|
# parser options |
1605
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?dump$/i) {$_listen->{'dump'} = delete($_arg{$_a}); } |
1606
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?append$/i) {$_listen->{'append'} = delete($_arg{$_a}); } |
1607
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?ext$/i) {$_listen->{'ext'} = delete($_arg{$_a}); } |
1608
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?report$/i) {$_listen->{'report'} = delete($_arg{$_a}); } |
1609
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?interval$/i) {$_listen->{'interval'} = delete($_arg{$_a}); } |
1610
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?rx_time$/i) {$_listen->{'rx_time'} = delete($_arg{$_a}); } |
1611
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?lastmsg$/i) {$_listen->{'lastmsg'} = delete($_arg{$_a}); } |
1612
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?debug$/i) {$_listen->{'debug'} = delete($_arg{$_a}); } |
1613
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?min_date$/i) {$_listen->{'filter_min_date'} = delete($_arg{$_a}); } |
1614
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?max_date$/i) {$_listen->{'filter_max_date'} = delete($_arg{$_a}); } |
1615
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?device$/i) {$_listen->{'filter_device'} = delete($_arg{$_a}); } |
1616
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?tag$/i) {$_listen->{'filter_tag'} = delete($_arg{$_a}); } |
1617
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?message$/i) {$_listen->{'filter_message'} = delete($_arg{$_a}); } |
1618
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?format$/i) {$_listen->{'format'} = delete($_arg{$_a}); } |
1619
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?moreTime$/i) {$_listen->{'moreTime'} = delete($_arg{$_a}); } |
1620
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?parseTag$/i) {$_listen->{'parseTag'} = delete($_arg{$_a}); } |
1621
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?fwd_server/i) {$_listen->{'fwd_server'} = delete($_arg{$_a}); } |
1622
|
0
|
|
|
|
|
|
elsif ($_a =~ /^-?fwd_port/i) {$_listen->{'fwd_port'} = delete($_arg{$_a}); } |
1623
|
|
|
|
|
|
|
elsif ($_a =~ /^-?fwd_proto/i) {$_listen->{'fwd_proto'} = delete($_arg{$_a}); } |
1624
|
|
|
|
|
|
|
else { |
1625
|
0
|
|
|
|
|
|
$ERROR = sprintf("unsupported argument: %s => %s", $_a, $_arg{$_a}); |
1626
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1627
|
|
|
|
|
|
|
} |
1628
|
|
|
|
|
|
|
} |
1629
|
|
|
|
|
|
|
|
1630
|
|
|
|
|
|
|
# on unix, you need to be root if port < 1024 |
1631
|
0
|
0
|
|
|
|
|
if ($^O !~ /win/i) { |
1632
|
0
|
0
|
0
|
|
|
|
if ($_listen->{'port'} < 1024 && $> != 0) { |
1633
|
0
|
|
|
|
|
|
$ERROR = "must have root uid, not $> for port $_listen->{'port'}"; |
1634
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1635
|
|
|
|
|
|
|
} |
1636
|
|
|
|
|
|
|
} |
1637
|
|
|
|
|
|
|
|
1638
|
|
|
|
|
|
|
# see if we need to parse the syslog line |
1639
|
0
|
0
|
0
|
|
|
|
if ($_listen->{'report'} || $_listen->{'verbose'} > 1) { |
1640
|
0
|
0
|
|
|
|
|
($_parse_obj, $_err) = Syslog->parse( |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1641
|
|
|
|
|
|
|
-report => $_listen->{'report'}, |
1642
|
|
|
|
|
|
|
exists($_listen->{'dump'}) ? (-dump => $_listen->{'dump'}) : (), |
1643
|
|
|
|
|
|
|
exists($_listen->{'append'}) ? (-append => $_listen->{'append'}) : (), |
1644
|
|
|
|
|
|
|
exists($_listen->{'ext'}) ? (-ext => $_listen->{'ext'}) : (), |
1645
|
|
|
|
|
|
|
exists($_listen->{'report'}) ? (-report => $_listen->{'report'}) : (), |
1646
|
|
|
|
|
|
|
exists($_listen->{'interval'}) ? (-interval => $_listen->{'interval'}) : (), |
1647
|
|
|
|
|
|
|
exists($_listen->{'rx_time'}) ? (-rx_time => $_listen->{'rx_time'}) : (), |
1648
|
|
|
|
|
|
|
exists($_listen->{'lastmsg'}) ? (-lastmsg => $_listen->{'lastmsg'}) : (), |
1649
|
|
|
|
|
|
|
exists($_listen->{'debug'}) ? (-debug => $_listen->{'debug'}) : (), |
1650
|
|
|
|
|
|
|
exists($_listen->{'msg_plus'}) ? (-msg_plus => $_listen->{'msg_plus'}) : (), |
1651
|
|
|
|
|
|
|
exists($_listen->{'min_date'}) ? (-min_date => $_listen->{'min_date'}) : (), |
1652
|
|
|
|
|
|
|
exists($_listen->{'max_date'}) ? (-max_date => $_listen->{'max_date'}) : (), |
1653
|
|
|
|
|
|
|
exists($_listen->{'device'}) ? (-device => $_listen->{'device'}) : (), |
1654
|
|
|
|
|
|
|
exists($_listen->{'tag'}) ? (-tag => $_listen->{'tag'}) : (), |
1655
|
|
|
|
|
|
|
exists($_listen->{'message'}) ? (-message => $_listen->{'message'}) : (), |
1656
|
|
|
|
|
|
|
exists($_listen->{'format'}) ? (-format => $_listen->{'format'}) : (), |
1657
|
|
|
|
|
|
|
exists($_listen->{'moreTime'}) ? (-moreTime => $_listen->{'moreTime'}) : (), |
1658
|
|
|
|
|
|
|
exists($_listen->{'parseTag'}) ? (-parseTag => $_listen->{'parseTag'}) : (), |
1659
|
|
|
|
|
|
|
); |
1660
|
0
|
0
|
|
|
|
|
unless($_parse_obj) { |
1661
|
0
|
|
|
|
|
|
$ERROR = "listener failed to open parser: $_err"; |
1662
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1663
|
|
|
|
|
|
|
} |
1664
|
|
|
|
|
|
|
} |
1665
|
|
|
|
|
|
|
|
1666
|
0
|
0
|
|
|
|
|
$_fwd = 1 if defined($_listen->{'fwd_server'}); |
1667
|
|
|
|
|
|
|
|
1668
|
|
|
|
|
|
|
# open socket |
1669
|
|
|
|
|
|
|
# |
1670
|
|
|
|
|
|
|
# fwd socket |
1671
|
0
|
0
|
|
|
|
|
if ($_fwd) { |
1672
|
0
|
|
|
|
|
|
printf("forwarding to %s:%s %s\n", |
1673
|
|
|
|
|
|
|
$_listen->{'fwd_server'}, $_listen->{'fwd_port'}, $_listen->{'fwd_proto'} |
1674
|
|
|
|
|
|
|
); |
1675
|
0
|
|
|
|
|
|
$_fwd_sock = IO::Socket::INET->new( |
1676
|
|
|
|
|
|
|
PeerAddr => $_listen->{'fwd_server'}, |
1677
|
|
|
|
|
|
|
PeerPort => $_listen->{'fwd_port'}, |
1678
|
|
|
|
|
|
|
Proto => $_listen->{'fwd_proto'} |
1679
|
|
|
|
|
|
|
); |
1680
|
0
|
0
|
|
|
|
|
unless ($_fwd_sock) { |
1681
|
0
|
|
|
|
|
|
$ERROR = sprintf("could not open forward socket to %s:%s [%s]", |
1682
|
|
|
|
|
|
|
$_listen->{'fwd_server'}, $_listen->{'port'}, $! |
1683
|
|
|
|
|
|
|
); |
1684
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1685
|
|
|
|
|
|
|
} |
1686
|
|
|
|
|
|
|
} |
1687
|
|
|
|
|
|
|
# rx socket |
1688
|
0
|
0
|
|
|
|
|
printf("opening rx socket port %s proto %s %s\n", |
1689
|
|
|
|
|
|
|
$_listen->{'port'}, $_listen->{'proto'}, |
1690
|
|
|
|
|
|
|
$_fwd ? 'forwarding' : 'not forwarding', |
1691
|
|
|
|
|
|
|
); |
1692
|
0
|
|
|
|
|
|
$_sock = IO::Socket::INET->new( |
1693
|
|
|
|
|
|
|
LocalPort => $_listen->{'port'}, |
1694
|
|
|
|
|
|
|
Proto => $_listen->{'proto'}, |
1695
|
|
|
|
|
|
|
); |
1696
|
0
|
0
|
|
|
|
|
unless ($_sock) { |
1697
|
0
|
|
|
|
|
|
$ERROR = sprintf("socket failed port: %s %s : %s", |
1698
|
|
|
|
|
|
|
$_listen->{'port'}, $_listen->{'proto'}, $@, |
1699
|
|
|
|
|
|
|
); |
1700
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : undef); |
1701
|
|
|
|
|
|
|
} |
1702
|
|
|
|
|
|
|
|
1703
|
|
|
|
|
|
|
# listen on socket |
1704
|
0
|
|
|
|
|
|
$_msg_count = 0; |
1705
|
0
|
|
|
|
|
|
while ($_sock->recv($_msg, $_listen->{'maxlength'})) { |
1706
|
0
|
|
|
|
|
|
printf("%s\n", $_msg); |
1707
|
0
|
0
|
|
|
|
|
if ($_fwd) { |
1708
|
0
|
|
|
|
|
|
print $_fwd_sock $_msg; |
1709
|
|
|
|
|
|
|
} |
1710
|
0
|
|
|
|
|
|
$_msg_count++; |
1711
|
|
|
|
|
|
|
# print out little more if we are verbose |
1712
|
0
|
0
|
|
|
|
|
if ($_listen->{'verbose'}) { |
1713
|
0
|
|
|
|
|
|
($_port, $_ipaddr_packed) = sockaddr_in($_sock->peername); |
1714
|
0
|
|
|
|
|
|
$ipaddr = inet_ntoa($_ipaddr_packed); |
1715
|
0
|
|
|
|
|
|
$_rhost = gethostbyaddr($_ipaddr_packed, AF_INET); |
1716
|
0
|
|
|
|
|
|
printf(" Packet: %s from %s:%s [%s]\n", |
1717
|
|
|
|
|
|
|
$_msg_count, $ipaddr, $_port, $_rhost |
1718
|
|
|
|
|
|
|
); |
1719
|
|
|
|
|
|
|
} |
1720
|
|
|
|
|
|
|
# parse the line if we want a report |
1721
|
0
|
0
|
0
|
|
|
|
if ($_listen->{'report'} || $_listen->{'verbose'} > 1) { |
1722
|
0
|
|
|
|
|
|
($_parse, $_err) = $_parse_obj->parse_syslog_line($_msg); |
1723
|
0
|
0
|
|
|
|
|
if ($_parse) { |
1724
|
0
|
0
|
|
|
|
|
if ($_listen->{'verbose'} > 1) { |
1725
|
0
|
|
|
|
|
|
printf(" Priority: %s Facility [%s] Severity [%s]\n", |
1726
|
|
|
|
|
|
|
$_parse->{'rx_priority'}, $_parse->{'rx_facility'}, $_parse->{'rx_severity'} |
1727
|
|
|
|
|
|
|
); |
1728
|
0
|
|
|
|
|
|
printf(" Timestamp: %s\n", $_parse->{'timestamp'}); |
1729
|
0
|
|
|
|
|
|
printf(" Device: %s\n", $_parse->{'device'}); |
1730
|
0
|
|
|
|
|
|
printf(" Tag: %s %s\n", $_parse->{'tag'}, $_parse->{'pid'}); |
1731
|
0
|
|
|
|
|
|
printf(" Content: %s\n", $_parse->{'content'}); |
1732
|
|
|
|
|
|
|
} |
1733
|
|
|
|
|
|
|
} |
1734
|
|
|
|
|
|
|
else { |
1735
|
0
|
0
|
|
|
|
|
printf("parse_syslog_line failed: %s\n", $_err) if $_listen->{'verbose'}; |
1736
|
|
|
|
|
|
|
} |
1737
|
|
|
|
|
|
|
} |
1738
|
|
|
|
|
|
|
# check if we are counting packets |
1739
|
|
|
|
|
|
|
#if ($_listen->{'packets'} > 0) {last if $_msg_count == $_listen->{'packets'};} |
1740
|
0
|
0
|
|
|
|
|
if ($_listen->{'packets'} > 0) { |
1741
|
0
|
0
|
|
|
|
|
if ($_msg_count == $_listen->{'packets'}) { |
1742
|
0
|
|
|
|
|
|
printf("received %s packets set for %s\n", $_msg_count, $_listen->{'packets'}); |
1743
|
0
|
|
|
|
|
|
last; |
1744
|
|
|
|
|
|
|
} |
1745
|
|
|
|
|
|
|
} |
1746
|
|
|
|
|
|
|
} |
1747
|
0
|
0
|
|
|
|
|
$_sock->close if $_sock; |
1748
|
0
|
0
|
|
|
|
|
$_fwd_sock->close if $_fwd_sock; |
1749
|
|
|
|
|
|
|
|
1750
|
|
|
|
|
|
|
# close files if we reported and dumped |
1751
|
0
|
0
|
0
|
|
|
|
if ($_listen->{'report'} && $_listen->{'dump'}) {$_parse_obj->close_dumps;} |
|
0
|
|
|
|
|
|
|
1752
|
|
|
|
|
|
|
|
1753
|
|
|
|
|
|
|
|
1754
|
|
|
|
|
|
|
# function to handle CTRL-C |
1755
|
|
|
|
|
|
|
sub interupt_listen { |
1756
|
0
|
|
|
0
|
0
|
|
printf("CTRL-C detected: closing socket\n"); |
1757
|
0
|
|
|
|
|
|
$_sock->shutdown(0); |
1758
|
0
|
0
|
|
|
|
|
$_fwd_sock->shutdown(0) if $_fwd_sock; |
1759
|
|
|
|
|
|
|
} |
1760
|
|
|
|
|
|
|
|
1761
|
0
|
0
|
|
|
|
|
if ($_listen->{'report'}) { |
1762
|
0
|
|
|
|
|
|
printf("Returning object reference\n"); |
1763
|
0
|
0
|
|
|
|
|
return(wantarray ? ($_parse, $ERROR) : $_parse); |
1764
|
|
|
|
|
|
|
} |
1765
|
|
|
|
|
|
|
else { |
1766
|
0
|
0
|
|
|
|
|
return(wantarray ? ($_msg_count, "$_msg_count messages") : $_msg_count); |
1767
|
|
|
|
|
|
|
} |
1768
|
|
|
|
|
|
|
} # end sub listen |
1769
|
|
|
|
|
|
|
|
1770
|
|
|
|
|
|
|
|
1771
|
|
|
|
|
|
|
|
1772
|
|
|
|
|
|
|
# |
1773
|
|
|
|
|
|
|
#============================================================================= |
1774
|
|
|
|
|
|
|
# |
1775
|
|
|
|
|
|
|
# handle the files |
1776
|
|
|
|
|
|
|
# |
1777
|
|
|
|
|
|
|
#============================================================================= |
1778
|
|
|
|
|
|
|
# |
1779
|
|
|
|
|
|
|
# function to dump line to file |
1780
|
|
|
|
|
|
|
# |
1781
|
|
|
|
|
|
|
# Arg |
1782
|
|
|
|
|
|
|
# $_[0] class |
1783
|
|
|
|
|
|
|
# $_[1] devicename |
1784
|
|
|
|
|
|
|
# $_[2] line |
1785
|
|
|
|
|
|
|
# |
1786
|
|
|
|
|
|
|
# Return |
1787
|
|
|
|
|
|
|
# 1 or undef |
1788
|
|
|
|
|
|
|
# |
1789
|
|
|
|
|
|
|
sub dump_line_to_file { |
1790
|
|
|
|
|
|
|
|
1791
|
0
|
|
|
0
|
0
|
|
my $_h = $_[1]; |
1792
|
0
|
|
|
|
|
|
$_h =~ s/ +//g; |
1793
|
0
|
|
|
|
|
|
my $_dstfile = sprintf("%s%s.%s", $_[0]->{'repository'}, $_[1], $_[0]->{'ext'}); |
1794
|
|
|
|
|
|
|
|
1795
|
0
|
|
|
|
|
|
$ERROR = ''; |
1796
|
|
|
|
|
|
|
|
1797
|
0
|
|
|
|
|
|
log_debug(3, "syslog line dump to file: [%s]\n", $_dstfile); |
1798
|
|
|
|
|
|
|
# see if we have a file handle |
1799
|
0
|
0
|
|
|
|
|
if (!defined($FH{$_h})) { |
1800
|
|
|
|
|
|
|
# open for overwrite or appending |
1801
|
0
|
0
|
|
|
|
|
if ($_[0]->{'append'} == 1) { |
1802
|
0
|
0
|
|
|
|
|
open($FH{$_h}, ">>$_dstfile") or $ERROR = "open append failed: $_h: $!"; |
1803
|
|
|
|
|
|
|
} |
1804
|
|
|
|
|
|
|
else { |
1805
|
0
|
0
|
|
|
|
|
open($FH{$_h}, ">$_dstfile") or $ERROR = "open overwright failed: $_h: $!"; |
1806
|
|
|
|
|
|
|
} |
1807
|
0
|
|
|
|
|
|
select $FH{$_h}; $| = 1; |
|
0
|
|
|
|
|
|
|
1808
|
0
|
|
|
|
|
|
select STDOUT; $| = 1; |
|
0
|
|
|
|
|
|
|
1809
|
|
|
|
|
|
|
} |
1810
|
|
|
|
|
|
|
|
1811
|
|
|
|
|
|
|
# exit out if we errored |
1812
|
0
|
0
|
|
|
|
|
if ($ERROR) { |
1813
|
0
|
|
|
|
|
|
log_debug(3, "%s\n", $ERROR); |
1814
|
0
|
0
|
|
|
|
|
return(wantarray ? (undef, $ERROR) : $ERROR); |
1815
|
|
|
|
|
|
|
} |
1816
|
|
|
|
|
|
|
|
1817
|
0
|
|
|
|
|
|
my $fh = $FH{$_h}; |
1818
|
0
|
|
|
|
|
|
printf $fh ("%s\n", $_[2]); |
1819
|
|
|
|
|
|
|
|
1820
|
0
|
0
|
|
|
|
|
return(wantarray ? (1, $ERROR) : 1); |
1821
|
|
|
|
|
|
|
|
1822
|
|
|
|
|
|
|
} |
1823
|
|
|
|
|
|
|
# |
1824
|
|
|
|
|
|
|
#............................................................................. |
1825
|
|
|
|
|
|
|
# |
1826
|
|
|
|
|
|
|
# function to close all files |
1827
|
|
|
|
|
|
|
# |
1828
|
|
|
|
|
|
|
# |
1829
|
|
|
|
|
|
|
sub close_dumps { |
1830
|
0
|
|
|
0
|
1
|
|
my $_f; |
1831
|
|
|
|
|
|
|
# close any filehandle opened for parse |
1832
|
0
|
|
|
|
|
|
foreach $_f (keys %FH) { close($FH{$_f});} |
|
0
|
|
|
|
|
|
|
1833
|
0
|
|
|
|
|
|
1; |
1834
|
|
|
|
|
|
|
} |
1835
|
|
|
|
|
|
|
|
1836
|
|
|
|
|
|
|
############################################################################## |
1837
|
|
|
|
|
|
|
# |
1838
|
|
|
|
|
|
|
# Report Functions |
1839
|
|
|
|
|
|
|
# |
1840
|
|
|
|
|
|
|
# |
1841
|
|
|
|
|
|
|
#............................................................................. |
1842
|
|
|
|
|
|
|
# |
1843
|
|
|
|
|
|
|
# |
1844
|
|
|
|
|
|
|
# function to derive stats |
1845
|
|
|
|
|
|
|
# stats are generated if -report => 1 |
1846
|
|
|
|
|
|
|
# |
1847
|
|
|
|
|
|
|
# user will have to access the %STATS hash created |
1848
|
|
|
|
|
|
|
# |
1849
|
|
|
|
|
|
|
# |
1850
|
|
|
|
|
|
|
# @DEVICES = list of each device found |
1851
|
|
|
|
|
|
|
# @TAGS = list of each tag found |
1852
|
|
|
|
|
|
|
# @FACILITYS = list of each facility found |
1853
|
|
|
|
|
|
|
# @SEVERITYS = list of each of each severity found |
1854
|
|
|
|
|
|
|
# |
1855
|
|
|
|
|
|
|
# %STATS{'syslog'}{'messages'} |
1856
|
|
|
|
|
|
|
# {'tag'}{}{'messages'} |
1857
|
|
|
|
|
|
|
# {'facility'}{}{'messages'} |
1858
|
|
|
|
|
|
|
# {'severity'}{}{'messages'} |
1859
|
|
|
|
|
|
|
# {'min_epoch'} |
1860
|
|
|
|
|
|
|
# {'min_date_str'} # done with &syslog_stats_epoch2datestr |
1861
|
|
|
|
|
|
|
# {'max_epoch'} |
1862
|
|
|
|
|
|
|
# {'max_date_str'} # done with &syslog_stats_epoch2datestr |
1863
|
|
|
|
|
|
|
# |
1864
|
|
|
|
|
|
|
# |
1865
|
|
|
|
|
|
|
# {'device'}{}{'messages'} |
1866
|
|
|
|
|
|
|
# {'tag'}{}{'messages'} |
1867
|
|
|
|
|
|
|
# {'facility'}{}{'messages'} |
1868
|
|
|
|
|
|
|
# {'severity'}{}{'messages'} |
1869
|
|
|
|
|
|
|
# {'min_epoch'} |
1870
|
|
|
|
|
|
|
# {'min_date_str'} # done with &syslog_stats_epoch2datestr |
1871
|
|
|
|
|
|
|
# {'max_epoch'} |
1872
|
|
|
|
|
|
|
# {'max_date_str'} # done with &syslog_stats_epoch2datestr |
1873
|
|
|
|
|
|
|
# |
1874
|
|
|
|
|
|
|
# |
1875
|
|
|
|
|
|
|
sub syslog_stats { |
1876
|
|
|
|
|
|
|
|
1877
|
0
|
|
0
|
0
|
0
|
|
my $_tag = $SYSLOG_href->{'tag'} || $NOTAG; |
1878
|
0
|
|
0
|
|
|
|
my $_prio = $SYSLOG_href->{'rx_priority'} || 'noFacility.noSeverity'; |
1879
|
0
|
|
0
|
|
|
|
my $_fac = $SYSLOG_href->{'rx_facility'} || 'noFacility'; |
1880
|
0
|
|
0
|
|
|
|
my $_sev = $SYSLOG_href->{'rx_severity'} || 'noSeverity'; |
1881
|
|
|
|
|
|
|
|
1882
|
|
|
|
|
|
|
|
1883
|
|
|
|
|
|
|
# set min,max epoch for date |
1884
|
|
|
|
|
|
|
# needed to be able to find min max dates |
1885
|
0
|
0
|
|
|
|
|
if (!defined($STATS{'syslog'}{'min_epoch'})) {$STATS{'syslog'}{'min_epoch'} = 2**32;} |
|
0
|
|
|
|
|
|
|
1886
|
0
|
0
|
|
|
|
|
if (!defined($STATS{'syslog'}{'max_epoch'})) {$STATS{'syslog'}{'max_epoch'} = 1;} |
|
0
|
|
|
|
|
|
|
1887
|
|
|
|
|
|
|
|
1888
|
|
|
|
|
|
|
# |
1889
|
|
|
|
|
|
|
# populate arrays |
1890
|
|
|
|
|
|
|
# |
1891
|
|
|
|
|
|
|
# device list |
1892
|
0
|
0
|
|
|
|
|
if ( !defined($STATS{'device'}{$SYSLOG_href->{'device'}}) ) |
1893
|
0
|
|
|
|
|
|
{ push(@DEVICES, $SYSLOG_href->{'device'}); } |
1894
|
|
|
|
|
|
|
|
1895
|
|
|
|
|
|
|
# TAG list |
1896
|
0
|
0
|
|
|
|
|
if ( !defined($STATS{'syslog'}{'tag'}{$_tag}) ) |
1897
|
0
|
|
|
|
|
|
{ push(@TAGS, $_tag); } |
1898
|
|
|
|
|
|
|
|
1899
|
|
|
|
|
|
|
# FACILITY list |
1900
|
0
|
0
|
|
|
|
|
if ( !defined($STATS{'syslog'}{'facility'}{$_fac}) ) |
1901
|
0
|
|
|
|
|
|
{ push(@FACILITYS, $_fac); } |
1902
|
|
|
|
|
|
|
|
1903
|
|
|
|
|
|
|
# SEVERITY list |
1904
|
0
|
0
|
|
|
|
|
if ( !defined($STATS{'syslog'}{'severity'}{$_sev}) ) |
1905
|
0
|
|
|
|
|
|
{ push(@SEVERITYS, $_sev ); } |
1906
|
|
|
|
|
|
|
|
1907
|
|
|
|
|
|
|
# |
1908
|
|
|
|
|
|
|
# per syslog |
1909
|
|
|
|
|
|
|
# |
1910
|
0
|
|
|
|
|
|
$STATS{'syslog'}{'messages'}++; |
1911
|
0
|
|
|
|
|
|
$STATS{'syslog'}{'tag'}{$_tag}{'messages'}++; |
1912
|
0
|
|
|
|
|
|
$STATS{'syslog'}{'facility'}{$_fac}{'messages'}++; |
1913
|
0
|
|
|
|
|
|
$STATS{'syslog'}{'severity'}{$_sev}{'messages'}++; |
1914
|
|
|
|
|
|
|
|
1915
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'epoch'} < $STATS{'syslog'}{'min_epoch'}) |
|
0
|
|
|
|
|
|
|
1916
|
|
|
|
|
|
|
{$STATS{'syslog'}{'min_epoch'} = $SYSLOG_href->{'epoch'};} |
1917
|
|
|
|
|
|
|
|
1918
|
0
|
0
|
|
|
|
|
if ($SYSLOG_href->{'epoch'} > $STATS{'syslog'}{'max_epoch'}) |
|
0
|
|
|
|
|
|
|
1919
|
|
|
|
|
|
|
{$STATS{'syslog'}{'max_epoch'} = $SYSLOG_href->{'epoch'};} |
1920
|
|
|
|
|
|
|
|
1921
|
|
|
|
|
|
|
# |
1922
|
|
|
|
|
|
|
# per device |
1923
|
|
|
|
|
|
|
# |
1924
|
0
|
|
|
|
|
|
$STATS{'device'}{$SYSLOG_href->{'device'}}{'messages'}++; |
1925
|
0
|
|
|
|
|
|
$STATS{'device'}{$SYSLOG_href->{'device'}}{'tag'}{$_tag}{'messages'}++; |
1926
|
0
|
|
|
|
|
|
$STATS{'device'}{$SYSLOG_href->{'device'}}{'facility'}{$_fac}{'messages'}++; |
1927
|
0
|
|
|
|
|
|
$STATS{'device'}{$SYSLOG_href->{'device'}}{'severity'}{$_sev}{'messages'}++; |
1928
|
|
|
|
|
|
|
|
1929
|
|
|
|
|
|
|
# check for min/max epoch existence |
1930
|
0
|
0
|
|
|
|
|
if (!defined($STATS{'device'}{$SYSLOG_href->{'device'}}{'min_epoch'})) |
|
0
|
|
|
|
|
|
|
1931
|
|
|
|
|
|
|
{$STATS{'device'}{$SYSLOG_href->{'device'}}{'min_epoch'} = 2**32;} |
1932
|
0
|
0
|
|
|
|
|
if (!defined($STATS{'device'}{$SYSLOG_href->{'device'}}{'max_epoch'})) |
|
0
|
|
|
|
|
|
|
1933
|
|
|
|
|
|
|
{$STATS{'device'}{$SYSLOG_href->{'device'}}{'max_epoch'} = 1;} |
1934
|
|
|
|
|
|
|
|
1935
|
|
|
|
|
|
|
# find min/max epoch per device |
1936
|
0
|
0
|
|
|
|
|
if($SYSLOG_href->{'epoch'} < $STATS{'device'}{$SYSLOG_href->{'device'}}{'min_epoch'}) |
|
0
|
|
|
|
|
|
|
1937
|
|
|
|
|
|
|
{$STATS{'device'}{$SYSLOG_href->{'device'}}{'min_epoch'} = $SYSLOG_href->{'epoch'};} |
1938
|
0
|
0
|
|
|
|
|
if($SYSLOG_href->{'epoch'} > $STATS{'device'}{$SYSLOG_href->{'device'}}{'max_epoch'}) |
|
0
|
|
|
|
|
|
|
1939
|
|
|
|
|
|
|
{$STATS{'device'}{$SYSLOG_href->{'device'}}{'max_epoch'} = $SYSLOG_href->{'epoch'};} |
1940
|
|
|
|
|
|
|
|
1941
|
0
|
|
|
|
|
|
1; |
1942
|
|
|
|
|
|
|
|
1943
|
|
|
|
|
|
|
} # end sub syslog_stats |
1944
|
|
|
|
|
|
|
|
1945
|
|
|
|
|
|
|
|
1946
|
|
|
|
|
|
|
# |
1947
|
|
|
|
|
|
|
#............................................................................. |
1948
|
|
|
|
|
|
|
# |
1949
|
|
|
|
|
|
|
# function to convert epoch values in %STAT to date strings |
1950
|
|
|
|
|
|
|
# do this separate so as to do it once per device and whole syslog |
1951
|
|
|
|
|
|
|
# |
1952
|
|
|
|
|
|
|
# |
1953
|
|
|
|
|
|
|
|
1954
|
|
|
|
|
|
|
sub syslog_stats_epoch2datestr { |
1955
|
|
|
|
|
|
|
|
1956
|
0
|
|
|
0
|
1
|
|
my $dev; |
1957
|
|
|
|
|
|
|
|
1958
|
0
|
|
|
|
|
|
$STATS{'syslog'}{'min_date_str'} = epoch_to_datestr($STATS{'syslog'}{'min_epoch'}); |
1959
|
0
|
|
|
|
|
|
$STATS{'syslog'}{'max_date_str'} = epoch_to_datestr($STATS{'syslog'}{'max_epoch'}); |
1960
|
|
|
|
|
|
|
|
1961
|
0
|
|
|
|
|
|
foreach $dev (keys %{$STATS{'device'}}) { |
|
0
|
|
|
|
|
|
|
1962
|
0
|
|
|
|
|
|
$STATS{'device'}{$dev}{'min_date_str'} = epoch_to_datestr($STATS{'device'}{$dev}{'min_epoch'}); |
1963
|
0
|
|
|
|
|
|
$STATS{'device'}{$dev}{'max_date_str'} = epoch_to_datestr($STATS{'device'}{$dev}{'max_epoch'}); |
1964
|
|
|
|
|
|
|
} |
1965
|
|
|
|
|
|
|
|
1966
|
0
|
|
|
|
|
|
1; |
1967
|
|
|
|
|
|
|
} |
1968
|
|
|
|
|
|
|
|
1969
|
|
|
|
|
|
|
|
1970
|
|
|
|
|
|
|
############################################################################# |
1971
|
|
|
|
|
|
|
# |
1972
|
|
|
|
|
|
|
# Timestamp Functions |
1973
|
|
|
|
|
|
|
# |
1974
|
|
|
|
|
|
|
#............................................................................. |
1975
|
|
|
|
|
|
|
# |
1976
|
|
|
|
|
|
|
# function to convert epoch to (month, day, hour, epoch_start_of_day) |
1977
|
|
|
|
|
|
|
# epoch_time_of_day for this (month, day, hour) |
1978
|
|
|
|
|
|
|
# |
1979
|
|
|
|
|
|
|
# Arg |
1980
|
|
|
|
|
|
|
# epoch seconds |
1981
|
|
|
|
|
|
|
# Return |
1982
|
|
|
|
|
|
|
# (month, day, hr, min, epoch_start_of_day, epoch_end_of_day); |
1983
|
|
|
|
|
|
|
# |
1984
|
|
|
|
|
|
|
sub _epoch_to_mdhm { |
1985
|
|
|
|
|
|
|
|
1986
|
|
|
|
|
|
|
# 0 1 2 3 4 5 6 7 8 |
1987
|
|
|
|
|
|
|
# localtime(epoch) = ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) |
1988
|
0
|
|
|
0
|
|
|
my @_val = localtime($_[0]); |
1989
|
|
|
|
|
|
|
|
1990
|
|
|
|
|
|
|
# sec min hr mday mon yr |
1991
|
0
|
|
|
|
|
|
my $_epoch_start_of_day = timelocal(0, 0, 0, $_val[3], $_val[4], $YEAR); |
1992
|
0
|
|
|
|
|
|
my $_epoch_end_of_day = timelocal(59, 59, 23, $_val[3], $_val[4], $YEAR); |
1993
|
|
|
|
|
|
|
|
1994
|
0
|
|
|
|
|
|
return($MON{$_val[4]}, $_val[3], $_val[2], $_val[1], $_epoch_start_of_day, $_epoch_end_of_day); |
1995
|
|
|
|
|
|
|
} |
1996
|
|
|
|
|
|
|
# |
1997
|
|
|
|
|
|
|
#............................................................................. |
1998
|
|
|
|
|
|
|
# |
1999
|
|
|
|
|
|
|
# function to convert epoch seconds to timestamp |
2000
|
|
|
|
|
|
|
# if no epoch seconds are given, current epoch seconds are used |
2001
|
|
|
|
|
|
|
# |
2002
|
|
|
|
|
|
|
# Arg |
2003
|
|
|
|
|
|
|
# $_[0] = epoch seconds |
2004
|
|
|
|
|
|
|
# Return |
2005
|
|
|
|
|
|
|
# Mmm d hh:mm:ss |
2006
|
|
|
|
|
|
|
# Mmm dd hh:mm:ss |
2007
|
|
|
|
|
|
|
# |
2008
|
|
|
|
|
|
|
sub epoch_to_syslog_timestamp { |
2009
|
|
|
|
|
|
|
|
2010
|
0
|
|
0
|
0
|
1
|
|
my $epoch = shift || time; |
2011
|
0
|
|
|
|
|
|
my @t = localtime($epoch); |
2012
|
|
|
|
|
|
|
|
2013
|
0
|
|
|
|
|
|
sprintf("%3s %2s %02s:%02s:%02s", |
2014
|
|
|
|
|
|
|
$MON{$t[4]+1}, $t[3], $t[2], $t[1], $t[0] |
2015
|
|
|
|
|
|
|
); |
2016
|
|
|
|
|
|
|
|
2017
|
|
|
|
|
|
|
} |
2018
|
|
|
|
|
|
|
#............................................................................. |
2019
|
|
|
|
|
|
|
# |
2020
|
|
|
|
|
|
|
# function to convert epoch seconds to common date string (datestr) |
2021
|
|
|
|
|
|
|
# |
2022
|
|
|
|
|
|
|
# Arg |
2023
|
|
|
|
|
|
|
# $_[0] = epoch |
2024
|
|
|
|
|
|
|
# |
2025
|
|
|
|
|
|
|
# Return |
2026
|
|
|
|
|
|
|
# date string |
2027
|
|
|
|
|
|
|
# |
2028
|
|
|
|
|
|
|
# |
2029
|
|
|
|
|
|
|
sub epoch_to_datestr { |
2030
|
|
|
|
|
|
|
|
2031
|
0
|
|
0
|
0
|
1
|
|
my $_epoch = shift || time; |
2032
|
0
|
|
|
|
|
|
my $_datestr = ''; |
2033
|
|
|
|
|
|
|
|
2034
|
0
|
|
|
|
|
|
my @_tokens = localtime($_epoch); |
2035
|
|
|
|
|
|
|
|
2036
|
0
|
|
|
|
|
|
my $_month = $MON{$_tokens[4]+1}; |
2037
|
|
|
|
|
|
|
|
2038
|
0
|
|
|
|
|
|
$_datestr = sprintf("%s/%s/%s %02s:%02s:%02s", |
2039
|
|
|
|
|
|
|
$_month, $_tokens[3], $_tokens[5]+1900, |
2040
|
|
|
|
|
|
|
$_tokens[2], $_tokens[1], $_tokens[0], |
2041
|
|
|
|
|
|
|
); |
2042
|
|
|
|
|
|
|
|
2043
|
0
|
|
|
|
|
|
log_debug(3, "epoch_to_datestr %s => [%s] [%s] [%s] [%s]\n", |
2044
|
|
|
|
|
|
|
$_epoch, $_datestr, |
2045
|
|
|
|
|
|
|
$_month, $_tokens[3], $_tokens[5]+1900, |
2046
|
|
|
|
|
|
|
); |
2047
|
|
|
|
|
|
|
|
2048
|
0
|
|
|
|
|
|
$_datestr; |
2049
|
|
|
|
|
|
|
} |
2050
|
|
|
|
|
|
|
|
2051
|
|
|
|
|
|
|
|
2052
|
|
|
|
|
|
|
# |
2053
|
|
|
|
|
|
|
#............................................................................. |
2054
|
|
|
|
|
|
|
# |
2055
|
|
|
|
|
|
|
# function to convert date give as a filter to an epoch |
2056
|
|
|
|
|
|
|
# |
2057
|
|
|
|
|
|
|
# Arg |
2058
|
|
|
|
|
|
|
# $_[0] = mm/dd/yyyy hh:mm:ss |
2059
|
|
|
|
|
|
|
sub date_filter_to_epoch { |
2060
|
|
|
|
|
|
|
|
2061
|
0
|
|
|
0
|
1
|
|
my $_str = shift; |
2062
|
0
|
|
|
|
|
|
my ($_mon, $_day, $_yr, $_hr, $_min, $_sec, $_epoch); |
2063
|
|
|
|
|
|
|
|
2064
|
|
|
|
|
|
|
# if Mmm/dd/yyyy convert month alpha string to decimal |
2065
|
0
|
0
|
|
|
|
|
if ($_str =~ /([JFMASONDjfmasond]\w\w)\/\d{1,2}\//) { |
2066
|
0
|
|
|
|
|
|
$_str =~ s/$1/$MON_index{$1}/; |
2067
|
|
|
|
|
|
|
} |
2068
|
|
|
|
|
|
|
|
2069
|
|
|
|
|
|
|
# mm/dd/yyyy hh:mm:ss |
2070
|
0
|
0
|
|
|
|
|
if ($_str =~ /^(\d{1,2})\/(\d{1,2})\/(\d{1,4}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2071
|
0
|
|
|
|
|
|
$_mon = $1; $_day = $2; $_yr = $3; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2072
|
0
|
|
|
|
|
|
$_hr = $4; $_min = $5; $_sec = $6; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2073
|
|
|
|
|
|
|
} |
2074
|
|
|
|
|
|
|
# mm/dd/yyyy hh:mm |
2075
|
|
|
|
|
|
|
elsif ($_str =~ /^(\d{1,2})\/(\d{1,2})\/(\d{1,4}) (\d{1,2}):(\d{1,2})$/) { |
2076
|
0
|
|
|
|
|
|
$_mon = $1; $_day = $2; $_yr = $3; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2077
|
0
|
|
|
|
|
|
$_hr = $4; $_min = $5; $_sec = 0; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2078
|
|
|
|
|
|
|
} |
2079
|
|
|
|
|
|
|
# mm/dd/yyyy hh |
2080
|
|
|
|
|
|
|
elsif ($_str =~ /^(\d{1,2})\/(\d{1,2})\/(\d{1,4}) (\d{1,2})$/) { |
2081
|
0
|
|
|
|
|
|
$_mon = $1; $_day = $2; $_yr = $3; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2082
|
0
|
|
|
|
|
|
$_hr = $4; $_min = 0; $_sec = 0; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2083
|
|
|
|
|
|
|
} |
2084
|
|
|
|
|
|
|
|
2085
|
|
|
|
|
|
|
# mm/dd/yyyy |
2086
|
|
|
|
|
|
|
elsif ($_str =~ /^(\d{1,2})\/(\d{1,2})\/(\d{1,4})$/) { |
2087
|
0
|
|
|
|
|
|
$_mon = $1; $_day = $2; $_yr = $3; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2088
|
0
|
|
|
|
|
|
$_hr = 23; $_min = 59; $_sec = 59; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2089
|
|
|
|
|
|
|
} |
2090
|
|
|
|
|
|
|
# assert |
2091
|
|
|
|
|
|
|
else { |
2092
|
0
|
|
|
|
|
|
$ERROR = "unsupported date filter: $_str"; |
2093
|
0
|
|
|
|
|
|
return(undef); |
2094
|
|
|
|
|
|
|
} |
2095
|
|
|
|
|
|
|
|
2096
|
0
|
|
|
|
|
|
$_epoch = timelocal($_sec, $_min, $_hr, $_day, $_mon-1, $_yr); |
2097
|
|
|
|
|
|
|
|
2098
|
0
|
|
|
|
|
|
return($_epoch); |
2099
|
|
|
|
|
|
|
|
2100
|
|
|
|
|
|
|
} # end date_filter_to_epoch |
2101
|
|
|
|
|
|
|
|
2102
|
|
|
|
|
|
|
|
2103
|
|
|
|
|
|
|
# |
2104
|
|
|
|
|
|
|
#............................................................................. |
2105
|
|
|
|
|
|
|
# |
2106
|
|
|
|
|
|
|
# function to validate syslog timestamp |
2107
|
|
|
|
|
|
|
# |
2108
|
|
|
|
|
|
|
# Mmm d hh:mm:ss |
2109
|
|
|
|
|
|
|
# Mmm dd hh:mm:ss |
2110
|
|
|
|
|
|
|
# |
2111
|
|
|
|
|
|
|
# Arg |
2112
|
|
|
|
|
|
|
# $_[0] = timestamp |
2113
|
|
|
|
|
|
|
# |
2114
|
|
|
|
|
|
|
# Return |
2115
|
|
|
|
|
|
|
# 0 - not valid |
2116
|
|
|
|
|
|
|
# 1 - valid |
2117
|
|
|
|
|
|
|
sub validate_timestamp_syntax { |
2118
|
0
|
0
|
|
0
|
1
|
|
if ($_[0] =~ /[JFMASONDjfmasond]\w\w \d \d\d:\d\d:\d\d/) |
|
0
|
0
|
|
|
|
|
|
2119
|
0
|
|
|
|
|
|
{return(1);} |
2120
|
|
|
|
|
|
|
elsif ($_[0] =~ /[JFMASONDjfmasond]\w\w \d\d \d\d:\d\d:\d\d/) |
2121
|
0
|
|
|
|
|
|
{return(1);} |
2122
|
|
|
|
|
|
|
else |
2123
|
|
|
|
|
|
|
{return(0);} |
2124
|
|
|
|
|
|
|
} |
2125
|
|
|
|
|
|
|
|
2126
|
|
|
|
|
|
|
|
2127
|
|
|
|
|
|
|
# |
2128
|
|
|
|
|
|
|
#............................................................................. |
2129
|
|
|
|
|
|
|
# |
2130
|
|
|
|
|
|
|
# function to timeslots based on min/max epoch |
2131
|
|
|
|
|
|
|
# make global array |
2132
|
|
|
|
|
|
|
# @TIMESLOTS = ([index, low, high], ...) |
2133
|
|
|
|
|
|
|
# index = Mmm-dd-hh:mm |
2134
|
|
|
|
|
|
|
|
2135
|
|
|
|
|
|
|
# |
2136
|
|
|
|
|
|
|
# Arg |
2137
|
|
|
|
|
|
|
# $_[0] = min epoch |
2138
|
|
|
|
|
|
|
# $_[1] = max epoch |
2139
|
|
|
|
|
|
|
# $_[2] = interval |
2140
|
|
|
|
|
|
|
# |
2141
|
|
|
|
|
|
|
# |
2142
|
|
|
|
|
|
|
sub make_timeslots { |
2143
|
|
|
|
|
|
|
|
2144
|
0
|
|
|
0
|
1
|
|
my $_min_epoch = shift; |
2145
|
0
|
|
|
|
|
|
my $_max_epoch = shift; |
2146
|
0
|
|
0
|
|
|
|
my $_int = shift || 3600; |
2147
|
|
|
|
|
|
|
|
2148
|
0
|
|
|
|
|
|
my ($_time, $_idx); |
2149
|
|
|
|
|
|
|
|
2150
|
|
|
|
|
|
|
# check that we have min/max |
2151
|
0
|
0
|
0
|
|
|
|
if (!$_min_epoch || !$_max_epoch) { |
2152
|
0
|
|
|
|
|
|
$ERROR = "min epoch [$_min_epoch] or max epoch [$_min_epoch] not defined"; |
2153
|
0
|
0
|
|
|
|
|
return( wantarray ? (undef, $ERROR) : undef); |
2154
|
|
|
|
|
|
|
} |
2155
|
|
|
|
|
|
|
# check min < max |
2156
|
0
|
0
|
|
|
|
|
if ($_min_epoch > $_max_epoch) { |
2157
|
0
|
|
|
|
|
|
$ERROR = "min epoch [$_min_epoch] > max epoch [$_min_epoch]"; |
2158
|
0
|
0
|
|
|
|
|
return( wantarray ? (undef, $ERROR) : undef); |
2159
|
|
|
|
|
|
|
} |
2160
|
|
|
|
|
|
|
# interval can be no less than 60 |
2161
|
0
|
0
|
|
|
|
|
if ($_int < 60) { |
2162
|
0
|
|
|
|
|
|
$_int = 60; |
2163
|
|
|
|
|
|
|
} |
2164
|
|
|
|
|
|
|
|
2165
|
0
|
|
|
|
|
|
for ($_time = $_min_epoch; $_time <= $_max_epoch; $_time = $_time + $_int) { |
2166
|
0
|
|
|
|
|
|
log_debug(3, "report time: %s\n", $_time); |
2167
|
0
|
|
|
|
|
|
$_idx = epoch_to_datestr($_time); |
2168
|
0
|
|
|
|
|
|
push(@TIMESLOTS, [$_idx, $_time, $_time + ($_int - 1)]); |
2169
|
0
|
|
|
|
|
|
log_debug(3, "report timeslot: %s %s => %s\n", |
2170
|
|
|
|
|
|
|
$_idx, $_time, $_time + ($_int - 1) |
2171
|
|
|
|
|
|
|
); |
2172
|
|
|
|
|
|
|
} |
2173
|
0
|
0
|
|
|
|
|
return( wantarray ? (1, undef) : 1); |
2174
|
|
|
|
|
|
|
} |
2175
|
|
|
|
|
|
|
|
2176
|
|
|
|
|
|
|
|
2177
|
|
|
|
|
|
|
|
2178
|
|
|
|
|
|
|
# |
2179
|
|
|
|
|
|
|
#............................................................................. |
2180
|
|
|
|
|
|
|
# |
2181
|
|
|
|
|
|
|
# function to return index that tx_time belongs to, info stored @TIMESLOTS |
2182
|
|
|
|
|
|
|
# read in epoch seconds, find element in @INFO whose whose rang include |
2183
|
|
|
|
|
|
|
# this arg value |
2184
|
|
|
|
|
|
|
# return index |
2185
|
|
|
|
|
|
|
# @TIMESLOTS = ([index, low_epoch, high_epoch], ...) |
2186
|
|
|
|
|
|
|
# |
2187
|
|
|
|
|
|
|
# Arg |
2188
|
|
|
|
|
|
|
# $_[0] = epoch of timestamp |
2189
|
|
|
|
|
|
|
# |
2190
|
|
|
|
|
|
|
# Return |
2191
|
|
|
|
|
|
|
# timeslot index for stats |
2192
|
|
|
|
|
|
|
# |
2193
|
|
|
|
|
|
|
sub epoch_timeslot_index { |
2194
|
|
|
|
|
|
|
|
2195
|
0
|
|
|
0
|
1
|
|
my $_i; |
2196
|
0
|
|
|
|
|
|
foreach $_i (@TIMESLOTS) { |
2197
|
0
|
0
|
0
|
|
|
|
if($_[0] >= $_i->[1] && $_[0] <= $_i->[2]) { |
2198
|
0
|
|
|
|
|
|
return($_i->[0]); |
2199
|
|
|
|
|
|
|
} |
2200
|
|
|
|
|
|
|
} |
2201
|
0
|
|
|
|
|
|
undef; |
2202
|
|
|
|
|
|
|
|
2203
|
|
|
|
|
|
|
} |
2204
|
|
|
|
|
|
|
|
2205
|
|
|
|
|
|
|
# |
2206
|
|
|
|
|
|
|
#............................................................................. |
2207
|
|
|
|
|
|
|
# |
2208
|
|
|
|
|
|
|
# function to get extra time info: year and weekday |
2209
|
|
|
|
|
|
|
# |
2210
|
|
|
|
|
|
|
# Arg |
2211
|
|
|
|
|
|
|
# sec, min, hour, day, month |
2212
|
|
|
|
|
|
|
# Return |
2213
|
|
|
|
|
|
|
# wantarray ? ($_epoch, $_wday) : $_epoch |
2214
|
|
|
|
|
|
|
# |
2215
|
|
|
|
|
|
|
sub _extra_time_values { |
2216
|
|
|
|
|
|
|
|
2217
|
0
|
|
|
0
|
|
|
$_[4]--; # 0 base the month |
2218
|
|
|
|
|
|
|
|
2219
|
0
|
|
|
|
|
|
my $_epoch = timelocal(@_, $YEAR); |
2220
|
0
|
|
|
|
|
|
my $_wday = (localtime($_epoch))[6]; |
2221
|
0
|
0
|
|
|
|
|
if ($DEBUG) { |
2222
|
0
|
|
|
|
|
|
log_debug(3, "determine epoch and wday: s:%s m:%s h:%s d:%s mon: %s\n", |
2223
|
|
|
|
|
|
|
@_ |
2224
|
|
|
|
|
|
|
); |
2225
|
0
|
|
|
|
|
|
log_debug(3, "epoch: %s wday: [%s]\n", $_epoch, $_wday); |
2226
|
|
|
|
|
|
|
} |
2227
|
|
|
|
|
|
|
|
2228
|
0
|
0
|
|
|
|
|
return(wantarray ? ($_epoch, $_wday) : $_epoch); |
2229
|
|
|
|
|
|
|
|
2230
|
|
|
|
|
|
|
} |
2231
|
|
|
|
|
|
|
# |
2232
|
|
|
|
|
|
|
#============================================================================= |
2233
|
|
|
|
|
|
|
# |
2234
|
|
|
|
|
|
|
# function to decode PRI to facility and severity |
2235
|
|
|
|
|
|
|
# |
2236
|
|
|
|
|
|
|
# Arg |
2237
|
|
|
|
|
|
|
# $_[0] = PRI |
2238
|
|
|
|
|
|
|
# |
2239
|
|
|
|
|
|
|
# Return (lower case are decimal, upper case are strings) |
2240
|
|
|
|
|
|
|
# pri, facility, severity, PRI, Facility, Severity |
2241
|
|
|
|
|
|
|
|
2242
|
|
|
|
|
|
|
sub decode_PRI { |
2243
|
|
|
|
|
|
|
|
2244
|
0
|
|
|
0
|
1
|
|
my ($_p, $_f, $_s, $_F, $_S, $_P); |
2245
|
|
|
|
|
|
|
|
2246
|
0
|
|
|
|
|
|
$_p = $_[0]; |
2247
|
|
|
|
|
|
|
# strip out '<>' that bound PRI |
2248
|
0
|
0
|
|
|
|
|
if ($_[0] =~ /[<|>]/) { |
2249
|
0
|
|
|
|
|
|
$_p =~ s//; |
2250
|
0
|
|
|
|
|
|
$_p =~ s/>//; |
2251
|
|
|
|
|
|
|
} |
2252
|
|
|
|
|
|
|
|
2253
|
|
|
|
|
|
|
# check that decimal number is between 0->191 |
2254
|
0
|
0
|
0
|
|
|
|
if ($_p >= 0 && $_p <= 191) { |
2255
|
0
|
|
|
|
|
|
$_f = int($_p/8); |
2256
|
0
|
|
|
|
|
|
$_s = $_p - ($_f*8); |
2257
|
|
|
|
|
|
|
|
2258
|
0
|
|
0
|
|
|
|
$_F = $Facility_Index{$_f} || "?$_f?"; |
2259
|
0
|
|
0
|
|
|
|
$_S = $Severity_Index{$_s} || "?$_s?"; |
2260
|
0
|
|
|
|
|
|
$_P = sprintf("%s.%s", $_F, $_S); |
2261
|
|
|
|
|
|
|
|
2262
|
0
|
0
|
|
|
|
|
return(wantarray ? ($_p, $_f, $_s, $_P, $_F, $_S) : $_P ); |
2263
|
|
|
|
|
|
|
} |
2264
|
|
|
|
|
|
|
# otherwise error out |
2265
|
|
|
|
|
|
|
else { |
2266
|
0
|
0
|
|
|
|
|
return(wantarray ? (-1, -1, -1, 'P?', 'F?', 'S?') : undef ); |
2267
|
|
|
|
|
|
|
} |
2268
|
|
|
|
|
|
|
|
2269
|
|
|
|
|
|
|
} |
2270
|
|
|
|
|
|
|
|
2271
|
|
|
|
|
|
|
|
2272
|
|
|
|
|
|
|
# |
2273
|
|
|
|
|
|
|
#............................................................................. |
2274
|
|
|
|
|
|
|
# |
2275
|
|
|
|
|
|
|
# function to normalize facility string |
2276
|
|
|
|
|
|
|
# |
2277
|
|
|
|
|
|
|
sub normalize_facility { |
2278
|
|
|
|
|
|
|
|
2279
|
0
|
|
|
0
|
1
|
|
my $_str = ''; |
2280
|
|
|
|
|
|
|
|
2281
|
0
|
0
|
|
|
|
|
if ($_[0] =~ /kern/i) {$_str = 'kern'} |
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2282
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /user/i) {$_str = 'user'} |
2283
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /mail/i) {$_str = 'mail'} |
2284
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /daemon/i) {$_str = 'daemon'} |
2285
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /auth/i) {$_str = 'auth'} |
2286
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /syslog/i) {$_str = 'syslog'} |
2287
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /lpr/i) {$_str = 'lpr'} |
2288
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /news/i) {$_str = 'news'} |
2289
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /uucp/i) {$_str = 'uucp'} |
2290
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /cron/i) {$_str = 'cron'} |
2291
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /auth/i) {$_str = 'authpriv'} |
2292
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /ftp/i) {$_str = 'ftp'} |
2293
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /ntp/i) {$_str = 'ntp'} |
2294
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /audit/i) {$_str = 'audit'} |
2295
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /alert/i) {$_str = 'alert'} |
2296
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /at/i) {$_str = 'at'} |
2297
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /local0$/i) {$_str = 'local0'} |
2298
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /local1$/i) {$_str = 'local1'} |
2299
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /local2$/i) {$_str = 'local2'} |
2300
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /local3$/i) {$_str = 'local3'} |
2301
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /local4$/i) {$_str = 'local4'} |
2302
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /local5$/i) {$_str = 'local5'} |
2303
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /local6$/i) {$_str = 'local6'} |
2304
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /local7$/i) {$_str = 'local7'} |
2305
|
|
|
|
|
|
|
else {$_str = $_[0];} |
2306
|
|
|
|
|
|
|
|
2307
|
0
|
|
|
|
|
|
return($_str); |
2308
|
|
|
|
|
|
|
} |
2309
|
|
|
|
|
|
|
# |
2310
|
|
|
|
|
|
|
#............................................................................. |
2311
|
|
|
|
|
|
|
# |
2312
|
|
|
|
|
|
|
# function to normalize severity string |
2313
|
|
|
|
|
|
|
# |
2314
|
|
|
|
|
|
|
sub normalize_severity { |
2315
|
|
|
|
|
|
|
|
2316
|
0
|
|
|
0
|
1
|
|
my $_str = ''; |
2317
|
|
|
|
|
|
|
|
2318
|
0
|
0
|
|
|
|
|
if ($_[0] =~ /emerg/i) {$_str = 'emerg'} |
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2319
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /alert/i) {$_str = 'alert'} |
2320
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /crit/i) {$_str = 'crit'} |
2321
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /err/i) {$_str = 'err'} |
2322
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /warn/i) {$_str = 'warn'} |
2323
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /notice/i) {$_str = 'notice'} |
2324
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /info/i) {$_str = 'info'} |
2325
|
0
|
|
|
|
|
|
elsif ($_[0] =~ /debug/i) {$_str = 'debug'} |
2326
|
|
|
|
|
|
|
else {$_str = $_[0];} |
2327
|
|
|
|
|
|
|
|
2328
|
0
|
|
|
|
|
|
return($_str); |
2329
|
|
|
|
|
|
|
|
2330
|
|
|
|
|
|
|
} |
2331
|
|
|
|
|
|
|
|
2332
|
|
|
|
|
|
|
# |
2333
|
|
|
|
|
|
|
#............................................................................. |
2334
|
|
|
|
|
|
|
# |
2335
|
|
|
|
|
|
|
# |
2336
|
|
|
|
|
|
|
sub log_debug { |
2337
|
|
|
|
|
|
|
|
2338
|
0
|
|
|
0
|
0
|
|
my $_level = shift; |
2339
|
0
|
|
|
|
|
|
my $_format = shift; |
2340
|
|
|
|
|
|
|
|
2341
|
|
|
|
|
|
|
|
2342
|
0
|
0
|
|
|
|
|
if ($_level <= $DEBUG) { |
2343
|
0
|
|
|
|
|
|
printf("debug: %s: $_format", (caller(1))[3], @_); |
2344
|
|
|
|
|
|
|
} |
2345
|
|
|
|
|
|
|
|
2346
|
0
|
|
|
|
|
|
1; |
2347
|
|
|
|
|
|
|
} |
2348
|
|
|
|
|
|
|
# |
2349
|
|
|
|
|
|
|
#............................................................................. |
2350
|
|
|
|
|
|
|
# |
2351
|
|
|
|
|
|
|
# function to set $YEAR |
2352
|
|
|
|
|
|
|
# |
2353
|
|
|
|
|
|
|
# call |
2354
|
|
|
|
|
|
|
# $_obj->set_year(1988); |
2355
|
|
|
|
|
|
|
# |
2356
|
|
|
|
|
|
|
# Arg |
2357
|
|
|
|
|
|
|
# $_[0] = class |
2358
|
|
|
|
|
|
|
# $_[1] = year to set to, else set to current year |
2359
|
|
|
|
|
|
|
# |
2360
|
|
|
|
|
|
|
# Return |
2361
|
|
|
|
|
|
|
# $YEAR |
2362
|
|
|
|
|
|
|
# |
2363
|
|
|
|
|
|
|
# |
2364
|
|
|
|
|
|
|
sub set_year { |
2365
|
0
|
|
|
0
|
1
|
|
my $_class = shift; |
2366
|
0
|
|
0
|
|
|
|
$YEAR = shift || ((localtime)[5]) + 1900; |
2367
|
0
|
|
|
|
|
|
$YEAR; |
2368
|
|
|
|
|
|
|
} |
2369
|
|
|
|
|
|
|
|
2370
|
|
|
|
|
|
|
# |
2371
|
|
|
|
|
|
|
#............................................................................. |
2372
|
|
|
|
|
|
|
# |
2373
|
|
|
|
|
|
|
# functions to return references to data structures |
2374
|
|
|
|
|
|
|
# |
2375
|
0
|
|
|
0
|
1
|
|
sub syslog_stats_href { return(\%STATS); } |
2376
|
0
|
|
|
0
|
1
|
|
sub syslog_device_aref { return(\@DEVICES); } |
2377
|
0
|
|
|
0
|
1
|
|
sub syslog_facility_aref { return(\@FACILITY); } |
2378
|
0
|
|
|
0
|
1
|
|
sub syslog_severity_aref { return(\@SEVERITY); } |
2379
|
0
|
|
|
0
|
1
|
|
sub syslog_tag_aref { return(\@TAGS); } |
2380
|
0
|
|
|
0
|
0
|
|
sub syslog_timeslot_aref { return(\@TIMESLOTS); } |
2381
|
0
|
|
|
0
|
1
|
|
sub syslog_error_count { $ERROR_count; } |
2382
|
0
|
|
|
0
|
1
|
|
sub syslog_filter_count { $FILTER_count; } |
2383
|
0
|
|
|
0
|
1
|
|
sub syslog_parse_count { $PARSE_count; } |
2384
|
|
|
|
|
|
|
|
2385
|
0
|
|
|
0
|
1
|
|
sub syslog_error {return($ERROR);} |
2386
|
|
|
|
|
|
|
|
2387
|
|
|
|
|
|
|
|
2388
|
|
|
|
|
|
|
|
2389
|
|
|
|
|
|
|
# |
2390
|
|
|
|
|
|
|
#............................................................................. |
2391
|
|
|
|
|
|
|
# |
2392
|
|
|
|
|
|
|
# from perl cookbook to put comma's in integer |
2393
|
|
|
|
|
|
|
sub _commify { |
2394
|
0
|
|
|
0
|
|
|
my $text = reverse $_[0]; |
2395
|
0
|
|
|
|
|
|
$text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g; |
2396
|
0
|
|
|
|
|
|
return scalar reverse $text; |
2397
|
|
|
|
|
|
|
} |
2398
|
|
|
|
|
|
|
|
2399
|
|
|
|
|
|
|
|
2400
|
|
|
|
|
|
|
1; # end package Syslog |
2401
|
|
|
|
|
|
|
|
2402
|
|
|
|
|
|
|
|
2403
|
|
|
|
|
|
|
#============================================================================= |
2404
|
|
|
|
|
|
|
# |
2405
|
|
|
|
|
|
|
# POD |
2406
|
|
|
|
|
|
|
# |
2407
|
|
|
|
|
|
|
#============================================================================= |
2408
|
|
|
|
|
|
|
|
2409
|
|
|
|
|
|
|
=pod |
2410
|
|
|
|
|
|
|
|
2411
|
|
|
|
|
|
|
=head1 NAME |
2412
|
|
|
|
|
|
|
|
2413
|
|
|
|
|
|
|
Net::Dev::Tools::Syslog - Send, Listen Parse Syslog messages. |
2414
|
|
|
|
|
|
|
|
2415
|
|
|
|
|
|
|
=head1 VERSION |
2416
|
|
|
|
|
|
|
|
2417
|
|
|
|
|
|
|
Syslog 1.0.0 |
2418
|
|
|
|
|
|
|
|
2419
|
|
|
|
|
|
|
=head1 SYNOPSIS |
2420
|
|
|
|
|
|
|
|
2421
|
|
|
|
|
|
|
use Syslog; |
2422
|
|
|
|
|
|
|
|
2423
|
|
|
|
|
|
|
# |
2424
|
|
|
|
|
|
|
# Syslog Parser |
2425
|
|
|
|
|
|
|
# |
2426
|
|
|
|
|
|
|
($syslog, $error) = Syslog->parse( |
2427
|
|
|
|
|
|
|
-dump => , |
2428
|
|
|
|
|
|
|
-append => <0|1>, |
2429
|
|
|
|
|
|
|
-ext => , |
2430
|
|
|
|
|
|
|
-report => <0|1>, |
2431
|
|
|
|
|
|
|
-interval => , |
2432
|
|
|
|
|
|
|
-debug => <0|1|2|3>, |
2433
|
|
|
|
|
|
|
-rx_time => <0|1>, |
2434
|
|
|
|
|
|
|
-lastmsg => <0|1>, |
2435
|
|
|
|
|
|
|
-min_date => , |
2436
|
|
|
|
|
|
|
-max_date => , |
2437
|
|
|
|
|
|
|
-device => , |
2438
|
|
|
|
|
|
|
-tag => , |
2439
|
|
|
|
|
|
|
-message => , |
2440
|
|
|
|
|
|
|
-format => |
2441
|
|
|
|
|
|
|
-moreTime => <0|1> |
2442
|
|
|
|
|
|
|
-parseTag => <0|1> |
2443
|
|
|
|
|
|
|
); |
2444
|
|
|
|
|
|
|
|
2445
|
|
|
|
|
|
|
$parse = $syslog->parse_syslog_line(); |
2446
|
|
|
|
|
|
|
|
2447
|
|
|
|
|
|
|
# |
2448
|
|
|
|
|
|
|
# Syslog Send |
2449
|
|
|
|
|
|
|
# |
2450
|
|
|
|
|
|
|
($send, $error) = Syslog->send( |
2451
|
|
|
|
|
|
|
-server => , |
2452
|
|
|
|
|
|
|
-port => , |
2453
|
|
|
|
|
|
|
-proto => , |
2454
|
|
|
|
|
|
|
-facility => , |
2455
|
|
|
|
|
|
|
-severity => , |
2456
|
|
|
|
|
|
|
-timestamp => , |
2457
|
|
|
|
|
|
|
-device => , |
2458
|
|
|
|
|
|
|
-tag => , |
2459
|
|
|
|
|
|
|
-pid => , |
2460
|
|
|
|
|
|
|
-message => , |
2461
|
|
|
|
|
|
|
-strict => <0|1>, |
2462
|
|
|
|
|
|
|
); |
2463
|
|
|
|
|
|
|
|
2464
|
|
|
|
|
|
|
$send->send_message( |
2465
|
|
|
|
|
|
|
-server => , |
2466
|
|
|
|
|
|
|
-port => , |
2467
|
|
|
|
|
|
|
-proto => , |
2468
|
|
|
|
|
|
|
-facility => , |
2469
|
|
|
|
|
|
|
-severity => , |
2470
|
|
|
|
|
|
|
-timestamp => , |
2471
|
|
|
|
|
|
|
-device => , |
2472
|
|
|
|
|
|
|
-tag => , |
2473
|
|
|
|
|
|
|
-pid => , |
2474
|
|
|
|
|
|
|
-message => , |
2475
|
|
|
|
|
|
|
-strict => <0|1>, |
2476
|
|
|
|
|
|
|
); |
2477
|
|
|
|
|
|
|
|
2478
|
|
|
|
|
|
|
# |
2479
|
|
|
|
|
|
|
# Syslog Listen |
2480
|
|
|
|
|
|
|
# |
2481
|
|
|
|
|
|
|
($listen, $error) = Syslog->listen( |
2482
|
|
|
|
|
|
|
-port => , |
2483
|
|
|
|
|
|
|
-proto => , |
2484
|
|
|
|
|
|
|
-maxlength => |
2485
|
|
|
|
|
|
|
-verbose => <0|1|2|3>, |
2486
|
|
|
|
|
|
|
-fwd_server => , |
2487
|
|
|
|
|
|
|
-fwd_port => , |
2488
|
|
|
|
|
|
|
-fwd_proto => , |
2489
|
|
|
|
|
|
|
); |
2490
|
|
|
|
|
|
|
|
2491
|
|
|
|
|
|
|
|
2492
|
|
|
|
|
|
|
=head1 DESCRIPTION |
2493
|
|
|
|
|
|
|
|
2494
|
|
|
|
|
|
|
Module provides methods to parse syslog files, send syslog messages to |
2495
|
|
|
|
|
|
|
syslog server, listen for syslog message on localhost. |
2496
|
|
|
|
|
|
|
|
2497
|
|
|
|
|
|
|
=over 4 |
2498
|
|
|
|
|
|
|
|
2499
|
|
|
|
|
|
|
=item Parser |
2500
|
|
|
|
|
|
|
|
2501
|
|
|
|
|
|
|
parse method creates a class that configures the parser used |
2502
|
|
|
|
|
|
|
on each syslog file entry (line) sent to the parser. |
2503
|
|
|
|
|
|
|
The object is first created with properties that define how |
2504
|
|
|
|
|
|
|
a syslog line is to be worked on. The parse_syslog_line function |
2505
|
|
|
|
|
|
|
(method) is then used to parse the syslog line and return a |
2506
|
|
|
|
|
|
|
reference to a hash. |
2507
|
|
|
|
|
|
|
|
2508
|
|
|
|
|
|
|
=item Send |
2509
|
|
|
|
|
|
|
|
2510
|
|
|
|
|
|
|
send method will send a syslog message to a syslog sever. The user |
2511
|
|
|
|
|
|
|
can provide as much or as little information desired. The class |
2512
|
|
|
|
|
|
|
will then create a syslog message from the information given |
2513
|
|
|
|
|
|
|
or from default values and send the message to the desired server. |
2514
|
|
|
|
|
|
|
|
2515
|
|
|
|
|
|
|
=item Listen |
2516
|
|
|
|
|
|
|
|
2517
|
|
|
|
|
|
|
listen will open the desired port on the local host to listen |
2518
|
|
|
|
|
|
|
for sylog messages. Message received on the port are assumed to |
2519
|
|
|
|
|
|
|
be syslog messages and are printed to STDOUT. Messages can also |
2520
|
|
|
|
|
|
|
be forwarded 'as received' to another address. The functionality |
2521
|
|
|
|
|
|
|
of the parser can also be used when in this mode. |
2522
|
|
|
|
|
|
|
|
2523
|
|
|
|
|
|
|
=back |
2524
|
|
|
|
|
|
|
|
2525
|
|
|
|
|
|
|
See documentation for individual function/methods for more detail |
2526
|
|
|
|
|
|
|
on usage and operation. |
2527
|
|
|
|
|
|
|
|
2528
|
|
|
|
|
|
|
|
2529
|
|
|
|
|
|
|
=head1 REQUIRES |
2530
|
|
|
|
|
|
|
|
2531
|
|
|
|
|
|
|
Time::Local used to convert TIMESTAMP to epoch |
2532
|
|
|
|
|
|
|
IO::Socket used by send and listen methods |
2533
|
|
|
|
|
|
|
Sys::Hostname used to support DNS |
2534
|
|
|
|
|
|
|
|
2535
|
|
|
|
|
|
|
=head1 EXPORTS |
2536
|
|
|
|
|
|
|
|
2537
|
|
|
|
|
|
|
parse_syslog_msg |
2538
|
|
|
|
|
|
|
epoch_to_syslog_timestamp |
2539
|
|
|
|
|
|
|
make_timeslots |
2540
|
|
|
|
|
|
|
epoch_timeslot_index |
2541
|
|
|
|
|
|
|
normalize_facility |
2542
|
|
|
|
|
|
|
normalize_severity |
2543
|
|
|
|
|
|
|
|
2544
|
|
|
|
|
|
|
=head1 EXPORT TAGS |
2545
|
|
|
|
|
|
|
|
2546
|
|
|
|
|
|
|
:parser parse_syslog_msg |
2547
|
|
|
|
|
|
|
:time epoch_to_syslog_timestamp, make_timeslots, epoch_timeslot_index |
2548
|
|
|
|
|
|
|
:syslog normalize_facility, normalize_severity |
2549
|
|
|
|
|
|
|
|
2550
|
|
|
|
|
|
|
|
2551
|
|
|
|
|
|
|
=head1 Parser Methods and Functions |
2552
|
|
|
|
|
|
|
|
2553
|
|
|
|
|
|
|
=head2 parse |
2554
|
|
|
|
|
|
|
|
2555
|
|
|
|
|
|
|
Constructor to create an object to parse the lines of a syslog file. |
2556
|
|
|
|
|
|
|
Arguments are used to define parsing. See function parse_syslog_line |
2557
|
|
|
|
|
|
|
section to see how to parse the line. |
2558
|
|
|
|
|
|
|
|
2559
|
|
|
|
|
|
|
($syslog, $error) = Syslog->parse( |
2560
|
|
|
|
|
|
|
-dump => , |
2561
|
|
|
|
|
|
|
-append => <0|1>, |
2562
|
|
|
|
|
|
|
-ext => , |
2563
|
|
|
|
|
|
|
-report => <0|1>, |
2564
|
|
|
|
|
|
|
-interval => , |
2565
|
|
|
|
|
|
|
-debug => <0|1|2|3>, |
2566
|
|
|
|
|
|
|
-rx_time => <0|1>, |
2567
|
|
|
|
|
|
|
-lastmsg => <0|1>, |
2568
|
|
|
|
|
|
|
-min_date => , |
2569
|
|
|
|
|
|
|
-max_date => , |
2570
|
|
|
|
|
|
|
-device => , |
2571
|
|
|
|
|
|
|
-tag => , |
2572
|
|
|
|
|
|
|
-message => , |
2573
|
|
|
|
|
|
|
-format => , |
2574
|
|
|
|
|
|
|
-moreTime => <0|1>, |
2575
|
|
|
|
|
|
|
-parseTag => <0|1>, |
2576
|
|
|
|
|
|
|
); |
2577
|
|
|
|
|
|
|
|
2578
|
|
|
|
|
|
|
|
2579
|
|
|
|
|
|
|
Argument Checks: |
2580
|
|
|
|
|
|
|
|
2581
|
|
|
|
|
|
|
If -dump is used, then argument must be a directory, current |
2582
|
|
|
|
|
|
|
directory is not assumed. The directory provided must exist and |
2583
|
|
|
|
|
|
|
allow user write access. |
2584
|
|
|
|
|
|
|
|
2585
|
|
|
|
|
|
|
If -interval is less than 60, it is set to 60. |
2586
|
|
|
|
|
|
|
|
2587
|
|
|
|
|
|
|
If -min_date and/or -max_date are given the syntax and range are checked. |
2588
|
|
|
|
|
|
|
|
2589
|
|
|
|
|
|
|
|
2590
|
|
|
|
|
|
|
Return, in list context will return reference to object and error. |
2591
|
|
|
|
|
|
|
In scalar context returns reference to object. If object fails to create, |
2592
|
|
|
|
|
|
|
then the reference is undef. |
2593
|
|
|
|
|
|
|
|
2594
|
|
|
|
|
|
|
=over 4 |
2595
|
|
|
|
|
|
|
|
2596
|
|
|
|
|
|
|
=item -dump |
2597
|
|
|
|
|
|
|
|
2598
|
|
|
|
|
|
|
Enable creation of separate syslog files. Each file created will only |
2599
|
|
|
|
|
|
|
contain lines for the device defined in the syslog message HOSTNAME. |
2600
|
|
|
|
|
|
|
The argument defines a directory to where device specific |
2601
|
|
|
|
|
|
|
syslog files are dumped. Current directory is not assumed. |
2602
|
|
|
|
|
|
|
Directories are checked for existence and writability. |
2603
|
|
|
|
|
|
|
|
2604
|
|
|
|
|
|
|
Default = FALSE, no dumps |
2605
|
|
|
|
|
|
|
|
2606
|
|
|
|
|
|
|
=item -append <0|1> |
2607
|
|
|
|
|
|
|
|
2608
|
|
|
|
|
|
|
If 0, device files created due to -dump are overwritten. |
2609
|
|
|
|
|
|
|
If 1, device files created due to -dump are appended to. |
2610
|
|
|
|
|
|
|
Default = 0, (overwrite) |
2611
|
|
|
|
|
|
|
|
2612
|
|
|
|
|
|
|
=item -ext |
2613
|
|
|
|
|
|
|
|
2614
|
|
|
|
|
|
|
File extension to use for device files created due to -dump |
2615
|
|
|
|
|
|
|
being enabled. |
2616
|
|
|
|
|
|
|
Default = 'slp', (SysLog Parsed) |
2617
|
|
|
|
|
|
|
|
2618
|
|
|
|
|
|
|
=item -report <0|1> |
2619
|
|
|
|
|
|
|
|
2620
|
|
|
|
|
|
|
If 0 no stats are recorded. |
2621
|
|
|
|
|
|
|
If 1 stats are extracted. For each line successfully parsed, information |
2622
|
|
|
|
|
|
|
is stored in a hash. This hash can be referenced with the function |
2623
|
|
|
|
|
|
|
syslog_stats_href. |
2624
|
|
|
|
|
|
|
|
2625
|
|
|
|
|
|
|
=item -interval |
2626
|
|
|
|
|
|
|
|
2627
|
|
|
|
|
|
|
The amount of seconds to use when making timeslots. |
2628
|
|
|
|
|
|
|
make_timeslots function will make timeslot ranging from |
2629
|
|
|
|
|
|
|
min and max time found or given. The timeslot info can then |
2630
|
|
|
|
|
|
|
be used to create stats for desired time intervals. |
2631
|
|
|
|
|
|
|
See @TIMESLOTS for more info. |
2632
|
|
|
|
|
|
|
Min value is 60 (1 minute). |
2633
|
|
|
|
|
|
|
Default is 3600 (1 hour). |
2634
|
|
|
|
|
|
|
|
2635
|
|
|
|
|
|
|
=item -debug <0|1|2|3> |
2636
|
|
|
|
|
|
|
|
2637
|
|
|
|
|
|
|
Set debug level, verbosity increases as number value increases. |
2638
|
|
|
|
|
|
|
|
2639
|
|
|
|
|
|
|
|
2640
|
|
|
|
|
|
|
=item -rx_time <0|1> |
2641
|
|
|
|
|
|
|
|
2642
|
|
|
|
|
|
|
Set flag to use the localhost receive time and not the timestamp from the |
2643
|
|
|
|
|
|
|
sylog message. Some syslog deamon prepend information to the syslog |
2644
|
|
|
|
|
|
|
message when writing to a file. If a receive time is one of these |
2645
|
|
|
|
|
|
|
fields, then it can be used. This will normalize all times to when |
2646
|
|
|
|
|
|
|
they are received by the serever. |
2647
|
|
|
|
|
|
|
Default is 0 |
2648
|
|
|
|
|
|
|
|
2649
|
|
|
|
|
|
|
=item -lastmsg <0|1> |
2650
|
|
|
|
|
|
|
|
2651
|
|
|
|
|
|
|
Set flag to to handle last message as previous message. |
2652
|
|
|
|
|
|
|
If true and the syslog message has the pattern |
2653
|
|
|
|
|
|
|
'last message repeated time',then we replace this current |
2654
|
|
|
|
|
|
|
line with the previous line. Otherwise the 'last message' line |
2655
|
|
|
|
|
|
|
is treated as all other syslog lines. The tag will be defined as |
2656
|
|
|
|
|
|
|
'lastmsg', pid and content set to ''. |
2657
|
|
|
|
|
|
|
Default is 0. |
2658
|
|
|
|
|
|
|
|
2659
|
|
|
|
|
|
|
|
2660
|
|
|
|
|
|
|
=item -min_date |
2661
|
|
|
|
|
|
|
|
2662
|
|
|
|
|
|
|
If given, then will be used to filter dates. Only lines with dates |
2663
|
|
|
|
|
|
|
greater to or equal to this will be be parsed. This check is performed |
2664
|
|
|
|
|
|
|
after -rx_time, thus filter applies to whatever date you decide to keep. |
2665
|
|
|
|
|
|
|
|
2666
|
|
|
|
|
|
|
You must enter mm/dd/yyyy, other values will default: |
2667
|
|
|
|
|
|
|
ss defaults to 0 if hh:mm given, 59 if no time given |
2668
|
|
|
|
|
|
|
mm defaults to 0 if hh: given, 59 if no time given |
2669
|
|
|
|
|
|
|
hh defaults to 23 if no time given |
2670
|
|
|
|
|
|
|
|
2671
|
|
|
|
|
|
|
Mmm/dd/yyyy can also be use, where Mmm is Jan, Feb, Mar,... |
2672
|
|
|
|
|
|
|
|
2673
|
|
|
|
|
|
|
|
2674
|
|
|
|
|
|
|
=item -max_date |
2675
|
|
|
|
|
|
|
|
2676
|
|
|
|
|
|
|
If given, then will be used to filter dates. Only lines with dates |
2677
|
|
|
|
|
|
|
less than or equal to this will be be parsed. This check is performed |
2678
|
|
|
|
|
|
|
after -rx_time, thus filter applies to whatever date you decide to keep. |
2679
|
|
|
|
|
|
|
|
2680
|
|
|
|
|
|
|
Apply same syntax rules as -min_date |
2681
|
|
|
|
|
|
|
|
2682
|
|
|
|
|
|
|
=item -device |
2683
|
|
|
|
|
|
|
|
2684
|
|
|
|
|
|
|
If given, only device fields matching the pattern are kept. Text strings |
2685
|
|
|
|
|
|
|
or Perl regexp can be given. |
2686
|
|
|
|
|
|
|
|
2687
|
|
|
|
|
|
|
|
2688
|
|
|
|
|
|
|
=item -tag |
2689
|
|
|
|
|
|
|
|
2690
|
|
|
|
|
|
|
If given, only tag fields matching the pattern are kept. Text strings |
2691
|
|
|
|
|
|
|
or Perl regexp can be given. |
2692
|
|
|
|
|
|
|
|
2693
|
|
|
|
|
|
|
=item -message |
2694
|
|
|
|
|
|
|
|
2695
|
|
|
|
|
|
|
If given, only message fields matching the pattern are kept. Text strings |
2696
|
|
|
|
|
|
|
or Perl regexp can be given. |
2697
|
|
|
|
|
|
|
|
2698
|
|
|
|
|
|
|
=item -format |
2699
|
|
|
|
|
|
|
|
2700
|
|
|
|
|
|
|
Defines how $SYSLOG_pattern is constructed to use match the syslog line |
2701
|
|
|
|
|
|
|
against to parse out the component parts. |
2702
|
|
|
|
|
|
|
bsd will use $TIMESTAMP, $HOSTNAME, $MESSAGE. |
2703
|
|
|
|
|
|
|
noHost will use $TIMESTAMP, $MESSAGE. |
2704
|
|
|
|
|
|
|
self will use $SYSLOG_pattern as defined by the user, by default |
2705
|
|
|
|
|
|
|
$SYSLOG_pattern is defined same as bsd |
2706
|
|
|
|
|
|
|
|
2707
|
|
|
|
|
|
|
=item -moreTime <0|1> |
2708
|
|
|
|
|
|
|
|
2709
|
|
|
|
|
|
|
If defined, derive more time information from the timestamp. This will |
2710
|
|
|
|
|
|
|
convert time strings to epoch second using localtime function. This |
2711
|
|
|
|
|
|
|
will slow down processing. This will be enabled if needed, such as when |
2712
|
|
|
|
|
|
|
-min_date, -max_date, -report are used. |
2713
|
|
|
|
|
|
|
|
2714
|
|
|
|
|
|
|
=item -parseTag <0|1> |
2715
|
|
|
|
|
|
|
|
2716
|
|
|
|
|
|
|
If enabled, will parse TAGs from Syslog Message. TAG syntax varys greatly |
2717
|
|
|
|
|
|
|
from different devices/vendors. This module tries to parse out the common |
2718
|
|
|
|
|
|
|
style but realizes it can not assume a common syntax so the user is allowed |
2719
|
|
|
|
|
|
|
to define their own. See the Data Access section on TAGs for more information. |
2720
|
|
|
|
|
|
|
|
2721
|
|
|
|
|
|
|
Common style is considered to be: foo[123]: |
2722
|
|
|
|
|
|
|
|
2723
|
|
|
|
|
|
|
=back |
2724
|
|
|
|
|
|
|
|
2725
|
|
|
|
|
|
|
|
2726
|
|
|
|
|
|
|
=head2 parse_syslog_line |
2727
|
|
|
|
|
|
|
|
2728
|
|
|
|
|
|
|
($parse, $error) = $syslog->parse_syslog_line(); |
2729
|
|
|
|
|
|
|
|
2730
|
|
|
|
|
|
|
Method to parse the syslog line. If syslog line is not given |
2731
|
|
|
|
|
|
|
as argument then $_ is parsed. |
2732
|
|
|
|
|
|
|
|
2733
|
|
|
|
|
|
|
The pattern used to parse the given line is a pattern made by the strings |
2734
|
|
|
|
|
|
|
defined by $TIMESTAMP,$HOSTNAME,$MESSAGE. If -format is bsd, then |
2735
|
|
|
|
|
|
|
$TIMESTAMP,$HOSTNAME,$MESSAGE are used to make the pattern. If -format |
2736
|
|
|
|
|
|
|
is noHost, then $TIMESTAMP, $MESSAGE are used to make the pattern. These |
2737
|
|
|
|
|
|
|
strings are used to make $SYSLOG_pattern |
2738
|
|
|
|
|
|
|
|
2739
|
|
|
|
|
|
|
Some syslog daemons may prepend other information when writing |
2740
|
|
|
|
|
|
|
syslog message to syslog file. parse_syslog_line will try to detect this |
2741
|
|
|
|
|
|
|
by applying a regexp match for an RFC 3164 syslog message to |
2742
|
|
|
|
|
|
|
$SYSLOG_pattern. The match will be treated as the syslog message, any string |
2743
|
|
|
|
|
|
|
found before the match will be considered a preamble. The preamble will be |
2744
|
|
|
|
|
|
|
parsed for receive time, syslog priority (facility.severity) and |
2745
|
|
|
|
|
|
|
source IP address. This info is extracted and made avaliable to the user. |
2746
|
|
|
|
|
|
|
|
2747
|
|
|
|
|
|
|
parse_syslog_line calls parse_syslog_msg to parse respective information. |
2748
|
|
|
|
|
|
|
The string given to parse_syslog_msg is the string matched by |
2749
|
|
|
|
|
|
|
$SYSLOG_pattern. Any facility or severity parsed is normalized to |
2750
|
|
|
|
|
|
|
the strings listed in @FACILITY and @SEVERITY. |
2751
|
|
|
|
|
|
|
|
2752
|
|
|
|
|
|
|
Syslog messages are the strings matched by $SYSLOG_pattern. Changing |
2753
|
|
|
|
|
|
|
this string to something else allows the user to modify the parser. |
2754
|
|
|
|
|
|
|
|
2755
|
|
|
|
|
|
|
The information parsed from the line given to parse_syslog_line is then |
2756
|
|
|
|
|
|
|
checked against any filters. |
2757
|
|
|
|
|
|
|
|
2758
|
|
|
|
|
|
|
If the filtering determines we keep the line the function checks if the |
2759
|
|
|
|
|
|
|
-dump or -report options are enabled and performs the required task. |
2760
|
|
|
|
|
|
|
|
2761
|
|
|
|
|
|
|
|
2762
|
|
|
|
|
|
|
See Data Access Section for hash structure made by parse_syslog_line. |
2763
|
|
|
|
|
|
|
Each call to this function clears the previous information stored. |
2764
|
|
|
|
|
|
|
|
2765
|
|
|
|
|
|
|
The user has external control over the parser through the global variables |
2766
|
|
|
|
|
|
|
$TIMESTAMP,$HOSTNAME,$MESSAGE, $SYSLOG_pattern. See the Data Access Section |
2767
|
|
|
|
|
|
|
for requirements of these strings. |
2768
|
|
|
|
|
|
|
|
2769
|
|
|
|
|
|
|
|
2770
|
|
|
|
|
|
|
In list context a reference to a hash and error are returned. |
2771
|
|
|
|
|
|
|
In scalar context, a reference to a hash is returned. |
2772
|
|
|
|
|
|
|
|
2773
|
|
|
|
|
|
|
Events to Return Error: |
2774
|
|
|
|
|
|
|
|
2775
|
|
|
|
|
|
|
=over |
2776
|
|
|
|
|
|
|
|
2777
|
|
|
|
|
|
|
=item blank line |
2778
|
|
|
|
|
|
|
|
2779
|
|
|
|
|
|
|
=item outside of date range, if date filters are applied |
2780
|
|
|
|
|
|
|
|
2781
|
|
|
|
|
|
|
=item no date parsed and date filters are applied |
2782
|
|
|
|
|
|
|
|
2783
|
|
|
|
|
|
|
=item unable to dump line to file, if -dump option true |
2784
|
|
|
|
|
|
|
|
2785
|
|
|
|
|
|
|
=back |
2786
|
|
|
|
|
|
|
|
2787
|
|
|
|
|
|
|
|
2788
|
|
|
|
|
|
|
=head2 parse_syslog_msg |
2789
|
|
|
|
|
|
|
|
2790
|
|
|
|
|
|
|
@fields = parse_syslog_msg($msg, [$moreTime, $parseTag, <0|1>]); |
2791
|
|
|
|
|
|
|
|
2792
|
|
|
|
|
|
|
$fields[0] = timestamp portion of syslog message |
2793
|
|
|
|
|
|
|
|
2794
|
|
|
|
|
|
|
$fields[1] = hostname portion of syslog message |
2795
|
|
|
|
|
|
|
|
2796
|
|
|
|
|
|
|
$fields[2] = message portion of syslog message |
2797
|
|
|
|
|
|
|
|
2798
|
|
|
|
|
|
|
$fields[3] = error string |
2799
|
|
|
|
|
|
|
|
2800
|
|
|
|
|
|
|
|
2801
|
|
|
|
|
|
|
This function can be used externally as a function call. |
2802
|
|
|
|
|
|
|
When called internally by parse_syslog_line the 4th argument is set |
2803
|
|
|
|
|
|
|
to 1 and the function populates the respective data structure. If called |
2804
|
|
|
|
|
|
|
externally, then will return in list context (timestamp, device, |
2805
|
|
|
|
|
|
|
message, error) or in scalar context a reference to a hash whose keys |
2806
|
|
|
|
|
|
|
are 'timestamp', 'device', 'message'. If an error occurs then everthing |
2807
|
|
|
|
|
|
|
is undef and the error is a string detailing the error. |
2808
|
|
|
|
|
|
|
|
2809
|
|
|
|
|
|
|
|
2810
|
|
|
|
|
|
|
The given line is pattern matched against $SYSLOG_pattern and the |
2811
|
|
|
|
|
|
|
information is gather from the $1, $2, $3, ... placeholders. |
2812
|
|
|
|
|
|
|
See Data Access for syntax if defining your own $TIMESTAMP,$HOSTNAME,$MESSAGE, |
2813
|
|
|
|
|
|
|
$SYSLOG_pattern strings. |
2814
|
|
|
|
|
|
|
|
2815
|
|
|
|
|
|
|
If the -moreTime argument is true (non zero) then the $TIMESTAMP is picked |
2816
|
|
|
|
|
|
|
apart for more information. This would be the -moreTime argument to |
2817
|
|
|
|
|
|
|
parse_syslog_line when doing OOP, otherwise user must define on a user call. |
2818
|
|
|
|
|
|
|
|
2819
|
|
|
|
|
|
|
If the -parseTag argument is true (non zero) then the parse_tag function |
2820
|
|
|
|
|
|
|
attempts to parse a TAG. This would be the -parseTag argument to |
2821
|
|
|
|
|
|
|
parse_syslog_line when doing OOP, otherwise user must define on a user call. |
2822
|
|
|
|
|
|
|
|
2823
|
|
|
|
|
|
|
See Data Access section, Syslog Line Hash Reference for the syntax of the hash |
2824
|
|
|
|
|
|
|
populated with the information parsed with parse_syslog_msg. |
2825
|
|
|
|
|
|
|
|
2826
|
|
|
|
|
|
|
|
2827
|
|
|
|
|
|
|
=head2 parse_tag |
2828
|
|
|
|
|
|
|
|
2829
|
|
|
|
|
|
|
($tag, $pid, $content) = parse_tag(); |
2830
|
|
|
|
|
|
|
|
2831
|
|
|
|
|
|
|
This function will parse TAG and PID from the given string and return the |
2832
|
|
|
|
|
|
|
TAG and PID and CONTENT. If the user defines $TAG_1 or $TAG_2 or $TAG_3, |
2833
|
|
|
|
|
|
|
then those patterns are used to match. See Data Access for syntax of $TAG_x. |
2834
|
|
|
|
|
|
|
Otherwise will look at beginning of the string for the common practice of |
2835
|
|
|
|
|
|
|
some text string and pid, such as foo[1234]: content. The given string |
2836
|
|
|
|
|
|
|
is assumed to be the MESSAGE portion of the syslog message, the MESSAGE |
2837
|
|
|
|
|
|
|
portion can be made of TAG and CONTENT fields. The MESSAGE portion follows |
2838
|
|
|
|
|
|
|
the HEADER which consist of TIMESTAMP and HOSTNAME, hostname field mandatory. |
2839
|
|
|
|
|
|
|
|
2840
|
|
|
|
|
|
|
When used by the object, hash key/value entries are populated for the |
2841
|
|
|
|
|
|
|
syslog line, see Data Access section. When used as a standalone function |
2842
|
|
|
|
|
|
|
then TAG, PID and CONTENT fields are returned in list context. |
2843
|
|
|
|
|
|
|
|
2844
|
|
|
|
|
|
|
|
2845
|
|
|
|
|
|
|
=head2 parse_preamble |
2846
|
|
|
|
|
|
|
|
2847
|
|
|
|
|
|
|
This function is not external but is described since debugging will |
2848
|
|
|
|
|
|
|
indicate this function. |
2849
|
|
|
|
|
|
|
|
2850
|
|
|
|
|
|
|
|
2851
|
|
|
|
|
|
|
($epoch, $date, $facility, $severity, $srcIP) = parse_preamble($preamble); |
2852
|
|
|
|
|
|
|
|
2853
|
|
|
|
|
|
|
Some syslog daemon will prepend information to the RFC3164 format. This |
2854
|
|
|
|
|
|
|
information is: |
2855
|
|
|
|
|
|
|
|
2856
|
|
|
|
|
|
|
=over |
2857
|
|
|
|
|
|
|
|
2858
|
|
|
|
|
|
|
=item local sytem time when the message was received |
2859
|
|
|
|
|
|
|
|
2860
|
|
|
|
|
|
|
=item the facility and severity, derived from PRI |
2861
|
|
|
|
|
|
|
|
2862
|
|
|
|
|
|
|
=item the source IP address |
2863
|
|
|
|
|
|
|
|
2864
|
|
|
|
|
|
|
=back |
2865
|
|
|
|
|
|
|
|
2866
|
|
|
|
|
|
|
When used by the object, hash key/value entries are populated for the |
2867
|
|
|
|
|
|
|
syslog line, see Data Access section. |
2868
|
|
|
|
|
|
|
|
2869
|
|
|
|
|
|
|
|
2870
|
|
|
|
|
|
|
This function will attempt to parse this information out and return in |
2871
|
|
|
|
|
|
|
list context, the receive time in epoch seconds, the local receive time, |
2872
|
|
|
|
|
|
|
the syslog message facility, the syslog message severity, the source IP |
2873
|
|
|
|
|
|
|
address. Date information is assumed to be delimited with dash '-', |
2874
|
|
|
|
|
|
|
time information is delimited with ':'. Since the syntax of this information |
2875
|
|
|
|
|
|
|
is unique, any one of the fields are parsed for, thus they can be in any order |
2876
|
|
|
|
|
|
|
in the preamble. |
2877
|
|
|
|
|
|
|
|
2878
|
|
|
|
|
|
|
|
2879
|
|
|
|
|
|
|
=head1 Send Methods and Functions |
2880
|
|
|
|
|
|
|
|
2881
|
|
|
|
|
|
|
=head2 send |
2882
|
|
|
|
|
|
|
|
2883
|
|
|
|
|
|
|
Constructor to create object that define the fields used in syslog messages to |
2884
|
|
|
|
|
|
|
be sent from the localhost. Arguments define all portions of a RFC 3164 |
2885
|
|
|
|
|
|
|
Syslog message. Message is sent when &send_message is called. |
2886
|
|
|
|
|
|
|
|
2887
|
|
|
|
|
|
|
Any argument can be defined now or when calling &send_message. This allows the user |
2888
|
|
|
|
|
|
|
to set values that are static for their needs or change dynamically each time |
2889
|
|
|
|
|
|
|
a message is sent. |
2890
|
|
|
|
|
|
|
|
2891
|
|
|
|
|
|
|
($syslog, $error) = Syslog->send( |
2892
|
|
|
|
|
|
|
-server => , |
2893
|
|
|
|
|
|
|
[-port => ,] |
2894
|
|
|
|
|
|
|
[-proto => ,] |
2895
|
|
|
|
|
|
|
[-facility => ,] |
2896
|
|
|
|
|
|
|
[-severity => ,] |
2897
|
|
|
|
|
|
|
[-timestamp => ,] |
2898
|
|
|
|
|
|
|
[-device => ,] |
2899
|
|
|
|
|
|
|
[-tag => ,] |
2900
|
|
|
|
|
|
|
[-pid => ,] |
2901
|
|
|
|
|
|
|
[-content => ,] |
2902
|
|
|
|
|
|
|
[-message => ,] |
2903
|
|
|
|
|
|
|
[-strict => <0|1>,] |
2904
|
|
|
|
|
|
|
[-noHost => <0|1>,] |
2905
|
|
|
|
|
|
|
[-hostname => <0|1>,] |
2906
|
|
|
|
|
|
|
[-noTag => <0|1>,] |
2907
|
|
|
|
|
|
|
[-debug => <0-5>,] |
2908
|
|
|
|
|
|
|
); |
2909
|
|
|
|
|
|
|
|
2910
|
|
|
|
|
|
|
|
2911
|
|
|
|
|
|
|
=over |
2912
|
|
|
|
|
|
|
|
2913
|
|
|
|
|
|
|
=item -server |
2914
|
|
|
|
|
|
|
|
2915
|
|
|
|
|
|
|
Destination Syslog Server IP Address. Default 127.0.0.1 |
2916
|
|
|
|
|
|
|
|
2917
|
|
|
|
|
|
|
=item -port |
2918
|
|
|
|
|
|
|
|
2919
|
|
|
|
|
|
|
Destination Port. Default is 514. |
2920
|
|
|
|
|
|
|
On UNIX systems, ports 0->1023 require user to be root (UID=0). |
2921
|
|
|
|
|
|
|
|
2922
|
|
|
|
|
|
|
=item -proto |
2923
|
|
|
|
|
|
|
|
2924
|
|
|
|
|
|
|
IP protocol to use, default is udp. |
2925
|
|
|
|
|
|
|
|
2926
|
|
|
|
|
|
|
=item -facility |
2927
|
|
|
|
|
|
|
|
2928
|
|
|
|
|
|
|
Syslog FACILITY (text) to use. Default is 'user'. |
2929
|
|
|
|
|
|
|
|
2930
|
|
|
|
|
|
|
=item -severity |
2931
|
|
|
|
|
|
|
|
2932
|
|
|
|
|
|
|
Syslog SEVERITY (text) to use. Default is 'debug'. |
2933
|
|
|
|
|
|
|
|
2934
|
|
|
|
|
|
|
=item -timestamp |
2935
|
|
|
|
|
|
|
|
2936
|
|
|
|
|
|
|
TIMESTAMP to put in to syslog message. Default is current time. |
2937
|
|
|
|
|
|
|
Syntax is Mmm dd hh:mm:ss or Mmm d hh:mm:ss |
2938
|
|
|
|
|
|
|
|
2939
|
|
|
|
|
|
|
=item -noHost |
2940
|
|
|
|
|
|
|
|
2941
|
|
|
|
|
|
|
Tell function to insert HOSTNAME field into syslog message. |
2942
|
|
|
|
|
|
|
If 1, HOSTNAME field is not inserted into syslog message. |
2943
|
|
|
|
|
|
|
If 0, HOSTNAME field is determined by -device or -hostname arguments. |
2944
|
|
|
|
|
|
|
Default is 0. |
2945
|
|
|
|
|
|
|
|
2946
|
|
|
|
|
|
|
=item -device |
2947
|
|
|
|
|
|
|
|
2948
|
|
|
|
|
|
|
HOSTNAME to put in to syslog message. If not given then -hostname |
2949
|
|
|
|
|
|
|
determines HOSTNAME, if -hostname is not true, then 'netdevsyslog' |
2950
|
|
|
|
|
|
|
is used for HOSTNAME field. |
2951
|
|
|
|
|
|
|
|
2952
|
|
|
|
|
|
|
=item -hostname |
2953
|
|
|
|
|
|
|
|
2954
|
|
|
|
|
|
|
Use sytem hostname value for HOSTNAME field, if -device does not give |
2955
|
|
|
|
|
|
|
a hostname to use, then a call to the systems hostname function |
2956
|
|
|
|
|
|
|
is called to get value for HOSTNAME field of syslog message. If |
2957
|
|
|
|
|
|
|
-device and -hostname are not used then 'netdevsyslog' is used |
2958
|
|
|
|
|
|
|
for HOSTNAME field. |
2959
|
|
|
|
|
|
|
|
2960
|
|
|
|
|
|
|
=item -noTag |
2961
|
|
|
|
|
|
|
|
2962
|
|
|
|
|
|
|
Tell function to insert a TAG into the syslog message. |
2963
|
|
|
|
|
|
|
If 1, do not put a TAG into syslog message. |
2964
|
|
|
|
|
|
|
If 0, insert a TAG into syslog message. |
2965
|
|
|
|
|
|
|
|
2966
|
|
|
|
|
|
|
=item -tag |
2967
|
|
|
|
|
|
|
|
2968
|
|
|
|
|
|
|
Syslog message TAG to insert into syslog message. If this |
2969
|
|
|
|
|
|
|
is given and -noTag = 0 then this string will be used as the TAG of the |
2970
|
|
|
|
|
|
|
syslog MESSAGE, a single space will separate it from the CONTENT. |
2971
|
|
|
|
|
|
|
This value will not be used if -message is given. |
2972
|
|
|
|
|
|
|
If not given and -noTag = 0 the function will create a TAG with the syntax |
2973
|
|
|
|
|
|
|
of 'NetDevSyslog[$pid]:', If -pid is given. |
2974
|
|
|
|
|
|
|
Otherwise 'NetDevSyslogp:[$$]', where system PID is used. |
2975
|
|
|
|
|
|
|
|
2976
|
|
|
|
|
|
|
|
2977
|
|
|
|
|
|
|
=item -pid |
2978
|
|
|
|
|
|
|
|
2979
|
|
|
|
|
|
|
Syslog message TAG PID to use. If given, will create |
2980
|
|
|
|
|
|
|
NetDevSyslog[$pid], otherwise the system PID for the the current |
2981
|
|
|
|
|
|
|
script will be used NetDevSyslogp[$$]. |
2982
|
|
|
|
|
|
|
This value will not be used if -message is given. |
2983
|
|
|
|
|
|
|
|
2984
|
|
|
|
|
|
|
|
2985
|
|
|
|
|
|
|
|
2986
|
|
|
|
|
|
|
=item -content |
2987
|
|
|
|
|
|
|
|
2988
|
|
|
|
|
|
|
String to use for syslog message CONTENT. The message portion of a |
2989
|
|
|
|
|
|
|
syslog message is defined as a TAG and CONTENT, with TAG not being |
2990
|
|
|
|
|
|
|
mandatory. This field will be combined with -tag and -pid to |
2991
|
|
|
|
|
|
|
create the syslog MESSAGE portion. |
2992
|
|
|
|
|
|
|
|
2993
|
|
|
|
|
|
|
|
2994
|
|
|
|
|
|
|
=item -message |
2995
|
|
|
|
|
|
|
|
2996
|
|
|
|
|
|
|
String to use as syslog MESSAGE portion. User may opt to not use |
2997
|
|
|
|
|
|
|
the -tag, -pid, -content message and just pass in the complete |
2998
|
|
|
|
|
|
|
MESSAGE portion to follow the TIMESTAMP and HOSTNAME fields. |
2999
|
|
|
|
|
|
|
If this is given it will have precedence over -content. |
3000
|
|
|
|
|
|
|
|
3001
|
|
|
|
|
|
|
|
3002
|
|
|
|
|
|
|
|
3003
|
|
|
|
|
|
|
=item -strict |
3004
|
|
|
|
|
|
|
|
3005
|
|
|
|
|
|
|
By default strict syntax is enforced, this can be disabled with -strict 0. |
3006
|
|
|
|
|
|
|
Strict rules allow message to be no longer than 1024 characters and TAG |
3007
|
|
|
|
|
|
|
within the message to be no longer than 32 characters. |
3008
|
|
|
|
|
|
|
|
3009
|
|
|
|
|
|
|
=back |
3010
|
|
|
|
|
|
|
|
3011
|
|
|
|
|
|
|
|
3012
|
|
|
|
|
|
|
=head2 send_message |
3013
|
|
|
|
|
|
|
|
3014
|
|
|
|
|
|
|
Function will create a RFC 3164 syslog message and send to destination IP:port. |
3015
|
|
|
|
|
|
|
For values not defined by user, defaults will be used. The same arguments given |
3016
|
|
|
|
|
|
|
for the constructor 'send' apply to this function. Thus any value can be changed |
3017
|
|
|
|
|
|
|
before transmission. |
3018
|
|
|
|
|
|
|
|
3019
|
|
|
|
|
|
|
($ok, $error) = $syslog->send_message( |
3020
|
|
|
|
|
|
|
[-server => ], |
3021
|
|
|
|
|
|
|
[-port => ,] |
3022
|
|
|
|
|
|
|
[-proto => ,] |
3023
|
|
|
|
|
|
|
[-facility => ,] |
3024
|
|
|
|
|
|
|
[-severity => ,] |
3025
|
|
|
|
|
|
|
[-timestamp => ,] |
3026
|
|
|
|
|
|
|
[-device => ,] |
3027
|
|
|
|
|
|
|
[-tag => ,] |
3028
|
|
|
|
|
|
|
[-pid => ,] |
3029
|
|
|
|
|
|
|
[-content => ], |
3030
|
|
|
|
|
|
|
[-message => ,] |
3031
|
|
|
|
|
|
|
[-strict => <0|1>], |
3032
|
|
|
|
|
|
|
[-noHost => <0|1>], |
3033
|
|
|
|
|
|
|
[-hostname => <0|1>], |
3034
|
|
|
|
|
|
|
[-noTag => <0|1>], |
3035
|
|
|
|
|
|
|
[-debug => <0-5>], |
3036
|
|
|
|
|
|
|
); |
3037
|
|
|
|
|
|
|
|
3038
|
|
|
|
|
|
|
See above send method for descriptions of send_message options. |
3039
|
|
|
|
|
|
|
|
3040
|
|
|
|
|
|
|
For any error detected, the message will not be sent and undef returned. |
3041
|
|
|
|
|
|
|
For each message sent, the socket is opened and closed. |
3042
|
|
|
|
|
|
|
|
3043
|
|
|
|
|
|
|
In list context the status and error are returned, in scalar context just the |
3044
|
|
|
|
|
|
|
status is returned. If the message is sent successfully, then status is 1, |
3045
|
|
|
|
|
|
|
otherwise undef. If an error occurs then the error variable is a descriptive |
3046
|
|
|
|
|
|
|
string, otherwise undef. |
3047
|
|
|
|
|
|
|
|
3048
|
|
|
|
|
|
|
|
3049
|
|
|
|
|
|
|
=head3 Syslog Message Creation. |
3050
|
|
|
|
|
|
|
|
3051
|
|
|
|
|
|
|
Using the options/arguments of send and send_message the syslog message is created |
3052
|
|
|
|
|
|
|
with the following logic: |
3053
|
|
|
|
|
|
|
|
3054
|
|
|
|
|
|
|
PRI (decimal) is calculated from FACILITY and SEVERITY values, defaults are |
3055
|
|
|
|
|
|
|
used if not given in function call. |
3056
|
|
|
|
|
|
|
|
3057
|
|
|
|
|
|
|
|
3058
|
|
|
|
|
|
|
TIMESTAMP is either given with -timestamp or taken from local system time. |
3059
|
|
|
|
|
|
|
|
3060
|
|
|
|
|
|
|
|
3061
|
|
|
|
|
|
|
HOSTNAME is created if -noHost set to 0. If -device given, then this |
3062
|
|
|
|
|
|
|
becomes HOSTNAME. Else if -hostname is 1, then system hostname is used. |
3063
|
|
|
|
|
|
|
Else 'netdevsyslog' is used. If -noHost is 1 then no HOSTNAME field is |
3064
|
|
|
|
|
|
|
put into the Syslog message. |
3065
|
|
|
|
|
|
|
|
3066
|
|
|
|
|
|
|
|
3067
|
|
|
|
|
|
|
MESSAGE is created either from user giving the full message with the |
3068
|
|
|
|
|
|
|
-message argument. Otherwise MESSAGE is created by combining TAG, PID, |
3069
|
|
|
|
|
|
|
CONTENT. CONTENT is the message of the sylog line. |
3070
|
|
|
|
|
|
|
|
3071
|
|
|
|
|
|
|
CONTENT creation follows this: |
3072
|
|
|
|
|
|
|
|
3073
|
|
|
|
|
|
|
if -content given, then CONTENT is the given string |
3074
|
|
|
|
|
|
|
if -noTag =0 |
3075
|
|
|
|
|
|
|
if -tag and -pid are defined TAG becomes tag[pid]: |
3076
|
|
|
|
|
|
|
if -tag only then TAG is the argument string |
3077
|
|
|
|
|
|
|
if -pid only then NetDevSyslog[pid]: |
3078
|
|
|
|
|
|
|
otherwise NetDevSyslogp[$$] |
3079
|
|
|
|
|
|
|
otherwise CONTENT becomes the default message. |
3080
|
|
|
|
|
|
|
|
3081
|
|
|
|
|
|
|
|
3082
|
|
|
|
|
|
|
|
3083
|
|
|
|
|
|
|
|
3084
|
|
|
|
|
|
|
SYSLOG MESSAGE to be put on the wire is then created by joining |
3085
|
|
|
|
|
|
|
the different variables, $TIMESTAMP, [$HOSTNAME], [$TAG], |
3086
|
|
|
|
|
|
|
$MESSAGE | $CONTENT |
3087
|
|
|
|
|
|
|
|
3088
|
|
|
|
|
|
|
|
3089
|
|
|
|
|
|
|
|
3090
|
|
|
|
|
|
|
=head1 Listen Methods and Functions |
3091
|
|
|
|
|
|
|
|
3092
|
|
|
|
|
|
|
=head2 listen |
3093
|
|
|
|
|
|
|
|
3094
|
|
|
|
|
|
|
Constructor to create object that listens on desired port and prints out |
3095
|
|
|
|
|
|
|
messages received. Message are assumed to be syslog messages. Messages |
3096
|
|
|
|
|
|
|
can also be forward unaltered to a defined address:port. |
3097
|
|
|
|
|
|
|
|
3098
|
|
|
|
|
|
|
($syslog, $error) = Syslog->listen( |
3099
|
|
|
|
|
|
|
[-port => ,] |
3100
|
|
|
|
|
|
|
[-proto => ,] |
3101
|
|
|
|
|
|
|
[-maxlength => ,] |
3102
|
|
|
|
|
|
|
[-packets => ,] |
3103
|
|
|
|
|
|
|
[-verbose => <0|1|2>,] |
3104
|
|
|
|
|
|
|
[-report => <0|1>], |
3105
|
|
|
|
|
|
|
[-fwd_server => ], |
3106
|
|
|
|
|
|
|
[-fwd_port => port>,] |
3107
|
|
|
|
|
|
|
[-fwd_proto => ,] |
3108
|
|
|
|
|
|
|
); |
3109
|
|
|
|
|
|
|
|
3110
|
|
|
|
|
|
|
|
3111
|
|
|
|
|
|
|
If -report or -verbose is used, then a parse oject is created |
3112
|
|
|
|
|
|
|
and the same options that can be given to the parse object can be given |
3113
|
|
|
|
|
|
|
to this object. |
3114
|
|
|
|
|
|
|
|
3115
|
|
|
|
|
|
|
|
3116
|
|
|
|
|
|
|
Message received will be printed to STDOUT. |
3117
|
|
|
|
|
|
|
|
3118
|
|
|
|
|
|
|
|
3119
|
|
|
|
|
|
|
On UNIX systems, if -port is less than 1024 then the the user |
3120
|
|
|
|
|
|
|
must have UID=0 (root). To listen on ports 1024 and above |
3121
|
|
|
|
|
|
|
any userid is allowed. |
3122
|
|
|
|
|
|
|
|
3123
|
|
|
|
|
|
|
|
3124
|
|
|
|
|
|
|
CTRL-C ($SIG{INT}) is redefined to shutdown the socket and then return |
3125
|
|
|
|
|
|
|
control back to caller, it will not exit your program. |
3126
|
|
|
|
|
|
|
|
3127
|
|
|
|
|
|
|
If -report option is enabled, then a reference to object that can be |
3128
|
|
|
|
|
|
|
used to access %STATS will be returned. |
3129
|
|
|
|
|
|
|
|
3130
|
|
|
|
|
|
|
Otherwise a counter value indicating the number of messages received |
3131
|
|
|
|
|
|
|
is returned. |
3132
|
|
|
|
|
|
|
|
3133
|
|
|
|
|
|
|
|
3134
|
|
|
|
|
|
|
=over |
3135
|
|
|
|
|
|
|
|
3136
|
|
|
|
|
|
|
=item -port |
3137
|
|
|
|
|
|
|
|
3138
|
|
|
|
|
|
|
Local port to listen for messages. Messages are assumed to be syslog messages. |
3139
|
|
|
|
|
|
|
Some OS's may require root access. |
3140
|
|
|
|
|
|
|
Default is 514. |
3141
|
|
|
|
|
|
|
|
3142
|
|
|
|
|
|
|
=item -proto |
3143
|
|
|
|
|
|
|
|
3144
|
|
|
|
|
|
|
Protocol to use. |
3145
|
|
|
|
|
|
|
Default is udp. |
3146
|
|
|
|
|
|
|
|
3147
|
|
|
|
|
|
|
|
3148
|
|
|
|
|
|
|
=item -maxlength |
3149
|
|
|
|
|
|
|
|
3150
|
|
|
|
|
|
|
Max message length. Default is 1024 |
3151
|
|
|
|
|
|
|
|
3152
|
|
|
|
|
|
|
=item -packets |
3153
|
|
|
|
|
|
|
|
3154
|
|
|
|
|
|
|
Shutdown the socket listening on after N packets are received on the |
3155
|
|
|
|
|
|
|
given port. At least one packet must be received for packet count |
3156
|
|
|
|
|
|
|
to be checked. |
3157
|
|
|
|
|
|
|
|
3158
|
|
|
|
|
|
|
=item -verbose |
3159
|
|
|
|
|
|
|
|
3160
|
|
|
|
|
|
|
Verbosity level 0-3 |
3161
|
|
|
|
|
|
|
|
3162
|
|
|
|
|
|
|
|
3163
|
|
|
|
|
|
|
=item -report |
3164
|
|
|
|
|
|
|
|
3165
|
|
|
|
|
|
|
Perform same reporting as the parse method does. All arguments to the parse |
3166
|
|
|
|
|
|
|
method can be used on this method. Unlike the parse method, reporting |
3167
|
|
|
|
|
|
|
is off by default for listen method. |
3168
|
|
|
|
|
|
|
|
3169
|
|
|
|
|
|
|
=item -fwd_server |
3170
|
|
|
|
|
|
|
|
3171
|
|
|
|
|
|
|
Forward received message to address given. Message is sent as it is received |
3172
|
|
|
|
|
|
|
off the wire. Dotted decimal IP address or DNS name can be given. |
3173
|
|
|
|
|
|
|
|
3174
|
|
|
|
|
|
|
=item -fwd_port |
3175
|
|
|
|
|
|
|
|
3176
|
|
|
|
|
|
|
Define TCP port for forward message to be sent. Default is 514 |
3177
|
|
|
|
|
|
|
|
3178
|
|
|
|
|
|
|
=item -fwd_proto |
3179
|
|
|
|
|
|
|
|
3180
|
|
|
|
|
|
|
Define transport protocol for forwarded message to be sent. Default is UDP. |
3181
|
|
|
|
|
|
|
String 'udp' or 'tcp' can be given. |
3182
|
|
|
|
|
|
|
|
3183
|
|
|
|
|
|
|
|
3184
|
|
|
|
|
|
|
=back |
3185
|
|
|
|
|
|
|
|
3186
|
|
|
|
|
|
|
|
3187
|
|
|
|
|
|
|
|
3188
|
|
|
|
|
|
|
=head1 General Functions |
3189
|
|
|
|
|
|
|
|
3190
|
|
|
|
|
|
|
=head2 init |
3191
|
|
|
|
|
|
|
|
3192
|
|
|
|
|
|
|
Initialize the hash storing the current syslog line information. |
3193
|
|
|
|
|
|
|
|
3194
|
|
|
|
|
|
|
$syslog->init(); |
3195
|
|
|
|
|
|
|
|
3196
|
|
|
|
|
|
|
|
3197
|
|
|
|
|
|
|
=head2 close_dumps |
3198
|
|
|
|
|
|
|
|
3199
|
|
|
|
|
|
|
Function to loop through all filehandles opened for dumping a syslog |
3200
|
|
|
|
|
|
|
line to a device specific file. The parsing function will take care |
3201
|
|
|
|
|
|
|
of closing any files created with the -dump option, this is available |
3202
|
|
|
|
|
|
|
to give the user the control if needed. |
3203
|
|
|
|
|
|
|
|
3204
|
|
|
|
|
|
|
$syslog->close_dumps(); |
3205
|
|
|
|
|
|
|
|
3206
|
|
|
|
|
|
|
|
3207
|
|
|
|
|
|
|
=head2 syslog_stats_epoch2datestr |
3208
|
|
|
|
|
|
|
|
3209
|
|
|
|
|
|
|
Function to convert epoch seconds, in the hash created with -report option, |
3210
|
|
|
|
|
|
|
to a date string of Mmm/dd/yyyy hh:mm:ss. This function acts on the hash |
3211
|
|
|
|
|
|
|
and convert epoch min, max time value for the whole syslog file and per |
3212
|
|
|
|
|
|
|
each device. If you reference the hash before running this function |
3213
|
|
|
|
|
|
|
you will not get the date string. This process is kept separate to save |
3214
|
|
|
|
|
|
|
time in waiting for this to complete if done during parsing, since |
3215
|
|
|
|
|
|
|
we only need to do it after the min and max are found. The syntax |
3216
|
|
|
|
|
|
|
is purposely different than the syntax of a sylog message, but does contain |
3217
|
|
|
|
|
|
|
the same information with a year value added. |
3218
|
|
|
|
|
|
|
|
3219
|
|
|
|
|
|
|
&syslog_stats_epoch2datestr; |
3220
|
|
|
|
|
|
|
|
3221
|
|
|
|
|
|
|
|
3222
|
|
|
|
|
|
|
=head2 epoch_to_syslog_timestamp |
3223
|
|
|
|
|
|
|
|
3224
|
|
|
|
|
|
|
Function to convert epoch seconds to a RFC 3164 syslog message timestamp. |
3225
|
|
|
|
|
|
|
If epoch seconds not given, then current time is used. |
3226
|
|
|
|
|
|
|
|
3227
|
|
|
|
|
|
|
$timestamp = epoch_to_syslog_timestamp($epoch); |
3228
|
|
|
|
|
|
|
|
3229
|
|
|
|
|
|
|
=head2 epoch_to_datestr |
3230
|
|
|
|
|
|
|
|
3231
|
|
|
|
|
|
|
Function to convert epoch seconds to a common date string. |
3232
|
|
|
|
|
|
|
If epoch seconds not given, then current time is used. |
3233
|
|
|
|
|
|
|
|
3234
|
|
|
|
|
|
|
$date_str = epoch_to_datestr($epoch) |
3235
|
|
|
|
|
|
|
|
3236
|
|
|
|
|
|
|
Date string format Mmm/dd/yyyy hh:mm:ss |
3237
|
|
|
|
|
|
|
|
3238
|
|
|
|
|
|
|
=head2 date_filter_to_epoch |
3239
|
|
|
|
|
|
|
|
3240
|
|
|
|
|
|
|
Function to convert date given for a filter to epoch seconds. |
3241
|
|
|
|
|
|
|
|
3242
|
|
|
|
|
|
|
$epoch = date_filter_to_epoch(); |
3243
|
|
|
|
|
|
|
|
3244
|
|
|
|
|
|
|
=head2 validate_timestamp_syntax |
3245
|
|
|
|
|
|
|
|
3246
|
|
|
|
|
|
|
Function to validate that a given timestamp matches the syntax |
3247
|
|
|
|
|
|
|
defined by RFC 3164. If valid, then '1' is returned, if invalid |
3248
|
|
|
|
|
|
|
then '0' is returned. |
3249
|
|
|
|
|
|
|
|
3250
|
|
|
|
|
|
|
$ok = validate_timestamp_syntax($timestamp); |
3251
|
|
|
|
|
|
|
|
3252
|
|
|
|
|
|
|
=head2 make_timeslots |
3253
|
|
|
|
|
|
|
|
3254
|
|
|
|
|
|
|
Function to create @TIMESLOTS given the min/max epoch seconds and |
3255
|
|
|
|
|
|
|
the interval. Will start at min epoch value and increment until |
3256
|
|
|
|
|
|
|
reaching or exceeding the max epoch value. For each increment an |
3257
|
|
|
|
|
|
|
index is made based on the min epoch for that interval. The index |
3258
|
|
|
|
|
|
|
is created with &epoch_to_datestr. |
3259
|
|
|
|
|
|
|
|
3260
|
|
|
|
|
|
|
make_timeslots($min_epoch, $max_epoch, $interval); |
3261
|
|
|
|
|
|
|
|
3262
|
|
|
|
|
|
|
Min and max values are mandatory and are checked to be greater or less |
3263
|
|
|
|
|
|
|
than the other value. If $interval is not given, function defaults |
3264
|
|
|
|
|
|
|
to 60 seconds. |
3265
|
|
|
|
|
|
|
|
3266
|
|
|
|
|
|
|
The created list is built as such |
3267
|
|
|
|
|
|
|
|
3268
|
|
|
|
|
|
|
@TIMESLOTS = ([$index, min_epoch, $max_epoch], ...); |
3269
|
|
|
|
|
|
|
|
3270
|
|
|
|
|
|
|
This list can be used to group syslog messages to a specific timeslot. |
3271
|
|
|
|
|
|
|
From the syslog line we have epoch seconds, this list provides a range |
3272
|
|
|
|
|
|
|
to check the epoch seconds against and the index for that range. |
3273
|
|
|
|
|
|
|
|
3274
|
|
|
|
|
|
|
=head2 epoch_timeslot_index |
3275
|
|
|
|
|
|
|
|
3276
|
|
|
|
|
|
|
Function that takes a given epoch second value and returns the timeslot |
3277
|
|
|
|
|
|
|
index value for that value from @TIMESLOTS. |
3278
|
|
|
|
|
|
|
|
3279
|
|
|
|
|
|
|
$index = epoch_timeslot_index($epoch); |
3280
|
|
|
|
|
|
|
|
3281
|
|
|
|
|
|
|
If no match is found, undef is returned. |
3282
|
|
|
|
|
|
|
|
3283
|
|
|
|
|
|
|
=head2 normalize_facility |
3284
|
|
|
|
|
|
|
|
3285
|
|
|
|
|
|
|
Function to take a character string representing a facility and |
3286
|
|
|
|
|
|
|
return a normalize string contained in @FACILITY. |
3287
|
|
|
|
|
|
|
|
3288
|
|
|
|
|
|
|
$facility = normalize_facility($facility); |
3289
|
|
|
|
|
|
|
|
3290
|
|
|
|
|
|
|
If given string is not normailized, it is returned |
3291
|
|
|
|
|
|
|
|
3292
|
|
|
|
|
|
|
=head2 normalize_severity |
3293
|
|
|
|
|
|
|
|
3294
|
|
|
|
|
|
|
Function to take a character string representing a severity and |
3295
|
|
|
|
|
|
|
return a normalize string contained in @SEVERITY. |
3296
|
|
|
|
|
|
|
|
3297
|
|
|
|
|
|
|
$severity = normalize_severity($severity); |
3298
|
|
|
|
|
|
|
|
3299
|
|
|
|
|
|
|
If given string is not normailized, it is returned |
3300
|
|
|
|
|
|
|
|
3301
|
|
|
|
|
|
|
=head2 decode_PRI |
3302
|
|
|
|
|
|
|
|
3303
|
|
|
|
|
|
|
Function to decode PRI in decimal format to a Facility and Severity. |
3304
|
|
|
|
|
|
|
Can accept either decimal number or decimal number bounded by '<' '>'. |
3305
|
|
|
|
|
|
|
|
3306
|
|
|
|
|
|
|
In list context will return list of information, in scalar context will |
3307
|
|
|
|
|
|
|
return respective Facility and Severity strings joined with '.'. |
3308
|
|
|
|
|
|
|
|
3309
|
|
|
|
|
|
|
|
3310
|
|
|
|
|
|
|
@pri = decode_PRI($pri_dec); |
3311
|
|
|
|
|
|
|
$PRI = decode_PRI($pri_dec); |
3312
|
|
|
|
|
|
|
|
3313
|
|
|
|
|
|
|
$pri[0] PRI decimal value |
3314
|
|
|
|
|
|
|
$pri[1] Facility decimal value |
3315
|
|
|
|
|
|
|
$pri[2] Severity decimal value |
3316
|
|
|
|
|
|
|
$pri[3] PRI character string (join facility and severity string) |
3317
|
|
|
|
|
|
|
$pri[4] Facility charater string |
3318
|
|
|
|
|
|
|
$pri[5] Severity charater string |
3319
|
|
|
|
|
|
|
|
3320
|
|
|
|
|
|
|
Given PRI value is checked to be between 0 and 191. If not, then undef |
3321
|
|
|
|
|
|
|
is returned in scalar context and for list values any decimal |
3322
|
|
|
|
|
|
|
number is -1, P?, F?, S? for PRI, Facility Severity character strings |
3323
|
|
|
|
|
|
|
respectively |
3324
|
|
|
|
|
|
|
|
3325
|
|
|
|
|
|
|
|
3326
|
|
|
|
|
|
|
=head2 set_year |
3327
|
|
|
|
|
|
|
|
3328
|
|
|
|
|
|
|
Set the value used by methods and functions of this module to the current |
3329
|
|
|
|
|
|
|
year as known by localtime. Syslog message timestamps do not conatain year |
3330
|
|
|
|
|
|
|
information. A user may need to change this when looking at a syslog from |
3331
|
|
|
|
|
|
|
a different year. |
3332
|
|
|
|
|
|
|
|
3333
|
|
|
|
|
|
|
If no value is given, then the current year is assumed, otherwise |
3334
|
|
|
|
|
|
|
the year is set to the argument. |
3335
|
|
|
|
|
|
|
|
3336
|
|
|
|
|
|
|
$syslog->set_year(2003); # set year to 2003 |
3337
|
|
|
|
|
|
|
$syslog->set_year(); # set year to ((localtime)[5]) + 1900 |
3338
|
|
|
|
|
|
|
|
3339
|
|
|
|
|
|
|
|
3340
|
|
|
|
|
|
|
|
3341
|
|
|
|
|
|
|
=head2 syslog_stats_href |
3342
|
|
|
|
|
|
|
|
3343
|
|
|
|
|
|
|
Return reference to %STATS, this is the hash created with the -report option |
3344
|
|
|
|
|
|
|
to the parser and listener. |
3345
|
|
|
|
|
|
|
|
3346
|
|
|
|
|
|
|
=head2 syslog_device_aref |
3347
|
|
|
|
|
|
|
|
3348
|
|
|
|
|
|
|
Return reference to @DEVICES, list of HOSTNAMEs parsed. |
3349
|
|
|
|
|
|
|
This is created with the -report option to the parser and listener. |
3350
|
|
|
|
|
|
|
|
3351
|
|
|
|
|
|
|
=head2 syslog_facility_aref |
3352
|
|
|
|
|
|
|
|
3353
|
|
|
|
|
|
|
Return reference to @FACILITY, list of FACILITIES parsed. |
3354
|
|
|
|
|
|
|
This is created with the -report option to the parser and listener. |
3355
|
|
|
|
|
|
|
|
3356
|
|
|
|
|
|
|
=head2 syslog_severity_aref |
3357
|
|
|
|
|
|
|
|
3358
|
|
|
|
|
|
|
Return reference to @SEVERITY, list of SEVERITIES parsed. |
3359
|
|
|
|
|
|
|
This is created with the -report option to the parser and listener. |
3360
|
|
|
|
|
|
|
|
3361
|
|
|
|
|
|
|
=head2 syslog_tag_aref |
3362
|
|
|
|
|
|
|
|
3363
|
|
|
|
|
|
|
Return reference to @TAGS, list of TAGS parsed |
3364
|
|
|
|
|
|
|
This is created with the -report option to the parser and listener. |
3365
|
|
|
|
|
|
|
|
3366
|
|
|
|
|
|
|
=head2 syslog_timeslot_ref |
3367
|
|
|
|
|
|
|
|
3368
|
|
|
|
|
|
|
Return reference to @TIMESLOTS, list of time slots made by |
3369
|
|
|
|
|
|
|
make_timeslot function. |
3370
|
|
|
|
|
|
|
|
3371
|
|
|
|
|
|
|
=head2 syslog_error |
3372
|
|
|
|
|
|
|
|
3373
|
|
|
|
|
|
|
Return last error. |
3374
|
|
|
|
|
|
|
|
3375
|
|
|
|
|
|
|
=head2 syslog_error_count |
3376
|
|
|
|
|
|
|
|
3377
|
|
|
|
|
|
|
Return error counter value, incremented each time the parser errors. |
3378
|
|
|
|
|
|
|
|
3379
|
|
|
|
|
|
|
=head2 syslog_filter_count |
3380
|
|
|
|
|
|
|
|
3381
|
|
|
|
|
|
|
Return filter counter value, incremented each time a line is filtered |
3382
|
|
|
|
|
|
|
|
3383
|
|
|
|
|
|
|
=head2 syslog_parse_count |
3384
|
|
|
|
|
|
|
|
3385
|
|
|
|
|
|
|
Return parser count, increments each time a line is given to parser |
3386
|
|
|
|
|
|
|
|
3387
|
|
|
|
|
|
|
|
3388
|
|
|
|
|
|
|
=head1 Data Access |
3389
|
|
|
|
|
|
|
|
3390
|
|
|
|
|
|
|
=head2 @FACILITY |
3391
|
|
|
|
|
|
|
|
3392
|
|
|
|
|
|
|
List of all syslog facilities strings as defined by RFC 3164. |
3393
|
|
|
|
|
|
|
Any facility string parse or given by the user is normalized |
3394
|
|
|
|
|
|
|
to strings found in this list. |
3395
|
|
|
|
|
|
|
|
3396
|
|
|
|
|
|
|
=head2 @SEVERITY |
3397
|
|
|
|
|
|
|
|
3398
|
|
|
|
|
|
|
List of all syslog severities strings as defined by RFC 3164. |
3399
|
|
|
|
|
|
|
Any severity string parse or given by the user is normalized |
3400
|
|
|
|
|
|
|
to strings found in this list. |
3401
|
|
|
|
|
|
|
|
3402
|
|
|
|
|
|
|
=head2 %Syslog_Facility |
3403
|
|
|
|
|
|
|
|
3404
|
|
|
|
|
|
|
Hash whose keys are syslog facility strings and whose value |
3405
|
|
|
|
|
|
|
is the decimal representation of that facility. |
3406
|
|
|
|
|
|
|
|
3407
|
|
|
|
|
|
|
=head2 %Syslog_Severity |
3408
|
|
|
|
|
|
|
|
3409
|
|
|
|
|
|
|
Hash whose keys are syslog severity strings and whose value |
3410
|
|
|
|
|
|
|
is the decimal representation of that severity. |
3411
|
|
|
|
|
|
|
|
3412
|
|
|
|
|
|
|
=head2 $TIMESTAMP |
3413
|
|
|
|
|
|
|
|
3414
|
|
|
|
|
|
|
The pattern used to parse TIMESTAMP from RFC 3164 syslog message. |
3415
|
|
|
|
|
|
|
|
3416
|
|
|
|
|
|
|
(([JFMASONDjfmasond]\w\w) {1,2}(\d+) (\d{2}:\d{2}:\d{2})) |
3417
|
|
|
|
|
|
|
|
3418
|
|
|
|
|
|
|
$1 = TIMESTAMP |
3419
|
|
|
|
|
|
|
|
3420
|
|
|
|
|
|
|
$2 = Month string |
3421
|
|
|
|
|
|
|
|
3422
|
|
|
|
|
|
|
$3 = Month day (decimal) |
3423
|
|
|
|
|
|
|
|
3424
|
|
|
|
|
|
|
$4 = hh:mm::ss |
3425
|
|
|
|
|
|
|
|
3426
|
|
|
|
|
|
|
|
3427
|
|
|
|
|
|
|
=head2 $HOSTNAME |
3428
|
|
|
|
|
|
|
|
3429
|
|
|
|
|
|
|
The patterm used to parse HOSTNAME from RFC 3164 syslog message. |
3430
|
|
|
|
|
|
|
|
3431
|
|
|
|
|
|
|
([a-zA-Z0-9_\.\-]+) |
3432
|
|
|
|
|
|
|
|
3433
|
|
|
|
|
|
|
$1 = HOSTNAME |
3434
|
|
|
|
|
|
|
|
3435
|
|
|
|
|
|
|
|
3436
|
|
|
|
|
|
|
=head2 $TAG_1 $TAG_2 $TAG_3 |
3437
|
|
|
|
|
|
|
|
3438
|
|
|
|
|
|
|
The user defined pattern used to parse a TAG from RFC 3164 syslog message. |
3439
|
|
|
|
|
|
|
If any of these are defined, then the TAG is to be parsed against these |
3440
|
|
|
|
|
|
|
patterns, otherwise the modules regexp pattern will be used. |
3441
|
|
|
|
|
|
|
|
3442
|
|
|
|
|
|
|
$TAG_1 $1 = task, $2 = pid, $3 = content |
3443
|
|
|
|
|
|
|
|
3444
|
|
|
|
|
|
|
$TAG_2 $1 = task, $2 = content, no pid |
3445
|
|
|
|
|
|
|
|
3446
|
|
|
|
|
|
|
$TAG_3 $1 = task, $2 = pid, $3 = content |
3447
|
|
|
|
|
|
|
|
3448
|
|
|
|
|
|
|
|
3449
|
|
|
|
|
|
|
=head2 $MESSAGE |
3450
|
|
|
|
|
|
|
|
3451
|
|
|
|
|
|
|
The pattern used to parse MESSAGE from RFC 3164 syslog message. |
3452
|
|
|
|
|
|
|
|
3453
|
|
|
|
|
|
|
(.+)$ |
3454
|
|
|
|
|
|
|
|
3455
|
|
|
|
|
|
|
$1 = MESSAGE |
3456
|
|
|
|
|
|
|
|
3457
|
|
|
|
|
|
|
|
3458
|
|
|
|
|
|
|
=head2 $SYSLOG_pattern |
3459
|
|
|
|
|
|
|
|
3460
|
|
|
|
|
|
|
The pattern used to parse any RFC 3164 syslog message. |
3461
|
|
|
|
|
|
|
Combination of $TIMESTAMP, $HOSTNAME, $MESSAGE are used to parse the |
3462
|
|
|
|
|
|
|
different parts from RFC 3164 syslog message. The user can |
3463
|
|
|
|
|
|
|
define this by defining the individual variables that make this |
3464
|
|
|
|
|
|
|
up or just define this directly. |
3465
|
|
|
|
|
|
|
|
3466
|
|
|
|
|
|
|
If used when -format is 'self' then |
3467
|
|
|
|
|
|
|
|
3468
|
|
|
|
|
|
|
$1 = TIMESTAMP |
3469
|
|
|
|
|
|
|
|
3470
|
|
|
|
|
|
|
$2 = Month string |
3471
|
|
|
|
|
|
|
|
3472
|
|
|
|
|
|
|
$3 = Month day (decimal) |
3473
|
|
|
|
|
|
|
|
3474
|
|
|
|
|
|
|
$4 = hh:mm::ss |
3475
|
|
|
|
|
|
|
|
3476
|
|
|
|
|
|
|
$5 = HOSTNAME |
3477
|
|
|
|
|
|
|
|
3478
|
|
|
|
|
|
|
$6 = MESSAGE |
3479
|
|
|
|
|
|
|
|
3480
|
|
|
|
|
|
|
|
3481
|
|
|
|
|
|
|
|
3482
|
|
|
|
|
|
|
|
3483
|
|
|
|
|
|
|
=head2 Syslog Line Hash Reference (parse_syslog_line) |
3484
|
|
|
|
|
|
|
|
3485
|
|
|
|
|
|
|
The hash reference returned by function parse_syslog_line has |
3486
|
|
|
|
|
|
|
the following keys: |
3487
|
|
|
|
|
|
|
|
3488
|
|
|
|
|
|
|
($hash_ref, $error) = $syslog->parse_syslog_line($message); |
3489
|
|
|
|
|
|
|
|
3490
|
|
|
|
|
|
|
|
3491
|
|
|
|
|
|
|
$hash_ref->{'line'} current line from syslog file |
3492
|
|
|
|
|
|
|
{'timestamp'} timestamp from syslog message |
3493
|
|
|
|
|
|
|
{'device'} device name from syslog message |
3494
|
|
|
|
|
|
|
{'message'} syslog message, from after devname |
3495
|
|
|
|
|
|
|
{'month_str'} month from syslog message timestamp (Jan,Feb,...) |
3496
|
|
|
|
|
|
|
{'month'} month index 0->11 |
3497
|
|
|
|
|
|
|
{'day'} day from syslog message timestamp |
3498
|
|
|
|
|
|
|
{'time_str'} hh:mm:ss from syslog message timestamp |
3499
|
|
|
|
|
|
|
{'hour'} hh from syslog message timestamp |
3500
|
|
|
|
|
|
|
{'min'} mm from syslog message timestamp |
3501
|
|
|
|
|
|
|
{'sec'} ss from syslog message timestamp |
3502
|
|
|
|
|
|
|
{'year'} year assumed from localtime |
3503
|
|
|
|
|
|
|
{'epoch'} epoch time converted from syslog message timestamp |
3504
|
|
|
|
|
|
|
{'wday'} wday integer derived from epoch (0-6) = (Sun-Sat) |
3505
|
|
|
|
|
|
|
{'wday_str'} wday string converted, (Sun, Mon, ...) |
3506
|
|
|
|
|
|
|
{'date_str'} syslog message {'epoch'} convert to common format |
3507
|
|
|
|
|
|
|
{'tag'} syslog message content tag |
3508
|
|
|
|
|
|
|
{'pid'} syslog message content tag pid |
3509
|
|
|
|
|
|
|
{'content'} syslog message content after tag parsed out |
3510
|
|
|
|
|
|
|
{'preamble'} string prepended to syslog message |
3511
|
|
|
|
|
|
|
{'rx_epoch'} extra info: rx time epoch |
3512
|
|
|
|
|
|
|
{'rx_timestamp'} extra info: rx timestamp |
3513
|
|
|
|
|
|
|
{'rx_priority'} extra info: priority (text) |
3514
|
|
|
|
|
|
|
{'rx_facility'} extra info: syslog facility (text) |
3515
|
|
|
|
|
|
|
{'rx_severity'} extra info: syslog severity (text) |
3516
|
|
|
|
|
|
|
{'srcIP'} extra info: src IP address |
3517
|
|
|
|
|
|
|
{'rx_epoch'} extra info: rx time epoch |
3518
|
|
|
|
|
|
|
{'rx_date_str'} extra info: rx time date string |
3519
|
|
|
|
|
|
|
{'rx_time_str'} extra info: rx time (hh:mm:ss) |
3520
|
|
|
|
|
|
|
{'rx_year'} extra info: rx time year value |
3521
|
|
|
|
|
|
|
{'rx_month'} extra info: rx time month value |
3522
|
|
|
|
|
|
|
{'rx_month_str'} extra info: rx time month value string (Jan,Feb,..) |
3523
|
|
|
|
|
|
|
{'rx_day'} extra info: rx time day value |
3524
|
|
|
|
|
|
|
{'rx_wday'} extra info: rx time weekday (0-6) (Sun, Mon,..) |
3525
|
|
|
|
|
|
|
{'rx_hour'} extra info: rx time hour value |
3526
|
|
|
|
|
|
|
{'rx_min'} extra info: rx time minute value |
3527
|
|
|
|
|
|
|
{'rx_sec'} extra info: rx time second value |
3528
|
|
|
|
|
|
|
|
3529
|
|
|
|
|
|
|
|
3530
|
|
|
|
|
|
|
=head3 More hash key details |
3531
|
|
|
|
|
|
|
|
3532
|
|
|
|
|
|
|
key = timestamp is $TIMESTAMP |
3533
|
|
|
|
|
|
|
|
3534
|
|
|
|
|
|
|
key = device is $HOSTNAME |
3535
|
|
|
|
|
|
|
|
3536
|
|
|
|
|
|
|
key = message is $MESSAGE |
3537
|
|
|
|
|
|
|
|
3538
|
|
|
|
|
|
|
key = month, day, time_str, hour, minute, sec is parsed from $TIMESTAMP. |
3539
|
|
|
|
|
|
|
month_str is derived |
3540
|
|
|
|
|
|
|
|
3541
|
|
|
|
|
|
|
key = tag and pid may come from $TAG_x if defined |
3542
|
|
|
|
|
|
|
|
3543
|
|
|
|
|
|
|
key = content is the message part after a TAG, if parsed, otherwise the whole message |
3544
|
|
|
|
|
|
|
after $HOSTNAME for bsd format, $TIMESTAMP for noHost format. |
3545
|
|
|
|
|
|
|
|
3546
|
|
|
|
|
|
|
key = preamble is the entire preamble string if found. |
3547
|
|
|
|
|
|
|
|
3548
|
|
|
|
|
|
|
key = rx_* is any information found and parsed from the preamble |
3549
|
|
|
|
|
|
|
|
3550
|
|
|
|
|
|
|
|
3551
|
|
|
|
|
|
|
=head2 %STATS |
3552
|
|
|
|
|
|
|
|
3553
|
|
|
|
|
|
|
Multi-level hash (HoH) that store statisticis. |
3554
|
|
|
|
|
|
|
This hash is created as each line is parsed if -report is enabled. |
3555
|
|
|
|
|
|
|
This only represent some basic stats that I thought everyone would want. |
3556
|
|
|
|
|
|
|
A user can derive their own by examining the different fields in hash |
3557
|
|
|
|
|
|
|
reference returned by parse_syslog_line. |
3558
|
|
|
|
|
|
|
|
3559
|
|
|
|
|
|
|
All of the values listed below are incremented (counter). |
3560
|
|
|
|
|
|
|
Strings enclosed in '<' '>' denote keys derived from information |
3561
|
|
|
|
|
|
|
found in the syslog file, in other words they are variable whereas the |
3562
|
|
|
|
|
|
|
single quoted strings are constant (hardcoded). |
3563
|
|
|
|
|
|
|
|
3564
|
|
|
|
|
|
|
$STATS{'syslog'}{'messages'} |
3565
|
|
|
|
|
|
|
{'min_epoch'} |
3566
|
|
|
|
|
|
|
{'max_epoch'} |
3567
|
|
|
|
|
|
|
{'min_date_str'} |
3568
|
|
|
|
|
|
|
{'max_date_str'} |
3569
|
|
|
|
|
|
|
{'tag'}{<$tag>}{'messages'} |
3570
|
|
|
|
|
|
|
{'facility'}{<$rx_facility>}{'messages'} |
3571
|
|
|
|
|
|
|
{'severity'}{<$rx_severity>}{'messages'} |
3572
|
|
|
|
|
|
|
|
3573
|
|
|
|
|
|
|
|
3574
|
|
|
|
|
|
|
$STATS{'device'}{<$dev>}{'messages'} |
3575
|
|
|
|
|
|
|
{'min_epoch'} |
3576
|
|
|
|
|
|
|
{'max_epoch'} |
3577
|
|
|
|
|
|
|
{'min_date_str'} |
3578
|
|
|
|
|
|
|
{'max_date_str'} |
3579
|
|
|
|
|
|
|
{'tag'}{<$tag>}{'messages'} |
3580
|
|
|
|
|
|
|
{'facility'}{<$rx_facility>}{'messages'} |
3581
|
|
|
|
|
|
|
{'severity'}{<$rx_severity>}{'messages'} |
3582
|
|
|
|
|
|
|
|
3583
|
|
|
|
|
|
|
|
3584
|
|
|
|
|
|
|
=head2 @TIMESLOTS |
3585
|
|
|
|
|
|
|
|
3586
|
|
|
|
|
|
|
@TIMESLOTS is a list (AoA) of time intervals ranging from the min |
3587
|
|
|
|
|
|
|
to max value provided to &make_timeslots function. |
3588
|
|
|
|
|
|
|
A @TIMESLOTS element contains 3 values |
3589
|
|
|
|
|
|
|
|
3590
|
|
|
|
|
|
|
@TIMESLOTS = ([index, min_epoch, max_epoch], ...); |
3591
|
|
|
|
|
|
|
|
3592
|
|
|
|
|
|
|
index - Unique string created to indicate start of timeslot |
3593
|
|
|
|
|
|
|
Mmm/dd/yyyy hh:mm |
3594
|
|
|
|
|
|
|
min_epoch - is begining of the timeslot interval in epoch seconds. |
3595
|
|
|
|
|
|
|
max_epoch - is ending of the timeslot interval in epoch seconds. |
3596
|
|
|
|
|
|
|
|
3597
|
|
|
|
|
|
|
|
3598
|
|
|
|
|
|
|
=head2 @DEVICES |
3599
|
|
|
|
|
|
|
|
3600
|
|
|
|
|
|
|
List of devices found. Created when -report is true. When a device |
3601
|
|
|
|
|
|
|
is firsted learned, its device name as known from the syslog message |
3602
|
|
|
|
|
|
|
is pushed on to this list. |
3603
|
|
|
|
|
|
|
|
3604
|
|
|
|
|
|
|
=head2 @TAGS |
3605
|
|
|
|
|
|
|
|
3606
|
|
|
|
|
|
|
List of tags found. Created when -report is true. When a tag |
3607
|
|
|
|
|
|
|
is firsted learned, its name as known from the sylog message |
3608
|
|
|
|
|
|
|
is pushed on to this list. |
3609
|
|
|
|
|
|
|
|
3610
|
|
|
|
|
|
|
|
3611
|
|
|
|
|
|
|
=head2 $ERROR_count |
3612
|
|
|
|
|
|
|
|
3613
|
|
|
|
|
|
|
Counter for each error occuring in parser. |
3614
|
|
|
|
|
|
|
|
3615
|
|
|
|
|
|
|
=head2 $FILTER_count |
3616
|
|
|
|
|
|
|
|
3617
|
|
|
|
|
|
|
Counter for each line filtered by parser. |
3618
|
|
|
|
|
|
|
|
3619
|
|
|
|
|
|
|
=head2 $PARSE_count |
3620
|
|
|
|
|
|
|
|
3621
|
|
|
|
|
|
|
Counter for each line parsed by parser. |
3622
|
|
|
|
|
|
|
|
3623
|
|
|
|
|
|
|
|
3624
|
|
|
|
|
|
|
=head1 Syslog Message Syntax |
3625
|
|
|
|
|
|
|
|
3626
|
|
|
|
|
|
|
RFC 3164 describes the syntax for syslog message. This modules |
3627
|
|
|
|
|
|
|
intends to adhere to this RFC as well as account for common |
3628
|
|
|
|
|
|
|
practices. |
3629
|
|
|
|
|
|
|
|
3630
|
|
|
|
|
|
|
As described in the RFC, 'device' is a machine that can generate a message. |
3631
|
|
|
|
|
|
|
A 'server' is a machine that receives the message and does not relay it to |
3632
|
|
|
|
|
|
|
any other machine. Syslog uses UDP for its transport and port 514 (server side) |
3633
|
|
|
|
|
|
|
has been assigned to syslog. It is suggested that the device source port also |
3634
|
|
|
|
|
|
|
be 514, since this is not mandatory, this module does not enforce it. |
3635
|
|
|
|
|
|
|
|
3636
|
|
|
|
|
|
|
Section 4.1 of RFC 3164 defines syslog message parts, familiarity with these |
3637
|
|
|
|
|
|
|
descriptions will give the user a better understanding of the functions |
3638
|
|
|
|
|
|
|
and arguments of this module. Maximum length of a syslog message must be 1024 |
3639
|
|
|
|
|
|
|
bytes. There is no minimum length for a syslog message. A message of 0 bytes |
3640
|
|
|
|
|
|
|
should not be transmitted. |
3641
|
|
|
|
|
|
|
|
3642
|
|
|
|
|
|
|
=head2 PRI |
3643
|
|
|
|
|
|
|
|
3644
|
|
|
|
|
|
|
4.1.1 PRI Part of RFC 3164 describes PRI. The PRI represents the syslog |
3645
|
|
|
|
|
|
|
Priority value which represents the Facility and Severity as a decimal |
3646
|
|
|
|
|
|
|
number bounded by angle brackets '<' '>'. The PRI will have 3,4 or 5 characters. |
3647
|
|
|
|
|
|
|
Since two characters are always the brackets, the decimal number is then |
3648
|
|
|
|
|
|
|
1-3 characters. |
3649
|
|
|
|
|
|
|
|
3650
|
|
|
|
|
|
|
The Facility and Severity of a message are numerically coded with |
3651
|
|
|
|
|
|
|
decimal values. |
3652
|
|
|
|
|
|
|
|
3653
|
|
|
|
|
|
|
Numerical Facility |
3654
|
|
|
|
|
|
|
Code |
3655
|
|
|
|
|
|
|
0 kernel messages |
3656
|
|
|
|
|
|
|
1 user-level messages |
3657
|
|
|
|
|
|
|
2 mail system |
3658
|
|
|
|
|
|
|
3 system daemons |
3659
|
|
|
|
|
|
|
4 security/authorization messages (note 1) |
3660
|
|
|
|
|
|
|
5 messages generated internally by syslogd |
3661
|
|
|
|
|
|
|
6 line printer subsystem |
3662
|
|
|
|
|
|
|
7 network news subsystem |
3663
|
|
|
|
|
|
|
8 UUCP subsystem |
3664
|
|
|
|
|
|
|
9 clock daemon (note 2) |
3665
|
|
|
|
|
|
|
10 security/authorization messages (note 1) |
3666
|
|
|
|
|
|
|
11 FTP daemon |
3667
|
|
|
|
|
|
|
12 NTP subsystem |
3668
|
|
|
|
|
|
|
13 log audit (note 1) |
3669
|
|
|
|
|
|
|
14 log alert (note 1) |
3670
|
|
|
|
|
|
|
15 clock daemon (note 2) |
3671
|
|
|
|
|
|
|
16 local use 0 (local0) |
3672
|
|
|
|
|
|
|
17 local use 1 (local1) |
3673
|
|
|
|
|
|
|
18 local use 2 (local2) |
3674
|
|
|
|
|
|
|
19 local use 3 (local3) |
3675
|
|
|
|
|
|
|
20 local use 4 (local4) |
3676
|
|
|
|
|
|
|
21 local use 5 (local5) |
3677
|
|
|
|
|
|
|
22 local use 6 (local6) |
3678
|
|
|
|
|
|
|
23 local use 7 (local7) |
3679
|
|
|
|
|
|
|
|
3680
|
|
|
|
|
|
|
Note 1 - Various operating systems have been found to utilize |
3681
|
|
|
|
|
|
|
Facilities 4, 10, 13 and 14 for security/authorization, |
3682
|
|
|
|
|
|
|
audit, and alert messages which seem to be similar. |
3683
|
|
|
|
|
|
|
Note 2 - Various operating systems have been found to utilize |
3684
|
|
|
|
|
|
|
both Facilities 9 and 15 for clock (cron/at) messages. |
3685
|
|
|
|
|
|
|
|
3686
|
|
|
|
|
|
|
|
3687
|
|
|
|
|
|
|
Numerical Severity |
3688
|
|
|
|
|
|
|
Code |
3689
|
|
|
|
|
|
|
|
3690
|
|
|
|
|
|
|
0 Emergency: system is unusable |
3691
|
|
|
|
|
|
|
1 Alert: action must be taken immediately |
3692
|
|
|
|
|
|
|
2 Critical: critical conditions |
3693
|
|
|
|
|
|
|
3 Error: error conditions |
3694
|
|
|
|
|
|
|
4 Warning: warning conditions |
3695
|
|
|
|
|
|
|
5 Notice: normal but significant condition |
3696
|
|
|
|
|
|
|
6 Informational: informational messages |
3697
|
|
|
|
|
|
|
7 Debug: debug-level messages |
3698
|
|
|
|
|
|
|
|
3699
|
|
|
|
|
|
|
|
3700
|
|
|
|
|
|
|
Priority is calculated as: (Facility*8) + Severity. After calculating the Priority, |
3701
|
|
|
|
|
|
|
bound it with barckets and its now a PRI. For example a daemon debug would |
3702
|
|
|
|
|
|
|
be (3*8)+7 => 31 Priority, PRI <31>. |
3703
|
|
|
|
|
|
|
|
3704
|
|
|
|
|
|
|
=head2 HEADER |
3705
|
|
|
|
|
|
|
|
3706
|
|
|
|
|
|
|
The header portion contains a timestamp and the device name or IP. The device |
3707
|
|
|
|
|
|
|
name is not mandatory. |
3708
|
|
|
|
|
|
|
|
3709
|
|
|
|
|
|
|
=head3 TIMESTAMP |
3710
|
|
|
|
|
|
|
|
3711
|
|
|
|
|
|
|
The TIMESTAMP immediately follows the trailing ">" from the PRI when received |
3712
|
|
|
|
|
|
|
on the wire. |
3713
|
|
|
|
|
|
|
The TIMESTAMP is separated from the HOSTNAME by single space characters. |
3714
|
|
|
|
|
|
|
|
3715
|
|
|
|
|
|
|
The TIMESTAMP field is the local time of the sending device and is in the i |
3716
|
|
|
|
|
|
|
format of 'Mmm dd hh:mm:ss'. |
3717
|
|
|
|
|
|
|
|
3718
|
|
|
|
|
|
|
Mmm is the month abbreviation, such as: |
3719
|
|
|
|
|
|
|
Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec. |
3720
|
|
|
|
|
|
|
|
3721
|
|
|
|
|
|
|
dd is day of month. If numeric day value is a single digit, |
3722
|
|
|
|
|
|
|
then the first character is a space. This would make the format |
3723
|
|
|
|
|
|
|
'Mmm d hh:mm:ss'. |
3724
|
|
|
|
|
|
|
|
3725
|
|
|
|
|
|
|
hh:mm::ss are hour minute seconds, 0 padded. Hours range from |
3726
|
|
|
|
|
|
|
0-23 and minutes and seconds range from 0-59. |
3727
|
|
|
|
|
|
|
|
3728
|
|
|
|
|
|
|
A single space charater must follow the the TIMESTAMP field. |
3729
|
|
|
|
|
|
|
|
3730
|
|
|
|
|
|
|
=head3 HOSTNAME |
3731
|
|
|
|
|
|
|
|
3732
|
|
|
|
|
|
|
The HOSTNAME is separated from the precedding TIMESTAMP by single |
3733
|
|
|
|
|
|
|
space character. The HOSTNAME will be the name of the device as it |
3734
|
|
|
|
|
|
|
knows itself. If it does not have a hostname, then its IP address is |
3735
|
|
|
|
|
|
|
used. |
3736
|
|
|
|
|
|
|
|
3737
|
|
|
|
|
|
|
=head2 MSG (message part) |
3738
|
|
|
|
|
|
|
|
3739
|
|
|
|
|
|
|
The MSG part will fill the rest of the syslog packet. |
3740
|
|
|
|
|
|
|
The MSG part is made of two parts the TAG and CONTENT. |
3741
|
|
|
|
|
|
|
The TAG value is the name of the originating process and must |
3742
|
|
|
|
|
|
|
not exceed 32 characters. |
3743
|
|
|
|
|
|
|
|
3744
|
|
|
|
|
|
|
Since there is no specific rule governing TAGs, the user of this module |
3745
|
|
|
|
|
|
|
is allowed to define 3 TAG patterns to be matched. Otherwise the module |
3746
|
|
|
|
|
|
|
trys to extract common practices. |
3747
|
|
|
|
|
|
|
|
3748
|
|
|
|
|
|
|
The CONTENT is the details of the message. |
3749
|
|
|
|
|
|
|
|
3750
|
|
|
|
|
|
|
=head1 Examples |
3751
|
|
|
|
|
|
|
|
3752
|
|
|
|
|
|
|
Examples are also in ./examples directory of distribution. This directory |
3753
|
|
|
|
|
|
|
also contains syslog generator script that is a bit more elaborate |
3754
|
|
|
|
|
|
|
than a simple example but is good for generating syslog message |
3755
|
|
|
|
|
|
|
from a range of dummy host name. Can generate a file or be used |
3756
|
|
|
|
|
|
|
to send to a server. The comments in the code should give you |
3757
|
|
|
|
|
|
|
a general idea of what is being done and what the varaibles mean. |
3758
|
|
|
|
|
|
|
|
3759
|
|
|
|
|
|
|
|
3760
|
|
|
|
|
|
|
=head3 Sample script to listen for syslog messages on local host. |
3761
|
|
|
|
|
|
|
|
3762
|
|
|
|
|
|
|
#!/usr/bin/perl |
3763
|
|
|
|
|
|
|
# Perl script to test Net::Dev::Tools::Syslog listen |
3764
|
|
|
|
|
|
|
|
3765
|
|
|
|
|
|
|
use strict; |
3766
|
|
|
|
|
|
|
use Net::Dev::Tools::Syslog; |
3767
|
|
|
|
|
|
|
|
3768
|
|
|
|
|
|
|
my ($listen_obj, $error, $ok); |
3769
|
|
|
|
|
|
|
|
3770
|
|
|
|
|
|
|
my $port = 7971; |
3771
|
|
|
|
|
|
|
my $proto = 'udp'; |
3772
|
|
|
|
|
|
|
# create object to listen |
3773
|
|
|
|
|
|
|
# CTRL-C will close sock and return to caller |
3774
|
|
|
|
|
|
|
($listen_obj, $error) = Syslog->listen( |
3775
|
|
|
|
|
|
|
-port => $port, |
3776
|
|
|
|
|
|
|
-proto => $proto, |
3777
|
|
|
|
|
|
|
#-verbose => 3, |
3778
|
|
|
|
|
|
|
#-packets => 150, |
3779
|
|
|
|
|
|
|
#-parseTag => 1, |
3780
|
|
|
|
|
|
|
); |
3781
|
|
|
|
|
|
|
unless ($listen_obj) { |
3782
|
|
|
|
|
|
|
printf("ERROR: syslog listen failed: %s\n", $error); |
3783
|
|
|
|
|
|
|
exit(1); |
3784
|
|
|
|
|
|
|
} |
3785
|
|
|
|
|
|
|
|
3786
|
|
|
|
|
|
|
exit(0); |
3787
|
|
|
|
|
|
|
|
3788
|
|
|
|
|
|
|
|
3789
|
|
|
|
|
|
|
=head3 Sample script to send syslog messages. |
3790
|
|
|
|
|
|
|
|
3791
|
|
|
|
|
|
|
#!/usr/bin/perl |
3792
|
|
|
|
|
|
|
# Perl script to test Net::Dev::Tools::Syslog sending |
3793
|
|
|
|
|
|
|
# |
3794
|
|
|
|
|
|
|
|
3795
|
|
|
|
|
|
|
use strict; |
3796
|
|
|
|
|
|
|
use Net::Dev::Tools::Syslog; |
3797
|
|
|
|
|
|
|
|
3798
|
|
|
|
|
|
|
my ($send_obj, $error, |
3799
|
|
|
|
|
|
|
$facility, $severity, |
3800
|
|
|
|
|
|
|
$ok, |
3801
|
|
|
|
|
|
|
); |
3802
|
|
|
|
|
|
|
|
3803
|
|
|
|
|
|
|
my $server = '192.168.1.1'; |
3804
|
|
|
|
|
|
|
my $port = 7971; |
3805
|
|
|
|
|
|
|
my $proto = 'udp'; |
3806
|
|
|
|
|
|
|
|
3807
|
|
|
|
|
|
|
my $test_send_all = 1; |
3808
|
|
|
|
|
|
|
my $sleep = 0; |
3809
|
|
|
|
|
|
|
my $pid = $$; |
3810
|
|
|
|
|
|
|
|
3811
|
|
|
|
|
|
|
# create send object |
3812
|
|
|
|
|
|
|
($send_obj, $error) = Syslog->send( |
3813
|
|
|
|
|
|
|
-server => $server, |
3814
|
|
|
|
|
|
|
-port => $port, |
3815
|
|
|
|
|
|
|
-proto => $proto, |
3816
|
|
|
|
|
|
|
); |
3817
|
|
|
|
|
|
|
unless ($send_obj) { |
3818
|
|
|
|
|
|
|
myprintf("ERROR: Syslog send failed: %s\n", $error); |
3819
|
|
|
|
|
|
|
exit(1); |
3820
|
|
|
|
|
|
|
} |
3821
|
|
|
|
|
|
|
|
3822
|
|
|
|
|
|
|
# send syslog message |
3823
|
|
|
|
|
|
|
printf("Sending syslog to %s:%s proto: %s pid: %s\n", $server, $port, $proto, $pid ); |
3824
|
|
|
|
|
|
|
# send all syslog type message |
3825
|
|
|
|
|
|
|
if ($test_send_all) { |
3826
|
|
|
|
|
|
|
foreach $facility (@Syslog::FACILITY) { |
3827
|
|
|
|
|
|
|
foreach $severity (@Syslog::SEVERITY) { |
3828
|
|
|
|
|
|
|
#printf("send message: %-10s %s\n", $facility, $severity); |
3829
|
|
|
|
|
|
|
($ok, $error) = $send_obj->send_message( |
3830
|
|
|
|
|
|
|
-facility => $facility, |
3831
|
|
|
|
|
|
|
-severity => $severity, |
3832
|
|
|
|
|
|
|
-hostname => 1, |
3833
|
|
|
|
|
|
|
-device => 'myTestHost', |
3834
|
|
|
|
|
|
|
-noTag => 0, |
3835
|
|
|
|
|
|
|
#-tag => 'myTag', |
3836
|
|
|
|
|
|
|
-pid => 1, |
3837
|
|
|
|
|
|
|
-content => 'my syslog message content', |
3838
|
|
|
|
|
|
|
); |
3839
|
|
|
|
|
|
|
if(!$ok) { |
3840
|
|
|
|
|
|
|
printf("ERROR: syslog->send_msg: %s\n", $error); |
3841
|
|
|
|
|
|
|
} |
3842
|
|
|
|
|
|
|
sleep $sleep; |
3843
|
|
|
|
|
|
|
} |
3844
|
|
|
|
|
|
|
} |
3845
|
|
|
|
|
|
|
} |
3846
|
|
|
|
|
|
|
else { |
3847
|
|
|
|
|
|
|
($ok, $error) = $send_obj->send_message( |
3848
|
|
|
|
|
|
|
-hostname => 1, |
3849
|
|
|
|
|
|
|
); |
3850
|
|
|
|
|
|
|
if(!$ok) { |
3851
|
|
|
|
|
|
|
printf("ERROR: syslog->send_msg: %s\n", $error); |
3852
|
|
|
|
|
|
|
} |
3853
|
|
|
|
|
|
|
} |
3854
|
|
|
|
|
|
|
|
3855
|
|
|
|
|
|
|
exit(0); |
3856
|
|
|
|
|
|
|
|
3857
|
|
|
|
|
|
|
=head3 Sample script to parse syslog messages from file. |
3858
|
|
|
|
|
|
|
|
3859
|
|
|
|
|
|
|
#!/usr/bin/perl |
3860
|
|
|
|
|
|
|
# Perl script to test Net::Dev::Tools::Syslog parsing |
3861
|
|
|
|
|
|
|
# |
3862
|
|
|
|
|
|
|
use strict; |
3863
|
|
|
|
|
|
|
use Net::Dev::Tools::Syslog; |
3864
|
|
|
|
|
|
|
|
3865
|
|
|
|
|
|
|
# get sylog file from cli |
3866
|
|
|
|
|
|
|
my $syslog_file = shift || die "usage: $0 \n"; |
3867
|
|
|
|
|
|
|
|
3868
|
|
|
|
|
|
|
my ($syslog_obj, $error, |
3869
|
|
|
|
|
|
|
$parse_href, |
3870
|
|
|
|
|
|
|
$report_href, |
3871
|
|
|
|
|
|
|
$fh, |
3872
|
|
|
|
|
|
|
$device, $tag, $facility, $severity, |
3873
|
|
|
|
|
|
|
); |
3874
|
|
|
|
|
|
|
|
3875
|
|
|
|
|
|
|
# create syslog parsing object |
3876
|
|
|
|
|
|
|
($syslog_obj, $error) = Syslog->parse( |
3877
|
|
|
|
|
|
|
-report => 1, |
3878
|
|
|
|
|
|
|
-parseTag => 1, |
3879
|
|
|
|
|
|
|
-dump => './dump2', |
3880
|
|
|
|
|
|
|
-debug => 0, |
3881
|
|
|
|
|
|
|
-moreTime => 1, |
3882
|
|
|
|
|
|
|
-format => 'noHost', |
3883
|
|
|
|
|
|
|
); |
3884
|
|
|
|
|
|
|
unless ($syslog_obj) { |
3885
|
|
|
|
|
|
|
printf("sylog object constructor failed: %s\n", $error); |
3886
|
|
|
|
|
|
|
exit(1); |
3887
|
|
|
|
|
|
|
} |
3888
|
|
|
|
|
|
|
|
3889
|
|
|
|
|
|
|
# open syslog file to parse |
3890
|
|
|
|
|
|
|
printf("parse syslog file: %s\n", $syslog_file); |
3891
|
|
|
|
|
|
|
open ($fh, "$syslog_file") || die "ERROR: open failed: $!\n"; |
3892
|
|
|
|
|
|
|
while(<$fh>) { |
3893
|
|
|
|
|
|
|
($parse_href, $error) = $syslog_obj->parse_syslog_line($_); |
3894
|
|
|
|
|
|
|
unless ($parse_href) { |
3895
|
|
|
|
|
|
|
printf("ERROR: line %s: %s\n", $., $error); |
3896
|
|
|
|
|
|
|
} |
3897
|
|
|
|
|
|
|
} |
3898
|
|
|
|
|
|
|
close($fh); |
3899
|
|
|
|
|
|
|
printf("parse syslog file done: %s lines\n", $.); |
3900
|
|
|
|
|
|
|
|
3901
|
|
|
|
|
|
|
# convert epoch time in report hash |
3902
|
|
|
|
|
|
|
&syslog_stats_epoch2datestr; |
3903
|
|
|
|
|
|
|
|
3904
|
|
|
|
|
|
|
# reference report hash and display |
3905
|
|
|
|
|
|
|
$report_href = &syslog_stats_href; |
3906
|
|
|
|
|
|
|
|
3907
|
|
|
|
|
|
|
# stats for entire syslog file |
3908
|
|
|
|
|
|
|
printf("Syslog: messages %s %s -> %s\n\n\n", |
3909
|
|
|
|
|
|
|
$report_href->{'syslog'}{'messages'}, |
3910
|
|
|
|
|
|
|
$report_href->{'syslog'}{'min_date_str'}, |
3911
|
|
|
|
|
|
|
$report_href->{'syslog'}{'max_date_str'}, |
3912
|
|
|
|
|
|
|
); |
3913
|
|
|
|
|
|
|
|
3914
|
|
|
|
|
|
|
# stats for each device found in syslog |
3915
|
|
|
|
|
|
|
foreach $device (keys %{$report_href->{'device'}}) { |
3916
|
|
|
|
|
|
|
printf("Device: %s messages: %s %s -> %s\n", |
3917
|
|
|
|
|
|
|
$device, |
3918
|
|
|
|
|
|
|
$report_href->{'device'}{$device}{'messages'}, |
3919
|
|
|
|
|
|
|
$report_href->{'device'}{$device}{'min_date_str'}, |
3920
|
|
|
|
|
|
|
$report_href->{'device'}{$device}{'max_date_str'}, |
3921
|
|
|
|
|
|
|
); |
3922
|
|
|
|
|
|
|
printf(" Tags:\n",); |
3923
|
|
|
|
|
|
|
foreach $tag (keys %{$report_href->{'device'}{$device}{'tag'}}) { |
3924
|
|
|
|
|
|
|
printf(" %8s %s\n", |
3925
|
|
|
|
|
|
|
$report_href->{'device'}{$device}{'tag'}{$tag}{'messages'}, $tag |
3926
|
|
|
|
|
|
|
); |
3927
|
|
|
|
|
|
|
} |
3928
|
|
|
|
|
|
|
printf(" Facility:\n",); |
3929
|
|
|
|
|
|
|
foreach $facility (keys %{$report_href->{'device'}{$device}{'facility'}}) { |
3930
|
|
|
|
|
|
|
printf(" %8s %s\n", |
3931
|
|
|
|
|
|
|
$report_href->{'device'}{$device}{'facility'}{$facility}{'messages'}, |
3932
|
|
|
|
|
|
|
$facility |
3933
|
|
|
|
|
|
|
); |
3934
|
|
|
|
|
|
|
} |
3935
|
|
|
|
|
|
|
printf(" Severity:\n",); |
3936
|
|
|
|
|
|
|
foreach $severity (keys %{$report_href->{'device'}{$device}{'severity'}}) { |
3937
|
|
|
|
|
|
|
printf(" %8s %s\n", |
3938
|
|
|
|
|
|
|
$report_href->{'device'}{$device}{'severity'}{$severity}{'messages'}, |
3939
|
|
|
|
|
|
|
$severity |
3940
|
|
|
|
|
|
|
); |
3941
|
|
|
|
|
|
|
} |
3942
|
|
|
|
|
|
|
printf("\n"); |
3943
|
|
|
|
|
|
|
} |
3944
|
|
|
|
|
|
|
|
3945
|
|
|
|
|
|
|
exit(0); |
3946
|
|
|
|
|
|
|
|
3947
|
|
|
|
|
|
|
=cut |
3948
|
|
|
|
|
|
|
|
3949
|
|
|
|
|
|
|
|
3950
|
|
|
|
|
|
|
=head1 AUTHOR |
3951
|
|
|
|
|
|
|
|
3952
|
|
|
|
|
|
|
sparsons@cpan.org |
3953
|
|
|
|
|
|
|
|
3954
|
|
|
|
|
|
|
=head1 COPYRIGHT |
3955
|
|
|
|
|
|
|
|
3956
|
|
|
|
|
|
|
Copyright (c) 2004-2006 Scott Parsons All rights reserved. |
3957
|
|
|
|
|
|
|
This program is free software; you may redistribute it |
3958
|
|
|
|
|
|
|
and/or modify it under the same terms as Perl itself. |
3959
|
|
|
|
|
|
|
|
3960
|
|
|
|
|
|
|
|
3961
|
|
|
|
|
|
|
|
3962
|
|
|
|
|
|
|
|
3963
|
|
|
|
|
|
|
|