package Linux::Systemd::Journal::Write 1.201600; # ABSTRACT: XS wrapper around sd-journal # TODO Helper script to generate message catalogs? # http://www.freedesktop.org/wiki/Software/systemd/catalog/ # TODO make sure all text is utf8 use v5.10.1; use Moo; use Carp; use XSLoader; XSLoader::load; has app_id => ( is => 'ro', lazy => 1, default => sub { require File::Basename; return File::Basename::basename($0); }, ); has priority => ( is => 'ro', lazy => 1, default => 6, isa => sub { die 'Invalid log level' unless (defined $_[0] && $_[0] =~ /^[0-7]$/); }, ); has caller_details => ( is => 'ro', default => 1, ); has caller_level => ( is => 'ro', default => 0, ); sub print { my ($self, $msg, $pri) = @_; $pri //= $self->priority; __sd_journal_print($pri, $msg); return 1; } sub send { my $self = shift; my $data; if (scalar @_ == 2 && !ref $_[0]) { my $ref = ref $_[1]; if ($ref eq 'HASH') { $data = {%{$_[1]}}; } elsif ($ref eq 'ARRAY') { $data = {@{$_[1]}}; } $data->{message} = $_[0]; } elsif (scalar @_ > 1) { $data = {@_}; } else { my $ref = ref $_[0]; if (!$ref) { $data->{message} = shift; } elsif ($ref eq 'HASH') { $data = shift; } elsif ($ref eq 'ARRAY') { $data = {@{$_[0]}}; } } croak 'Invalid params' unless defined $data; # message is required if (!exists $data->{message} && !exists $data->{MESSAGE}) { croak 'Missing message param'; } # XXX this isn't required by sd-journal if (!exists $data->{priority} && !exists $data->{PRIORITY}) { $data->{priority} = $self->priority; } if (!exists $data->{syslog_identifier}) { $data->{syslog_identifier} = $self->app_id; } if ($self->caller_details) { my @caller = caller($self->caller_level); $data->{CODE_LINE} = $caller[2]; $data->{CODE_FILE} = $caller[1]; @caller = caller($self->caller_level + 1); $data->{CODE_FUNC} = $caller[3]; } # flatten it out my @array = map { uc($_) . '=' . ($data->{$_} // 'undef') } keys %$data; __sd_journal_send(\@array); return 1; } sub perror { __sd_journal_perror($_[1]); return 1; } 1; __END__ =pod =encoding UTF-8 =for :stopwords Ioan Rogers =head1 NAME Linux::Systemd::Journal::Write - XS wrapper around sd-journal =head1 VERSION version 1.201600 =head1 SYNOPSIS use Linux::Systemd::Journal::Write; my $jnl = Linux::Systemd::Journal::Write->new; # basic log messages $jnl->print('flarg'); # with default log level $jnl->print('Hello world', 4); # WARN level # add abitrary data to the log entry my %hash = (DAY_ONE => 'Monday', DAY_TWO => 'Tuesday', DAY_THREE => 'Wednesday'); $jnl->send('Here is a message', \%hash); # add abitrary data to the log entry # will log "Failed to open file: No such file or directory" and ERRNO=2 open my $fh, '<', 'nosuchfile' or $jnl->perror('Failed to open file'); =head1 DESCRIPTION =head2 Log Levels The log levels use by C and by L are the same as those use by C, so instead of using numeric priorities you can use Sys::Syslog ':macros'; giving you access to the C L<"level constants"|Sys::Syslog/Levels> =head1 ATTRIBUTES =head2 C Will be used to set C. Defaults to C; =head2 C Default log priority. See L =head2 C Boolean controlling whether to log the C, C, and C of the L. Optional. Defaults to C; See also L =head2 C If this module is not being used directly, but through some proxy module for instance, C is used to determine the number of frames to look back through. Optional. Defaults to C<0>; =head1 METHODS =head2 C $msg should be either a string. $pri is optional, and defaults to $self->priority =head2 C If there is one arg, it may be a simple string to log. Or, it could be a hashref or an arrayref. In this case, one of the keys sent MUST be 'message'. If there are two args, the first must be the string to use as a message, the second a hashref or arrayref. In this case, a key called message should not be set. Finally, C can also be called with an array of key => values, one of which must be message. Keys will be uppercased. =head2 C Logs the string of the current set C, prefixed with C<$msg>. =head1 SEE ALSO =over 4 =item * L At some point between me writing this module and getting around to releasing it, another module was released to write the journal. =item * L The main C page. =item * L Man page of the C API =back =head1 AUTHOR Ioan Rogers =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2020 by Ioan Rogers. This is free software, licensed under: The GNU Lesser General Public License, Version 2.1, February 1999 =cut