📄 syslog.pm
字号:
}}sub connect_tcp { my ($errs) = @_; my $tcp = getprotobyname('tcp'); if (!defined $tcp) { push @$errs, "getprotobyname failed for tcp"; return 0; } my $syslog = getservbyname('syslog', 'tcp'); $syslog = getservbyname('syslogng', 'tcp') unless defined $syslog; if (!defined $syslog) { push @$errs, "getservbyname failed for syslog/tcp and syslogng/tcp"; return 0; } my $addr; if (defined $host) { $addr = inet_aton($host); if (!$addr) { push @$errs, "can't lookup $host"; return 0; } } else { $addr = INADDR_LOOPBACK; } $addr = sockaddr_in($syslog, $addr); if (!socket(SYSLOG, AF_INET, SOCK_STREAM, $tcp)) { push @$errs, "tcp socket: $!"; return 0; } setsockopt(SYSLOG, SOL_SOCKET, SO_KEEPALIVE, 1); if (eval { IPPROTO_TCP() }) { # These constants don't exist in 5.005. They were added in 1999 setsockopt(SYSLOG, IPPROTO_TCP(), TCP_NODELAY(), 1); } $@ = ""; if (!connect(SYSLOG, $addr)) { push @$errs, "tcp connect: $!"; return 0; } $syslog_send = \&_syslog_send_socket; return 1;}sub connect_udp { my ($errs) = @_; my $udp = getprotobyname('udp'); if (!defined $udp) { push @$errs, "getprotobyname failed for udp"; return 0; } my $syslog = getservbyname('syslog', 'udp'); if (!defined $syslog) { push @$errs, "getservbyname failed for syslog/udp"; return 0; } my $addr; if (defined $host) { $addr = inet_aton($host); if (!$addr) { push @$errs, "can't lookup $host"; return 0; } } else { $addr = INADDR_LOOPBACK; } $addr = sockaddr_in($syslog, $addr); if (!socket(SYSLOG, AF_INET, SOCK_DGRAM, $udp)) { push @$errs, "udp socket: $!"; return 0; } if (!connect(SYSLOG, $addr)) { push @$errs, "udp connect: $!"; return 0; } # We want to check that the UDP connect worked. However the only # way to do that is to send a message and see if an ICMP is returned _syslog_send_socket(""); if (!connection_ok()) { push @$errs, "udp connect: nobody listening"; return 0; } $syslog_send = \&_syslog_send_socket; return 1;}sub connect_stream { my ($errs) = @_; # might want syslog_path to be variable based on syslog.h (if only # it were in there!) $syslog_path = '/dev/conslog' unless defined $syslog_path; if (!-w $syslog_path) { push @$errs, "stream $syslog_path is not writable"; return 0; } if (!sysopen(SYSLOG, $syslog_path, 0400, O_WRONLY)) { push @$errs, "stream can't open $syslog_path: $!"; return 0; } $syslog_send = \&_syslog_send_stream; return 1;}sub connect_pipe { my ($errs) = @_; $syslog_path ||= &_PATH_LOG || "/dev/log"; if (not -w $syslog_path) { push @$errs, "$syslog_path is not writable"; return 0; } if (not open(SYSLOG, ">$syslog_path")) { push @$errs, "can't write to $syslog_path: $!"; return 0; } $syslog_send = \&_syslog_send_pipe; return 1;}sub connect_unix { my ($errs) = @_; $syslog_path ||= _PATH_LOG() if length _PATH_LOG(); if (not defined $syslog_path) { push @$errs, "_PATH_LOG not available in syslog.h and no user-supplied socket path"; return 0; } if (not (-S $syslog_path or -c _)) { push @$errs, "$syslog_path is not a socket"; return 0; } my $addr = sockaddr_un($syslog_path); if (!$addr) { push @$errs, "can't locate $syslog_path"; return 0; } if (!socket(SYSLOG, AF_UNIX, SOCK_STREAM, 0)) { push @$errs, "unix stream socket: $!"; return 0; } if (!connect(SYSLOG, $addr)) { if (!socket(SYSLOG, AF_UNIX, SOCK_DGRAM, 0)) { push @$errs, "unix dgram socket: $!"; return 0; } if (!connect(SYSLOG, $addr)) { push @$errs, "unix dgram connect: $!"; return 0; } } $syslog_send = \&_syslog_send_socket; return 1;}sub connect_native { my ($errs) = @_; my $logopt = 0; # reconstruct the numeric equivalent of the options for my $opt (keys %options) { $logopt += xlate($opt) if $options{$opt} } eval { openlog_xs($ident, $logopt, xlate($facility)) }; if ($@) { push @$errs, $@; return 0; } $syslog_send = \&_syslog_send_native; return 1;}sub connect_eventlog { my ($errs) = @_; $syslog_xobj = Sys::Syslog::Win32::_install(); $syslog_send = \&Sys::Syslog::Win32::_syslog_send; return 1;}sub connect_console { my ($errs) = @_; if (!-w '/dev/console') { push @$errs, "console is not writable"; return 0; } $syslog_send = \&_syslog_send_console; return 1;}# To test if the connection is still good, we need to check if any# errors are present on the connection. The errors will not be raised# by a write. Instead, sockets are made readable and the next read# would cause the error to be returned. Unfortunately the syslog # 'protocol' never provides anything for us to read. But with # judicious use of select(), we can see if it would be readable...sub connection_ok { return 1 if defined $current_proto and ( $current_proto eq 'native' or $current_proto eq 'console' or $current_proto eq 'eventlog' ); my $rin = ''; vec($rin, fileno(SYSLOG), 1) = 1; my $ret = select $rin, undef, $rin, 0.25; return ($ret ? 0 : 1);}sub disconnect_log { $connected = 0; $syslog_send = undef; if (defined $current_proto and $current_proto eq 'native') { closelog_xs(); return 1; } elsif (defined $current_proto and $current_proto eq 'eventlog') { $syslog_xobj->Close(); return 1; } return close SYSLOG;}1;__END__=head1 NAMESys::Syslog - Perl interface to the UNIX syslog(3) calls=head1 VERSIONVersion 0.22=head1 SYNOPSIS use Sys::Syslog; # all except setlogsock(), or: use Sys::Syslog qw(:DEFAULT setlogsock); # default set, plus setlogsock() use Sys::Syslog qw(:standard :macros); # standard functions, plus macros openlog $ident, $logopt, $facility; # don't forget this syslog $priority, $format, @args; $oldmask = setlogmask $mask_priority; closelog;=head1 DESCRIPTIONC<Sys::Syslog> is an interface to the UNIX C<syslog(3)> program.Call C<syslog()> with a string priority and a list of C<printf()> argsjust like C<syslog(3)>.You can find a kind of FAQ in L<"THE RULES OF SYS::SYSLOG">. Please read it before coding, and again before asking questions. =head1 EXPORTSC<Sys::Syslog> exports the following C<Exporter> tags: =over 4=item *C<:standard> exports the standard C<syslog(3)> functions: openlog closelog setlogmask syslog=item *C<:extended> exports the Perl specific functions for C<syslog(3)>: setlogsock=item *C<:macros> exports the symbols corresponding to most of your C<syslog(3)> macros and the C<LOG_UPTO()> and C<LOG_MASK()> functions. See L<"CONSTANTS"> for the supported constants and their meaning. =backBy default, C<Sys::Syslog> exports the symbols from the C<:standard> tag. =head1 FUNCTIONS=over 4=item B<openlog($ident, $logopt, $facility)>Opens the syslog.C<$ident> is prepended to every message. C<$logopt> contains zero ormore of the options detailed below. C<$facility> specifies the part of the system to report about, for example C<LOG_USER> or C<LOG_LOCAL0>:see L<"Facilities"> for a list of well-known facilities, and your C<syslog(3)> documentation for the facilities available in your system. Check L<"SEE ALSO"> for useful links. Facility can be given as a string or a numeric macro. This function will croak if it can't connect to the syslog daemon.Note that C<openlog()> now takes three arguments, just like C<openlog(3)>.B<You should use C<openlog()> before calling C<syslog()>.>B<Options>=over 4=item *C<cons> - This option is ignored, since the failover mechanism will drop down to the console automatically if all other media fail.=item *C<ndelay> - Open the connection immediately (normally, the connection isopened when the first message is logged).=item *C<nofatal> - When set to true, C<openlog()> and C<syslog()> will only emit warnings instead of dying if the connection to the syslog can't be established. =item *C<nowait> - Don't wait for child processes that may have been created while logging the message. (The GNU C library does not create a childprocess, so this option has no effect on Linux.)=item *C<perror> - Write the message to standard error output as well to thesystem log.=item *C<pid> - Include PID with each message.=backB<Examples>Open the syslog with options C<ndelay> and C<pid>, and with facility C<LOCAL0>: openlog($name, "ndelay,pid", "local0");Same thing, but this time using the macro corresponding to C<LOCAL0>: openlog($name, "ndelay,pid", LOG_LOCAL0);=item B<syslog($priority, $message)>=item B<syslog($priority, $format, @args)>If C<$priority> permits, logs C<$message> or C<sprintf($format, @args)>with the addition that C<%m> in $message or C<$format> is replaced withC<"$!"> (the latest error message). C<$priority> can specify a level, or a level and a facility. Levels and facilities can be given as strings or as macros. When using the C<eventlog>mechanism, priorities C<DEBUG> and C<INFO> are mapped to event type C<informational>, C<NOTICE> and C<WARNIN> to C<warning> and C<ERR> to C<EMERG> to C<error>.If you didn't use C<openlog()> before using C<syslog()>, C<syslog()> will try to guess the C<$ident> by extracting the shortest prefix of C<$format> that ends in a C<":">.B<Examples> syslog("info", $message); # informational level syslog(LOG_INFO, $message); # informational level syslog("info|local0", $message); # information level, Local0 facility syslog(LOG_INFO|LOG_LOCAL0, $message); # information level, Local0 facility=over 4=item B<Note>C<Sys::Syslog> version v0.07 and older passed the C<$message> as the formatting string to C<sprintf()> even when no formatting argumentswere provided. If the code calling C<syslog()> might execute with older versions of this module, make sure to call the function asC<syslog($priority, "%s", $message)> instead of C<syslog($priority,$message)>. This protects against hostile formatting sequences thatmight show up if $message contains tainted data.=back=item B<setlogmask($mask_priority)>Sets the log mask for the current process to C<$mask_priority> and returns the old mask. If the mask argument is 0, the current log mask is not modified. See L<"Levels"> for the list of available levels. You can use the C<LOG_UPTO()> function to allow all levels up to a given priority (but it only accept the numeric macros as arguments).B<Examples>Only log errors: setlogmask( LOG_MASK(LOG_ERR) );Log everything except informational messages: setlogmask( ~(LOG_MASK(LOG_INFO)) );Log critical messages, errors and warnings: setlogmask( LOG_MASK(LOG_CRIT) | LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) );Log all messages up to debug: setlogmask( LOG_UPTO(LOG_DEBUG) );=item B<setlogsock($sock_type)>=item B<setlogsock($sock_type, $stream_location)> (added in Perl 5.004_02)Sets the socket type to be used for the next call toC<openlog()> or C<syslog()> and returns true on success,C<undef> on failure. The available mechanisms are: =over=item *C<"native"> - use the native C functions from your C<syslog(3)> library(added in C<Sys::Syslog> 0.15).=item *C<"eventlog"> - send messages to the Win32 events logger (Win32 only; added in C<Sys::Syslog> 0.19).=item *C<"tcp"> - connect to a TCP socket, on the C<syslog/tcp> or C<syslogng/tcp> service. =item *C<"udp"> - connect to a UDP socket, on the C<syslog/udp> service.=item *C<"inet"> - connect to an INET socket, either TCP or UDP, tried in that order. =item *C<"unix"> - connect to a UNIX domain socket (in some systems a character special device). The name of that socket is the second parameter or, if you omit the second parameter, the value returned by the C<_PATH_LOG> macro (if your system defines it), or F</dev/log> or F</dev/conslog>, whatever is writable. =item *C<"stream"> - connect to the stream indicated by the pathname provided as the optional second parameter, or, if omitted, to F</dev/conslog>. For example Solaris and IRIX system may prefer C<"stream"> instead of C<"unix">. =item *C<"pipe"> - connect to the named pipe indicated by the pathname provided as the optional second parameter, or, if omitted, to the value returned by the C<_PATH_LOG> macro (if your system defines it), or F</dev/log>(added in C<Sys::Syslog> 0.21).=item *C<"console"> - send messages directly to the console, as for the C<"cons"> option of C<openlog()>.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -