We're using Unix domain sockets here, which means that the data is only accessible to local log receivers.
Perl:
use IO::Socket qw(AF_UNIX SOCK_STREAM);
# Send log information to a Unix domain socket, but only if there's a
# log-receiver waiting. If there's no log-receiver available, then the log data
# is simply discarded. This is useful for when you want to accumulate lots of
# data in only rare situations, such as when a programmer is actively
# collecting it.
#
# To receive this log data on the terminal, run:
# socat -d -d -u UNIX-LISTEN:/tmp/app1.sock,mode=777,reuseaddr,fork STDOUT
#
sub log_to_Unixdomainsocket {
my $log_text = join( '', @_ ); # call this just like print()
# A "Unix-domain socket" is a socket that's local-only.
#
# Multiple processes can send logs to the same socket. You could use a separate socket for each
# project, perhaps.
my $socket_path = '/tmp/app1.sock';
# The log-sender is actually the socket-client, and the log-receiver is actually the
# socket-server. This way, it's easy to detect if there's any log-receiver waiting (because the
# socket-client finds out quickly whether there's any socket-server it can connect to).
return unless (-e $socket_path);
-S $socket_path
or die "ERROR: File exists but isn't a Unix-domain socket: $socket_path\n";
# cache the socket handle
if (! exists $::_UDS_socket{$socket_path}) {
$::_UDS_socket{$socket_path} = IO::Socket->new(
Domain => AF_UNIX,
Type => SOCK_STREAM,
Peer => $socket_path)
or die "Cannot create socket - $IO::Socket::errstr\n";
$::_UDS_socket{$socket_path}->autoflush(1);
}
my $socket = $::_UDS_socket{$socket_path};
$socket->send( $log_text );
}
socat -u UNIX-LISTEN:/tmp/app1.sock,mode=777,reuseaddr,fork STDOUT
Log::Log4perl::Appender::Socket::UNIX
log2sock — allows you to send logs to a UNIX domain socket