| 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
|
|
|
|
|
|
|
|