| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# ABSTRACT: Simple syslog line parser |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package Parse::Syslog::Line; |
|
4
|
|
|
|
|
|
|
|
|
5
|
4
|
|
|
4
|
|
822115
|
use warnings; |
|
|
4
|
|
|
|
|
14
|
|
|
|
4
|
|
|
|
|
136
|
|
|
6
|
4
|
|
|
4
|
|
25
|
use strict; |
|
|
4
|
|
|
|
|
10
|
|
|
|
4
|
|
|
|
|
87
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
4
|
|
|
4
|
|
24
|
use Carp; |
|
|
4
|
|
|
|
|
16
|
|
|
|
4
|
|
|
|
|
228
|
|
|
9
|
4
|
|
|
4
|
|
1815
|
use Const::Fast; |
|
|
4
|
|
|
|
|
8300
|
|
|
|
4
|
|
|
|
|
26
|
|
|
10
|
4
|
|
|
4
|
|
2189
|
use English qw(-no_match_vars); |
|
|
4
|
|
|
|
|
13333
|
|
|
|
4
|
|
|
|
|
23
|
|
|
11
|
4
|
|
|
4
|
|
1204
|
use Exporter; |
|
|
4
|
|
|
|
|
10
|
|
|
|
4
|
|
|
|
|
149
|
|
|
12
|
4
|
|
|
4
|
|
1745
|
use HTTP::Date qw( str2time ); |
|
|
4
|
|
|
|
|
14514
|
|
|
|
4
|
|
|
|
|
273
|
|
|
13
|
4
|
|
|
4
|
|
2047
|
use Module::Load qw( load ); |
|
|
4
|
|
|
|
|
4257
|
|
|
|
4
|
|
|
|
|
90
|
|
|
14
|
4
|
|
|
4
|
|
1933
|
use Module::Loaded qw( is_loaded ); |
|
|
4
|
|
|
|
|
2090
|
|
|
|
4
|
|
|
|
|
194
|
|
|
15
|
4
|
|
|
4
|
|
1178
|
use POSIX qw( strftime tzset ); |
|
|
4
|
|
|
|
|
15484
|
|
|
|
4
|
|
|
|
|
32
|
|
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our $VERSION = '4.0'; |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# Default for Handling Parsing |
|
20
|
|
|
|
|
|
|
our $DateParsing = 1; |
|
21
|
|
|
|
|
|
|
our $DateTimeCreate = 0; |
|
22
|
|
|
|
|
|
|
our $EpochCreate = 1; |
|
23
|
|
|
|
|
|
|
our $NormalizeToUTC = 0; |
|
24
|
|
|
|
|
|
|
our $OutputTimeZone = 0; |
|
25
|
|
|
|
|
|
|
our $IgnoreTimeZones = 0; |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
our $ExtractProgram = 1; |
|
28
|
|
|
|
|
|
|
our $PruneRaw = 0; |
|
29
|
|
|
|
|
|
|
our $PruneEmpty = 0; |
|
30
|
|
|
|
|
|
|
our @PruneFields = (); |
|
31
|
|
|
|
|
|
|
our $FmtDate; |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
my %INT_PRIORITY = ( |
|
35
|
|
|
|
|
|
|
'emerg' => 0, |
|
36
|
|
|
|
|
|
|
'alert' => 1, |
|
37
|
|
|
|
|
|
|
'crit' => 2, |
|
38
|
|
|
|
|
|
|
'err' => 3, |
|
39
|
|
|
|
|
|
|
'warn' => 4, |
|
40
|
|
|
|
|
|
|
'notice' => 5, |
|
41
|
|
|
|
|
|
|
'info' => 6, |
|
42
|
|
|
|
|
|
|
'debug' => 7, |
|
43
|
|
|
|
|
|
|
); |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
my %INT_FACILITY = ( |
|
46
|
|
|
|
|
|
|
# |
|
47
|
|
|
|
|
|
|
# POSIX Facilities |
|
48
|
|
|
|
|
|
|
'kern' => 0 << 3, |
|
49
|
|
|
|
|
|
|
'user' => 1 << 3, |
|
50
|
|
|
|
|
|
|
'mail' => 2 << 3, |
|
51
|
|
|
|
|
|
|
'daemon' => 3 << 3, |
|
52
|
|
|
|
|
|
|
'auth' => 4 << 3, |
|
53
|
|
|
|
|
|
|
'syslog' => 5 << 3, |
|
54
|
|
|
|
|
|
|
'lpr' => 6 << 3, |
|
55
|
|
|
|
|
|
|
'news' => 7 << 3, |
|
56
|
|
|
|
|
|
|
'uucp' => 8 << 3, |
|
57
|
|
|
|
|
|
|
'cron' => 9 << 3, |
|
58
|
|
|
|
|
|
|
'authpriv' => 10 << 3, |
|
59
|
|
|
|
|
|
|
'ftp' => 11 << 3, |
|
60
|
|
|
|
|
|
|
# |
|
61
|
|
|
|
|
|
|
# Local Reserved |
|
62
|
|
|
|
|
|
|
'local0' => 16 << 3, |
|
63
|
|
|
|
|
|
|
'local1' => 17 << 3, |
|
64
|
|
|
|
|
|
|
'local2' => 18 << 3, |
|
65
|
|
|
|
|
|
|
'local3' => 19 << 3, |
|
66
|
|
|
|
|
|
|
'local4' => 20 << 3, |
|
67
|
|
|
|
|
|
|
'local5' => 21 << 3, |
|
68
|
|
|
|
|
|
|
'local6' => 22 << 3, |
|
69
|
|
|
|
|
|
|
'local7' => 23 << 3, |
|
70
|
|
|
|
|
|
|
# |
|
71
|
|
|
|
|
|
|
# Apple Additions |
|
72
|
|
|
|
|
|
|
'netinfo' => 12 << 3, |
|
73
|
|
|
|
|
|
|
'remoteauth' => 13 << 3, |
|
74
|
|
|
|
|
|
|
'install' => 14 << 3, |
|
75
|
|
|
|
|
|
|
'ras' => 15 << 3, |
|
76
|
|
|
|
|
|
|
'launchd' => 24 << 3, |
|
77
|
|
|
|
|
|
|
); |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
const our %LOG_PRIORITY => ( |
|
80
|
|
|
|
|
|
|
%INT_PRIORITY, |
|
81
|
|
|
|
|
|
|
reverse(%INT_PRIORITY), |
|
82
|
|
|
|
|
|
|
); |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
const our %LOG_FACILITY => ( |
|
85
|
|
|
|
|
|
|
%INT_FACILITY, |
|
86
|
|
|
|
|
|
|
reverse(%INT_FACILITY), |
|
87
|
|
|
|
|
|
|
); |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
const our %CONV_MASK => ( |
|
90
|
|
|
|
|
|
|
priority => 0x07, |
|
91
|
|
|
|
|
|
|
facility => 0x03f8, |
|
92
|
|
|
|
|
|
|
); |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
|
96
|
|
|
|
|
|
|
our @EXPORT = qw(parse_syslog_line); |
|
97
|
|
|
|
|
|
|
our @EXPORT_OK = qw( |
|
98
|
|
|
|
|
|
|
parse_syslog_line |
|
99
|
|
|
|
|
|
|
preamble_priority preamble_facility |
|
100
|
|
|
|
|
|
|
%LOG_FACILITY %LOG_PRIORITY |
|
101
|
|
|
|
|
|
|
get_syslog_timezone set_syslog_timezone |
|
102
|
|
|
|
|
|
|
use_utc_syslog |
|
103
|
|
|
|
|
|
|
); |
|
104
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( |
|
105
|
|
|
|
|
|
|
constants => [ qw( %LOG_FACILITY %LOG_PRIORITY ) ], |
|
106
|
|
|
|
|
|
|
preamble => [ qw(preamble_priority preamble_facility) ], |
|
107
|
|
|
|
|
|
|
with_timezones => [ qw(parse_syslog_line set_syslog_timezone get_syslog_timezone use_utc_syslog) ], |
|
108
|
|
|
|
|
|
|
); |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# Regex to Extract Data |
|
111
|
|
|
|
|
|
|
const my %RE => ( |
|
112
|
|
|
|
|
|
|
IPv4 => qr/(?>(?:[0-9]{1,3}\.){3}[0-9]{1,3})/, |
|
113
|
|
|
|
|
|
|
preamble => qr/(?>^\<(\d+)\>)/, |
|
114
|
|
|
|
|
|
|
year => qr/(?>^(\d{4}) )/, |
|
115
|
|
|
|
|
|
|
date => qr/(?>^([A-Za-z]{3}\s+[0-9]+\s+[0-9]{1,2}(?:\:[0-9]{2}){1,2}))/, |
|
116
|
|
|
|
|
|
|
date_long => qr/^(?> |
|
117
|
|
|
|
|
|
|
(?:[0-9]{4}\s+)? # Year: Because, Cisco |
|
118
|
|
|
|
|
|
|
([.*])? # Cisco adds a * for no ntp, and a . for configured but out of sync |
|
119
|
|
|
|
|
|
|
[a-zA-Z]{3}\s+[0-9]+ # Date: Jan 1 |
|
120
|
|
|
|
|
|
|
(?:\s+[0-9]{4})? # Year: Because, Cisco |
|
121
|
|
|
|
|
|
|
\s+ # Date Separator: spaces |
|
122
|
|
|
|
|
|
|
[0-9]{1,2}(?:\:[0-9]{2}){1,2} # Time: HH:MM or HH:MM:SS |
|
123
|
|
|
|
|
|
|
(?:\.[0-9]{3,6})? # Time: .DDD(DDD) ms resolution |
|
124
|
|
|
|
|
|
|
(?:\s+[A-Z]{3,4})? # Timezone, ZZZ or ZZZZ |
|
125
|
|
|
|
|
|
|
(?:\:?) # Cisco adds a : after the second timestamp |
|
126
|
|
|
|
|
|
|
)/x, |
|
127
|
|
|
|
|
|
|
date_iso8601 => qr/(?>^( |
|
128
|
|
|
|
|
|
|
[0-9]{4}(?:\-[0-9]{2}){2} # Date YYYY-MM-DD |
|
129
|
|
|
|
|
|
|
(?:\s|T) # Date Separator T or ' ' |
|
130
|
|
|
|
|
|
|
[0-9]{2}(?:\:[0-9]{2}){1,2} # Time HH:MM:SS |
|
131
|
|
|
|
|
|
|
(?:\.(?:[0-9]{3}){1,2})? # Time: .DDD millisecond or .DDDDDD microsecond resolution |
|
132
|
|
|
|
|
|
|
(?:[Zz]|[+\-][0-9]{2}\:[0-9]{2}) # UTC Offset +DD:MM or 'Z' indicating UTC-0 |
|
133
|
|
|
|
|
|
|
))/x, |
|
134
|
|
|
|
|
|
|
host => qr/^\s*([^:\s]+)\s+/, |
|
135
|
|
|
|
|
|
|
cisco_hates_you => qr/^\s*[0-9]*:\s+/, |
|
136
|
|
|
|
|
|
|
program_raw => qr/^\s*([^\[][^:]+):\s*/, |
|
137
|
|
|
|
|
|
|
program_name => qr/^([^\[\(\ ]+)/, |
|
138
|
|
|
|
|
|
|
program_sub => qr/(?>\(([^\)]+)\))/, |
|
139
|
|
|
|
|
|
|
program_pid => qr/(?>\[([^\]]+)\])/, |
|
140
|
|
|
|
|
|
|
program_netapp => qr/(?>\[([^\]]+)\]:\s*)/, |
|
141
|
|
|
|
|
|
|
); |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
my %_empty_msg = map { $_ => undef } qw( |
|
145
|
|
|
|
|
|
|
preamble priority priority_int facility facility_int |
|
146
|
|
|
|
|
|
|
datetime_raw date_raw date time datetime_str datetime_obj epoch |
|
147
|
|
|
|
|
|
|
host_raw host domain |
|
148
|
|
|
|
|
|
|
program_raw program_name program_pid program_sub |
|
149
|
|
|
|
|
|
|
); |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
my $SYSLOG_TIMEZONE = ''; |
|
153
|
|
|
|
|
|
|
my $DateTimeTried = 0; |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub parse_syslog_line { |
|
156
|
83
|
|
|
83
|
1
|
101242
|
my ($raw_string) = @_; |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Initialize everything to undef |
|
159
|
83
|
100
|
|
|
|
802
|
my %msg = $PruneEmpty ? () : %_empty_msg; |
|
160
|
83
|
100
|
|
|
|
332
|
$msg{message_raw} = $raw_string unless $PruneRaw; |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
# |
|
163
|
|
|
|
|
|
|
# grab the preamble: |
|
164
|
83
|
100
|
|
|
|
557
|
if( $raw_string =~ s/$RE{preamble}//o ) { |
|
165
|
|
|
|
|
|
|
# Cast to integer |
|
166
|
54
|
|
|
|
|
200
|
$msg{preamble} = int $1; |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
# Extract Integers |
|
169
|
54
|
|
|
|
|
130
|
$msg{priority_int} = $msg{preamble} & $CONV_MASK{priority}; |
|
170
|
54
|
|
|
|
|
99
|
$msg{facility_int} = $msg{preamble} & $CONV_MASK{facility}; |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
# Lookups |
|
173
|
54
|
|
|
|
|
163
|
$msg{priority} = $LOG_PRIORITY{ $msg{priority_int} }; |
|
174
|
54
|
|
|
|
|
142
|
$msg{facility} = $LOG_FACILITY{ $msg{facility_int} }; |
|
175
|
|
|
|
|
|
|
} |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# |
|
178
|
|
|
|
|
|
|
# Handle Date/Time |
|
179
|
83
|
|
|
|
|
154
|
my $year; |
|
180
|
83
|
100
|
|
|
|
456
|
if( $raw_string =~ s/$RE{year}//o ) { |
|
181
|
3
|
|
|
|
|
14
|
$year = $1; |
|
182
|
|
|
|
|
|
|
} |
|
183
|
83
|
100
|
|
|
|
666
|
if( $raw_string =~ s/$RE{date}//o) { |
|
|
|
50
|
|
|
|
|
|
|
184
|
65
|
|
|
|
|
193
|
$msg{datetime_raw} = $1; |
|
185
|
65
|
100
|
|
|
|
168
|
$msg{datetime_raw} .= " $year" |
|
186
|
|
|
|
|
|
|
if $year; |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
elsif( $raw_string =~ s/$RE{date_iso8601}//o) { |
|
189
|
18
|
|
|
|
|
65
|
$msg{datetime_raw} = $1; |
|
190
|
|
|
|
|
|
|
} |
|
191
|
83
|
50
|
33
|
|
|
447
|
if( exists $msg{datetime_raw} && length $msg{datetime_raw} ) { |
|
192
|
83
|
|
|
|
|
165
|
$msg{date_raw} = $msg{datetime_raw}; |
|
193
|
|
|
|
|
|
|
|
|
194
|
83
|
50
|
|
|
|
201
|
if ( $DateParsing ) { |
|
195
|
|
|
|
|
|
|
# if User wants to fight with dates himself, let him :) |
|
196
|
83
|
100
|
66
|
|
|
310
|
if( $FmtDate && ref $FmtDate eq 'CODE' ) { |
|
197
|
20
|
|
|
|
|
64
|
@msg{qw(date time epoch datetime_str)} = $FmtDate->($msg{datetime_raw}); |
|
198
|
|
|
|
|
|
|
} |
|
199
|
|
|
|
|
|
|
else { |
|
200
|
|
|
|
|
|
|
# Parse the Epoch |
|
201
|
63
|
|
|
|
|
222
|
$msg{epoch} = HTTP::Date::str2time($msg{datetime_raw}); |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
# Format accordingly, keep highest resolution we can |
|
204
|
63
|
|
|
|
|
8926
|
my $diff = ($msg{epoch} - int($msg{epoch})); |
|
205
|
63
|
100
|
|
|
|
263
|
my $hires = $diff > 0 ? substr(sprintf('%0.6f', $diff),1) : ''; |
|
206
|
63
|
100
|
|
|
|
241
|
my $tm_fmt = '%FT%T' . $hires . ( $OutputTimeZone ? ($SYSLOG_TIMEZONE eq 'UTC' ? 'Z' : '%z') : '' ); |
|
|
|
100
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# Set the Date Strings |
|
209
|
|
|
|
|
|
|
$msg{datetime_str} = $NormalizeToUTC ? strftime($tm_fmt, gmtime $msg{epoch}) |
|
210
|
63
|
100
|
|
|
|
655
|
: strftime($tm_fmt, localtime $msg{epoch}); |
|
211
|
|
|
|
|
|
|
# Split this up into parts |
|
212
|
63
|
|
|
|
|
1276
|
my @parts = split /[ T]/, $msg{datetime_str}; |
|
213
|
63
|
|
|
|
|
150
|
$msg{date} = $parts[0]; |
|
214
|
63
|
|
|
|
|
204
|
$msg{time} = (split /[+\-Z]/, $parts[1])[0]; |
|
215
|
63
|
100
|
|
|
|
349
|
$msg{offset} = $NormalizeToUTC ? 'Z' |
|
|
|
100
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
: $parts[1] =~ /([Z+\-].*)/ ? $1 |
|
217
|
|
|
|
|
|
|
: $SYSLOG_TIMEZONE; |
|
218
|
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
# Debugging for my sanity |
|
220
|
|
|
|
|
|
|
printf("TZ=%s Parsed: %s to [%s] %s D:%s T:%s O:%s\n", |
|
221
|
|
|
|
|
|
|
$SYSLOG_TIMEZONE, |
|
222
|
|
|
|
|
|
|
@msg{qw(datetime_raw epoch datetime_str date time offset)}, |
|
223
|
63
|
50
|
|
|
|
244
|
) if $ENV{DEBUG_PARSE_SYSLOG_LINE}; |
|
224
|
|
|
|
|
|
|
} |
|
225
|
|
|
|
|
|
|
# Use Module::Load to runtime load the DateTime libraries *if* necessary |
|
226
|
83
|
100
|
|
|
|
403
|
if( $DateTimeCreate ) { |
|
227
|
6
|
100
|
66
|
|
|
244
|
unless( $DateTimeTried && is_loaded('DateTime') ) { |
|
228
|
1
|
|
|
|
|
36
|
warn "DateTime seriously degrades performance, please start using 'epoch' and/or 'datetime_str' instead."; |
|
229
|
|
|
|
|
|
|
eval { |
|
230
|
1
|
|
|
|
|
11
|
load DateTime; |
|
231
|
1
|
|
|
|
|
115
|
1; |
|
232
|
1
|
50
|
|
|
|
6
|
} or do { |
|
233
|
0
|
|
|
|
|
0
|
my $err = $@; |
|
234
|
0
|
|
|
|
|
0
|
warn "DateTime unavailable, disabling it: $err"; |
|
235
|
0
|
|
|
|
|
0
|
$DateTimeCreate = 0; |
|
236
|
|
|
|
|
|
|
}; |
|
237
|
1
|
|
|
|
|
3
|
$DateTimeTried++; |
|
238
|
|
|
|
|
|
|
} |
|
239
|
6
|
50
|
|
|
|
103
|
eval { |
|
240
|
6
|
|
|
|
|
165
|
my %args = (epoch => $msg{epoch}); |
|
241
|
6
|
50
|
|
|
|
21
|
$args{time_zone} = $SYSLOG_TIMEZONE if $SYSLOG_TIMEZONE; |
|
242
|
6
|
|
|
|
|
39
|
$msg{datetime_obj} = DateTime->from_epoch(%args); |
|
243
|
|
|
|
|
|
|
} if $DateTimeCreate; |
|
244
|
|
|
|
|
|
|
} |
|
245
|
|
|
|
|
|
|
} |
|
246
|
|
|
|
|
|
|
} |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# |
|
249
|
|
|
|
|
|
|
# Host Information: |
|
250
|
83
|
100
|
|
|
|
16786
|
if( $raw_string =~ s/$RE{host}//o ) { |
|
251
|
80
|
|
|
|
|
211
|
my $hostStr = $1; |
|
252
|
80
|
|
|
|
|
394
|
my($ip) = ($hostStr =~ /($RE{IPv4})/o); |
|
253
|
80
|
100
|
66
|
|
|
392
|
if( defined $ip && length $ip ) { |
|
|
|
50
|
|
|
|
|
|
|
254
|
21
|
|
|
|
|
55
|
$msg{host_raw} = $hostStr; |
|
255
|
21
|
|
|
|
|
58
|
$msg{host} = $ip; |
|
256
|
|
|
|
|
|
|
} |
|
257
|
|
|
|
|
|
|
elsif( length $hostStr ) { |
|
258
|
59
|
|
|
|
|
186
|
my ($host,$domain) = split /\./, $hostStr, 2; |
|
259
|
59
|
|
|
|
|
138
|
$msg{host_raw} = $hostStr; |
|
260
|
59
|
|
|
|
|
101
|
$msg{host} = $host; |
|
261
|
59
|
|
|
|
|
130
|
$msg{domain} = $domain; |
|
262
|
|
|
|
|
|
|
} |
|
263
|
|
|
|
|
|
|
} |
|
264
|
83
|
100
|
|
|
|
372
|
if( $raw_string =~ s/$RE{cisco_hates_you}//o ) { |
|
265
|
|
|
|
|
|
|
# Yes, Cisco adds a second timestamp to it's messages, because it hates you. |
|
266
|
23
|
100
|
|
|
|
170
|
if( $raw_string =~ s/$RE{date_long}//o ) { |
|
267
|
|
|
|
|
|
|
# Cisco encodes the status of NTP in the second datestamp, so let's pass it back |
|
268
|
17
|
100
|
|
|
|
54
|
if ( my $ntp = $1 ) { |
|
269
|
6
|
50
|
|
|
|
29
|
$msg{ntp} = $ntp eq '.' ? 'out of sync' |
|
|
|
100
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
: $ntp eq '*' ? 'not configured' |
|
271
|
|
|
|
|
|
|
: 'unknown'; |
|
272
|
|
|
|
|
|
|
} |
|
273
|
|
|
|
|
|
|
else { |
|
274
|
11
|
|
|
|
|
29
|
$msg{ntp} = 'ok'; |
|
275
|
|
|
|
|
|
|
} |
|
276
|
|
|
|
|
|
|
} |
|
277
|
|
|
|
|
|
|
} |
|
278
|
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
# |
|
280
|
|
|
|
|
|
|
# Parse the Program portion |
|
281
|
83
|
100
|
|
|
|
185
|
if( $ExtractProgram ) { |
|
282
|
63
|
100
|
|
|
|
310
|
if( $raw_string =~ s/$RE{program_raw}//o ) { |
|
|
|
50
|
|
|
|
|
|
|
283
|
57
|
|
|
|
|
159
|
$msg{program_raw} = $1; |
|
284
|
57
|
|
|
|
|
194
|
my $progStr = join ' ', grep {!exists $INT_PRIORITY{$_}} split /\s+/, $msg{program_raw}; |
|
|
68
|
|
|
|
|
262
|
|
|
285
|
57
|
50
|
33
|
|
|
288
|
if( defined $progStr && length $progStr) { |
|
286
|
57
|
50
|
|
|
|
262
|
if( ($msg{program_name}) = ($progStr =~ /$RE{program_name}/o) ) { |
|
287
|
57
|
100
|
|
|
|
173
|
if (length $msg{program_name} != length $msg{program_raw} ) { |
|
288
|
|
|
|
|
|
|
(($msg{program_pid}) = ($progStr =~ /$RE{program_pid}/o)) |
|
289
|
14
|
100
|
|
|
|
92
|
|| (($msg{program_sub}) = ($progStr =~ /$RE{program_sub}/o)) |
|
290
|
|
|
|
|
|
|
} |
|
291
|
|
|
|
|
|
|
} |
|
292
|
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
} |
|
294
|
|
|
|
|
|
|
elsif( $raw_string =~ s/$RE{program_netapp}//o ) { |
|
295
|
|
|
|
|
|
|
# Check for a [host thing.subthing:level]: tag |
|
296
|
|
|
|
|
|
|
# or [host:thing.subthing:level]: tag, Thanks NetApp. |
|
297
|
6
|
|
|
|
|
16
|
my $subStr = $1; |
|
298
|
6
|
|
|
|
|
15
|
$msg{program_raw} = qq{[$subStr]}; |
|
299
|
6
|
|
|
|
|
26
|
my ($host,$program,$level) = split /[: ]+/, $subStr; |
|
300
|
6
|
|
|
|
|
15
|
$msg{program_name} = $program; |
|
301
|
6
|
0
|
33
|
|
|
17
|
if(!exists $msg{priority} && exists $LOG_PRIORITY{$level}) { |
|
302
|
0
|
|
|
|
|
0
|
$msg{priority} = $level; |
|
303
|
0
|
|
|
|
|
0
|
$msg{priority_int} = $LOG_PRIORITY{$level}; |
|
304
|
|
|
|
|
|
|
} |
|
305
|
6
|
|
|
|
|
15
|
$raw_string =~ s/^[ :]+//; |
|
306
|
|
|
|
|
|
|
} |
|
307
|
|
|
|
|
|
|
} |
|
308
|
|
|
|
|
|
|
else { |
|
309
|
20
|
|
|
|
|
58
|
$raw_string =~ s/^\s+//; |
|
310
|
|
|
|
|
|
|
} |
|
311
|
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
# The left overs should be the message |
|
313
|
83
|
|
|
|
|
176
|
$msg{content} = $raw_string; |
|
314
|
83
|
|
|
|
|
176
|
chomp $msg{content}; |
|
315
|
83
|
100
|
|
|
|
269
|
$msg{message} = defined $msg{program_raw} ? "$msg{program_raw}: $msg{content}" : $msg{content}; |
|
316
|
|
|
|
|
|
|
|
|
317
|
83
|
100
|
|
|
|
193
|
if( $PruneRaw ) { |
|
318
|
9
|
|
|
|
|
36
|
delete $msg{$_} for grep { $_ =~ /_raw$/ } keys %msg; |
|
|
158
|
|
|
|
|
321
|
|
|
319
|
|
|
|
|
|
|
} |
|
320
|
83
|
100
|
|
|
|
200
|
if( $PruneEmpty ) { |
|
321
|
9
|
|
|
|
|
26
|
delete $msg{$_} for grep { !defined $msg{$_} } keys %msg; |
|
|
122
|
|
|
|
|
205
|
|
|
322
|
|
|
|
|
|
|
} |
|
323
|
83
|
50
|
|
|
|
209
|
if( @PruneFields ) { |
|
324
|
4
|
|
|
4
|
|
10100
|
no warnings; |
|
|
4
|
|
|
|
|
13
|
|
|
|
4
|
|
|
|
|
2161
|
|
|
325
|
0
|
|
|
|
|
0
|
delete $msg{$_} for @PruneFields; |
|
326
|
|
|
|
|
|
|
} |
|
327
|
83
|
50
|
33
|
|
|
367
|
delete $msg{epoch} if exists $msg{epoch} and !$EpochCreate; |
|
328
|
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
# |
|
330
|
|
|
|
|
|
|
# Return our hash reference! |
|
331
|
83
|
|
|
|
|
250
|
return \%msg; |
|
332
|
|
|
|
|
|
|
} |
|
333
|
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
sub preamble_priority { |
|
336
|
0
|
|
|
0
|
1
|
0
|
my $preamble = int shift; |
|
337
|
|
|
|
|
|
|
|
|
338
|
0
|
|
|
|
|
0
|
my %hash = ( |
|
339
|
|
|
|
|
|
|
preamble => $preamble, |
|
340
|
|
|
|
|
|
|
); |
|
341
|
|
|
|
|
|
|
|
|
342
|
0
|
|
|
|
|
0
|
$hash{as_int} = $preamble & $CONV_MASK{priority}; |
|
343
|
0
|
|
|
|
|
0
|
$hash{as_text} = $LOG_PRIORITY{ $hash{as_int} }; |
|
344
|
|
|
|
|
|
|
|
|
345
|
0
|
|
|
|
|
0
|
return \%hash; |
|
346
|
|
|
|
|
|
|
} |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
sub preamble_facility { |
|
350
|
0
|
|
|
0
|
1
|
0
|
my $preamble = int shift; |
|
351
|
|
|
|
|
|
|
|
|
352
|
0
|
|
|
|
|
0
|
my %hash = ( |
|
353
|
|
|
|
|
|
|
preamble => $preamble, |
|
354
|
|
|
|
|
|
|
); |
|
355
|
|
|
|
|
|
|
|
|
356
|
0
|
|
|
|
|
0
|
$hash{as_int} = $preamble & $CONV_MASK{facility}; |
|
357
|
0
|
|
|
|
|
0
|
$hash{as_text} = $LOG_FACILITY{ $hash{as_int} }; |
|
358
|
|
|
|
|
|
|
|
|
359
|
0
|
|
|
|
|
0
|
return \%hash; |
|
360
|
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
} |
|
362
|
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
sub set_syslog_timezone { |
|
364
|
7
|
|
|
7
|
1
|
21419
|
my ( $tz_name ) = @_; |
|
365
|
|
|
|
|
|
|
|
|
366
|
7
|
50
|
66
|
|
|
63
|
if( defined $tz_name && (!exists $ENV{TZ} || $tz_name ne $ENV{TZ}) ) { |
|
|
|
|
66
|
|
|
|
|
|
367
|
7
|
|
|
|
|
56
|
$ENV{TZ} = $SYSLOG_TIMEZONE = $tz_name; |
|
368
|
7
|
|
|
|
|
589
|
tzset(); |
|
369
|
7
|
|
|
|
|
38
|
$OutputTimeZone = 1; |
|
370
|
|
|
|
|
|
|
# Output some useful debug information |
|
371
|
|
|
|
|
|
|
printf("set_syslog_timezone('%s') results in a timezone of '%s' with offset: %s\n", |
|
372
|
|
|
|
|
|
|
$tz_name, |
|
373
|
|
|
|
|
|
|
strftime('%Z', localtime), |
|
374
|
|
|
|
|
|
|
strftime('%z', localtime), |
|
375
|
7
|
50
|
|
|
|
26
|
) if $ENV{DEBUG_PARSE_SYSLOG_LINE}; |
|
376
|
|
|
|
|
|
|
} |
|
377
|
|
|
|
|
|
|
|
|
378
|
7
|
|
|
|
|
20
|
return $SYSLOG_TIMEZONE; |
|
379
|
|
|
|
|
|
|
} |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
sub get_syslog_timezone { |
|
382
|
1
|
|
|
1
|
1
|
738
|
return $SYSLOG_TIMEZONE; |
|
383
|
|
|
|
|
|
|
} |
|
384
|
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
# If you have a syslog which logs dates in UTC, then processing will be much, much faster |
|
386
|
|
|
|
|
|
|
sub use_utc_syslog { |
|
387
|
1
|
|
|
1
|
1
|
4118
|
set_syslog_timezone('UTC'); |
|
388
|
1
|
|
|
|
|
2
|
$NormalizeToUTC = 1; |
|
389
|
1
|
|
|
|
|
3
|
return; |
|
390
|
|
|
|
|
|
|
} |
|
391
|
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
1; # End of Parse::Syslog::Line |
|
393
|
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
__END__ |
|
395
|
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=pod |
|
397
|
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
=encoding UTF-8 |
|
399
|
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
=head1 NAME |
|
401
|
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
Parse::Syslog::Line - Simple syslog line parser |
|
403
|
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
=head1 VERSION |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
version 4.0 |
|
407
|
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
I wanted a very simple log parser for network based syslog input. |
|
411
|
|
|
|
|
|
|
Nothing existed that simply took a line and returned a hash ref all |
|
412
|
|
|
|
|
|
|
parsed out. |
|
413
|
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
use Parse::Syslog::Line qw(parse_syslog_line); |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
$Parse::Syslog::Line::DateTimeCreate = 1; |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
my $href = parse_syslog_line( $msg ); |
|
419
|
|
|
|
|
|
|
# |
|
420
|
|
|
|
|
|
|
# $href = { |
|
421
|
|
|
|
|
|
|
# preamble => '13', |
|
422
|
|
|
|
|
|
|
# priority => 'notice', |
|
423
|
|
|
|
|
|
|
# priority_int => 5, |
|
424
|
|
|
|
|
|
|
# facility => 'user', |
|
425
|
|
|
|
|
|
|
# facility_int => 8, |
|
426
|
|
|
|
|
|
|
# date => 'YYYY-MM-DD', |
|
427
|
|
|
|
|
|
|
# time => 'HH::MM:SS', |
|
428
|
|
|
|
|
|
|
# epoch => 1361095933, |
|
429
|
|
|
|
|
|
|
# datetime_str => ISO 8601 datetime, $NormalizeToUTC = 1 then UTC, else local |
|
430
|
|
|
|
|
|
|
# datetime_obj => undef, # If $DateTimeCreate = 1, else undef |
|
431
|
|
|
|
|
|
|
# datetime_raw => 'Feb 17 11:12:13' |
|
432
|
|
|
|
|
|
|
# date_raw => 'Feb 17 11:12:13' |
|
433
|
|
|
|
|
|
|
# host_raw => 'hostname', # Hostname as it appeared in the message |
|
434
|
|
|
|
|
|
|
# host => 'hostname', # Hostname without domain |
|
435
|
|
|
|
|
|
|
# domain => 'blah.com', # if provided |
|
436
|
|
|
|
|
|
|
# program_raw => 'sshd(blah)[pid]', |
|
437
|
|
|
|
|
|
|
# program_name => 'sshd', |
|
438
|
|
|
|
|
|
|
# program_sub => 'pam_unix', |
|
439
|
|
|
|
|
|
|
# program_pid => 20345, |
|
440
|
|
|
|
|
|
|
# content => 'the rest of the message' |
|
441
|
|
|
|
|
|
|
# message => 'program[pid]: the rest of the message', |
|
442
|
|
|
|
|
|
|
# message_raw => 'The message as it was passed', |
|
443
|
|
|
|
|
|
|
# ntp => 'ok', # Only set for Cisco messages |
|
444
|
|
|
|
|
|
|
# }; |
|
445
|
|
|
|
|
|
|
... |
|
446
|
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
=head1 EXPORT |
|
448
|
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
Exported by default: |
|
450
|
|
|
|
|
|
|
parse_syslog_line( $one_line_of_syslog_message ); |
|
451
|
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
Optional Exports: |
|
453
|
|
|
|
|
|
|
:preamble |
|
454
|
|
|
|
|
|
|
preamble_priority |
|
455
|
|
|
|
|
|
|
preamble_facility |
|
456
|
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
:constants |
|
458
|
|
|
|
|
|
|
%LOG_FACILITY |
|
459
|
|
|
|
|
|
|
%LOG_PRIORITY |
|
460
|
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
:with_timezones |
|
462
|
|
|
|
|
|
|
set_syslog_timezone |
|
463
|
|
|
|
|
|
|
get_syslog_timezone |
|
464
|
|
|
|
|
|
|
use_utc_syslog |
|
465
|
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
=head1 VARIABLES |
|
467
|
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
=head2 ExtractProgram |
|
469
|
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
If this variable is set to 1 (the default), parse_syslog_line() will try it's |
|
471
|
|
|
|
|
|
|
best to extract a "program" field from the input. This is the most expensive |
|
472
|
|
|
|
|
|
|
set of regex in the module, so if you don't need that pre-parsed, you can speed |
|
473
|
|
|
|
|
|
|
the module up significantly by setting this variable. |
|
474
|
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
Vendors who do proprietary non-sense with their syslog formats are to blame for |
|
476
|
|
|
|
|
|
|
this setting. |
|
477
|
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
Usage: |
|
479
|
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
$Parse::Syslog::Line::ExtractProgram = 0; |
|
481
|
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
=head2 DateParsing |
|
483
|
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
If this variable is set to 0 raw date will not be parsed further into components (datetime_str date time epoch). |
|
485
|
|
|
|
|
|
|
Default is 1 (parsing enabled). |
|
486
|
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
Usage: |
|
488
|
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
$Parse::Syslog::Line::DateParsing = 0; |
|
490
|
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=head2 DateTimeCreate |
|
492
|
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
If this variable is set to 1 (the default), a DateTime object will be returned in the |
|
494
|
|
|
|
|
|
|
$m->{datetime_obj} field. Otherwise, this will be skipped. |
|
495
|
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
NOTE: DateTime timezone calculation is fairly slow. Unless you really need to |
|
497
|
|
|
|
|
|
|
take timezones into account, you're better off using other modes (below). |
|
498
|
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
Usage: |
|
500
|
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
$Parse::Syslog::Line::DateTimeCreate = 0; |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=head2 EpochCreate |
|
504
|
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
If this variable is set to 1, the default, the number of seconds from UNIX |
|
506
|
|
|
|
|
|
|
epoch will be returned in the $m->{epoch} field. Setting this to false will |
|
507
|
|
|
|
|
|
|
only delete the epoch before returning the hash reference. |
|
508
|
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
=head2 NormalizeToUTC |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
When set, the datetime_str will be ISO8601 UTC. |
|
512
|
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
=head2 OutputTimeZones |
|
514
|
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
Default is false, but is enabled if you call set_syslog_timezone() or |
|
516
|
|
|
|
|
|
|
use_utc_syslog(). If enabled, this will append the timezone offset to the |
|
517
|
|
|
|
|
|
|
datetime_str. |
|
518
|
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=head2 FmtDate |
|
520
|
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
You can pass your own formatter/parser here. Given a raw datetime string it |
|
522
|
|
|
|
|
|
|
should output a list containing date, time, epoch, datetime_str, |
|
523
|
|
|
|
|
|
|
in your wanted format. |
|
524
|
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
use Parse::Syslog::Line; |
|
526
|
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
local $Parse::Syslog::Line::FmtDate = sub { |
|
528
|
|
|
|
|
|
|
my ($raw_datestr) = @_; |
|
529
|
|
|
|
|
|
|
my @elements = ( |
|
530
|
|
|
|
|
|
|
#date |
|
531
|
|
|
|
|
|
|
#time |
|
532
|
|
|
|
|
|
|
#epoch |
|
533
|
|
|
|
|
|
|
#datetime_str |
|
534
|
|
|
|
|
|
|
); |
|
535
|
|
|
|
|
|
|
return @elements; |
|
536
|
|
|
|
|
|
|
}; |
|
537
|
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
B<NOTE>: No further date processing will be done, you're on your own here. |
|
539
|
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
=head2 PruneRaw |
|
541
|
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
This variable defaults to 0, set to 1 to delete all keys in the return hash ending in "_raw" |
|
543
|
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
Usage: |
|
545
|
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
$Parse::Syslog::Line::PruneRaw = 1; |
|
547
|
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
=head2 PruneEmpty |
|
549
|
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
This variable defaults to 0, set to 1 to delete all keys in the return hash which are undefined. |
|
551
|
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
Usage: |
|
553
|
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
$Parse::Syslog::Line::PruneEmpty = 1; |
|
555
|
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
=head2 PruneFields |
|
557
|
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
This should be an array of fields you'd like to be removed from the hash reference. |
|
559
|
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
Usage: |
|
561
|
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
@Parse::Syslog::Line::PruneFields = qw(date_raw facility_int priority_int); |
|
563
|
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
565
|
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
=head2 parse_syslog_line |
|
567
|
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
Returns a hash reference of syslog message parsed data. |
|
569
|
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
B<NOTE>: Date/time parsing is hard. This module has been optimized to balance |
|
571
|
|
|
|
|
|
|
common sense and processing speed. Care is taken to ensure that any data input |
|
572
|
|
|
|
|
|
|
into the system isn't lost, but with the varieties of vendor and admin crafted |
|
573
|
|
|
|
|
|
|
date formats, we don't always get it right. Feel free to override date |
|
574
|
|
|
|
|
|
|
processing using by setting the $FmtDate variable or completely disable it with |
|
575
|
|
|
|
|
|
|
$DateParsing set to 0. |
|
576
|
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
=head2 set_syslog_timezone($timezone_name) |
|
578
|
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
Sets a timezone $timezone_name for parsed messages. This timezone will be used |
|
580
|
|
|
|
|
|
|
to calculate offset from UTC if a timezone designation is not present in the |
|
581
|
|
|
|
|
|
|
message being parsed. This timezone will also serve as the source timezone for |
|
582
|
|
|
|
|
|
|
the datetime_str field. |
|
583
|
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
=head2 get_syslog_timezone |
|
585
|
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
Returns the name of the timezone currently set by set_syslog_timezone. |
|
587
|
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
=head2 use_utc_syslog |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
A convenient function which sets the syslog timezone to UTC and sets the config |
|
591
|
|
|
|
|
|
|
variables accordingly. Automatically sets $NormaizeToUTC and datetime_str will |
|
592
|
|
|
|
|
|
|
be set to the UTC equivalent. |
|
593
|
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
=head2 preamble_priority |
|
595
|
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
Takes the Integer portion of the syslog messsage and returns |
|
597
|
|
|
|
|
|
|
a hash reference as such: |
|
598
|
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
$prioRef = { |
|
600
|
|
|
|
|
|
|
'preamble' => 13 |
|
601
|
|
|
|
|
|
|
'as_text' => 'notice', |
|
602
|
|
|
|
|
|
|
'as_int' => 5, |
|
603
|
|
|
|
|
|
|
}; |
|
604
|
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
=head2 preamble_facility |
|
606
|
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
Takes the Integer portion of the syslog messsage and returns |
|
608
|
|
|
|
|
|
|
a hash reference as such: |
|
609
|
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
$facRef = { |
|
611
|
|
|
|
|
|
|
'preamble' => 13 |
|
612
|
|
|
|
|
|
|
'as_text' => 'user', |
|
613
|
|
|
|
|
|
|
'as_int' => 8, |
|
614
|
|
|
|
|
|
|
}; |
|
615
|
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
=head1 DEVELOPMENT |
|
617
|
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
This module is developed with Dist::Zilla. To build from the repository, use Dist::Zilla: |
|
619
|
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
dzil authordeps --missing |cpanm |
|
621
|
|
|
|
|
|
|
dzil listdeps --missing |cpanm |
|
622
|
|
|
|
|
|
|
dzil build |
|
623
|
|
|
|
|
|
|
dzil test |
|
624
|
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
=head1 AUTHOR |
|
626
|
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
Brad Lhotsky <brad@divisionbyzero.net> |
|
628
|
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
This software is Copyright (c) 2017 by Brad Lhotsky. |
|
632
|
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
This is free software, licensed under: |
|
634
|
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
The (three-clause) BSD License |
|
636
|
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
=head1 CONTRIBUTORS |
|
638
|
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
=for stopwords BartÅomiej Fulanty Csillag Tamas Keedi Kim Mateu X Hunter Neil Bowers Shawn Wilson Tomohiro Hosaka |
|
640
|
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
=over 4 |
|
642
|
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
=item * |
|
644
|
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
BartÅomiej Fulanty <starlight@cpan.org> |
|
646
|
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
=item * |
|
648
|
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
Csillag Tamas <cstamas@digitus.itk.ppke.hu> |
|
650
|
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
=item * |
|
652
|
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
Keedi Kim <keedi.k@gmail.com> |
|
654
|
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
=item * |
|
656
|
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
Mateu X Hunter <mhunter@maxmind.com> |
|
658
|
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
=item * |
|
660
|
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
Neil Bowers <neil@bowers.com> |
|
662
|
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
=item * |
|
664
|
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
Shawn Wilson <swilson@korelogic.com> |
|
666
|
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
=item * |
|
668
|
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
Tomohiro Hosaka <bokutin@bokut.in> |
|
670
|
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
=back |
|
672
|
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan |
|
674
|
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
=head1 SUPPORT |
|
676
|
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
=head2 Websites |
|
678
|
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
The following websites have more information about this module, and may be of help to you. As always, |
|
680
|
|
|
|
|
|
|
in addition to those websites please use your favorite search engine to discover more resources. |
|
681
|
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
=over 4 |
|
683
|
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
=item * |
|
685
|
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
MetaCPAN |
|
687
|
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
A modern, open-source CPAN search engine, useful to view POD in HTML format. |
|
689
|
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
L<http://metacpan.org/release/Parse-Syslog-Line> |
|
691
|
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
=item * |
|
693
|
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
RT: CPAN's Bug Tracker |
|
695
|
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
The RT ( Request Tracker ) website is the default bug/issue tracking system for CPAN. |
|
697
|
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
L<https://rt.cpan.org/Public/Dist/Display.html?Name=Parse-Syslog-Line> |
|
699
|
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
=back |
|
701
|
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
=head2 Source Code |
|
703
|
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
This module's source code is available by visiting: |
|
705
|
|
|
|
|
|
|
L<https://github.com/reyjrar/Parse-Syslog-Line> |
|
706
|
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
=cut |