mirror of https://github.com/digint/btrbk
Merge branch 'syslog'
commit
e9e398af37
|
@ -2,6 +2,7 @@ btrbk-current
|
||||||
|
|
||||||
* Bugfix: set correct parent section when propagating targets
|
* Bugfix: set correct parent section when propagating targets
|
||||||
(close: #85).
|
(close: #85).
|
||||||
|
* Add syslog output of transaction log (close #82).
|
||||||
|
|
||||||
btrbk-0.23.0
|
btrbk-0.23.0
|
||||||
|
|
||||||
|
|
68
btrbk
68
btrbk
|
@ -69,6 +69,7 @@ my $ssh_cipher_match = qr/[a-z0-9][a-z0-9@.-]+/;
|
||||||
my $safe_cmd_match = qr/[0-9a-zA-Z_@=\+\-\.\/]+/; # $file_match plus '=': good enough for our purpose
|
my $safe_cmd_match = qr/[0-9a-zA-Z_@=\+\-\.\/]+/; # $file_match plus '=': good enough for our purpose
|
||||||
|
|
||||||
my %day_of_week_map = ( sunday => 0, monday => 1, tuesday => 2, wednesday => 3, thursday => 4, friday => 5, saturday => 6 );
|
my %day_of_week_map = ( sunday => 0, monday => 1, tuesday => 2, wednesday => 3, thursday => 4, friday => 5, saturday => 6 );
|
||||||
|
my @syslog_facilities = qw( user mail daemon auth lpr news cron authpriv local0 local1 local2 local3 local4 local5 local6 local7 );
|
||||||
|
|
||||||
my %config_options = (
|
my %config_options = (
|
||||||
# NOTE: the parser always maps "no" to undef
|
# NOTE: the parser always maps "no" to undef
|
||||||
|
@ -94,6 +95,7 @@ my %config_options = (
|
||||||
ssh_cipher_spec => { default => "default", accept_regexp => qr/^$ssh_cipher_match(,$ssh_cipher_match)*$/ },
|
ssh_cipher_spec => { default => "default", accept_regexp => qr/^$ssh_cipher_match(,$ssh_cipher_match)*$/ },
|
||||||
rate_limit => { default => undef, accept => [ "no" ], accept_regexp => qr/^[0-9]+[kmgt]?$/, require_bin => '/usr/bin/pv' },
|
rate_limit => { default => undef, accept => [ "no" ], accept_regexp => qr/^[0-9]+[kmgt]?$/, require_bin => '/usr/bin/pv' },
|
||||||
transaction_log => { default => undef, accept_file => { absolute => 1 } },
|
transaction_log => { default => undef, accept_file => { absolute => 1 } },
|
||||||
|
transaction_syslog => { default => undef, accept => \@syslog_facilities },
|
||||||
|
|
||||||
raw_target_compress => { default => undef, accept => [ "no", "gzip", "bzip2", "xz" ] },
|
raw_target_compress => { default => undef, accept => [ "no", "gzip", "bzip2", "xz" ] },
|
||||||
raw_target_compress_level => { default => "default", accept => [ "default" ], accept_numeric => 1 },
|
raw_target_compress_level => { default => "default", accept => [ "default" ], accept_numeric => 1 },
|
||||||
|
@ -178,6 +180,7 @@ my %table_formats = (
|
||||||
long => [ qw( localtime type status duration target_host target_subvol source_host source_subvol parent_subvol message ) ],
|
long => [ qw( localtime type status duration target_host target_subvol source_host source_subvol parent_subvol message ) ],
|
||||||
raw => [ qw( time localtime type status duration target_url source_url parent_url message ) ],
|
raw => [ qw( time localtime type status duration target_url source_url parent_url message ) ],
|
||||||
tlog => [ qw( localtime type status duration target_url source_url parent_url message ) ],
|
tlog => [ qw( localtime type status duration target_url source_url parent_url message ) ],
|
||||||
|
syslog => [ qw( type status duration target_url source_url parent_url message ) ],
|
||||||
},
|
},
|
||||||
|
|
||||||
origin_tree => { table => [ qw( tree uuid parent_uuid received_uuid ) ],
|
origin_tree => { table => [ qw( tree uuid parent_uuid received_uuid ) ],
|
||||||
|
@ -202,6 +205,7 @@ my $err = "";
|
||||||
my $abrt = ""; # last ABORTED() message
|
my $abrt = ""; # last ABORTED() message
|
||||||
my $output_format;
|
my $output_format;
|
||||||
my $tlog_fh;
|
my $tlog_fh;
|
||||||
|
my $syslog_enabled = 0;
|
||||||
my $current_transaction;
|
my $current_transaction;
|
||||||
my @transaction_log;
|
my @transaction_log;
|
||||||
my %config_override;
|
my %config_override;
|
||||||
|
@ -318,10 +322,16 @@ sub ABORTED($;$)
|
||||||
$config->{ABORTED} = $abrt;
|
$config->{ABORTED} = $abrt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub eval_quiet(&)
|
||||||
|
{
|
||||||
|
local $SIG{__DIE__};
|
||||||
|
return eval { $_[0]->() }
|
||||||
|
}
|
||||||
|
|
||||||
sub init_transaction_log($)
|
sub init_transaction_log($$)
|
||||||
{
|
{
|
||||||
my $file = shift;
|
my $file = shift;
|
||||||
|
my $config_syslog_facility = shift;
|
||||||
if(defined($file) && (not $dryrun)) {
|
if(defined($file) && (not $dryrun)) {
|
||||||
if(open($tlog_fh, ">> $file")) {
|
if(open($tlog_fh, ">> $file")) {
|
||||||
# print headers
|
# print headers
|
||||||
|
@ -332,6 +342,17 @@ sub init_transaction_log($)
|
||||||
ERROR "Failed to open transaction log '$file': $!";
|
ERROR "Failed to open transaction log '$file': $!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(defined($config_syslog_facility) && (not $dryrun)) {
|
||||||
|
DEBUG "Opening syslog";
|
||||||
|
if(eval_quiet { require Sys::Syslog; }) {
|
||||||
|
$syslog_enabled = 1;
|
||||||
|
Sys::Syslog::openlog("btrbk", "", $config_syslog_facility);
|
||||||
|
DEBUG "Syslog enabled";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WARN "Syslog disabled: $@";
|
||||||
|
}
|
||||||
|
}
|
||||||
action("startup", status => "v$VERSION", message => "$VERSION_INFO");
|
action("startup", status => "v$VERSION", message => "$VERSION_INFO");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +362,10 @@ sub close_transaction_log()
|
||||||
DEBUG "Closing transaction log";
|
DEBUG "Closing transaction log";
|
||||||
close $tlog_fh || ERROR "Failed to close transaction log: $!";
|
close $tlog_fh || ERROR "Failed to close transaction log: $!";
|
||||||
}
|
}
|
||||||
|
if($syslog_enabled) {
|
||||||
|
DEBUG "Closing syslog";
|
||||||
|
eval_quiet { Sys::Syslog::closelog(); };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub action($@)
|
sub action($@)
|
||||||
|
@ -352,6 +377,7 @@ sub action($@)
|
||||||
$h->{time} = $time;
|
$h->{time} = $time;
|
||||||
$h->{localtime} = timestamp($time, 'debug-iso');
|
$h->{localtime} = timestamp($time, 'debug-iso');
|
||||||
print_formatted("transaction", [ $h ], output_format => "tlog", no_header => 1, outfile => $tlog_fh) if($tlog_fh);
|
print_formatted("transaction", [ $h ], output_format => "tlog", no_header => 1, outfile => $tlog_fh) if($tlog_fh);
|
||||||
|
print_formatted("transaction", [ $h ], output_format => "syslog", no_header => 1) if($syslog_enabled); # dirty hack, this calls syslog()
|
||||||
push @transaction_log, $h;
|
push @transaction_log, $h;
|
||||||
return $h;
|
return $h;
|
||||||
}
|
}
|
||||||
|
@ -381,6 +407,13 @@ sub end_transaction($$)
|
||||||
$current_transaction = undef;
|
$current_transaction = undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub syslog($)
|
||||||
|
{
|
||||||
|
return undef unless($syslog_enabled);
|
||||||
|
my $line = shift;
|
||||||
|
eval_quiet { Sys::Syslog::syslog("info", $line); };
|
||||||
|
}
|
||||||
|
|
||||||
sub safe_cmd($)
|
sub safe_cmd($)
|
||||||
{
|
{
|
||||||
my $aref = shift;
|
my $aref = shift;
|
||||||
|
@ -1557,15 +1590,12 @@ sub add_btrbk_filename_info($;$)
|
||||||
my $zz = $+{zz};
|
my $zz = $+{zz};
|
||||||
|
|
||||||
my $time;
|
my $time;
|
||||||
eval {
|
if(defined($zz)) {
|
||||||
local $SIG{'__DIE__'};
|
eval_quiet { $time = timegm(@tm); };
|
||||||
if(defined($zz)) {
|
} else {
|
||||||
$time = timegm(@tm);
|
eval_quiet { $time = timelocal(@tm); };
|
||||||
} else {
|
}
|
||||||
$time = timelocal(@tm);
|
unless(defined($time)) {
|
||||||
}
|
|
||||||
};
|
|
||||||
if($@) {
|
|
||||||
WARN "Illegal timestamp on subvolume \"$node->{REL_PATH}\", ignoring";
|
WARN "Illegal timestamp on subvolume \"$node->{REL_PATH}\", ignoring";
|
||||||
# WARN "$@"; # sadly Time::Local croaks, which also prints the line number from here.
|
# WARN "$@"; # sadly Time::Local croaks, which also prints the line number from here.
|
||||||
return undef;
|
return undef;
|
||||||
|
@ -3164,14 +3194,19 @@ sub print_formatted(@)
|
||||||
print $fh join(' ', map { "$_=\"" . ($row->{$_} // "") . "\""; } @$keys) . "\n";
|
print $fh join(' ', map { "$_=\"" . ($row->{$_} // "") . "\""; } @$keys) . "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif($format eq "tlog")
|
elsif(($format eq "tlog") || ($format eq "syslog"))
|
||||||
{
|
{
|
||||||
# output: value0 value1, ...
|
# output: value0 value1, ...
|
||||||
unless($args{no_header}) {
|
unless($args{no_header}) {
|
||||||
print $fh join(' ', @$keys) . "\n";
|
print $fh join(' ', @$keys) . "\n";
|
||||||
}
|
}
|
||||||
foreach my $row (@$data) {
|
foreach my $row (@$data) {
|
||||||
print $fh join(' ', map { ((defined($row->{$_}) && ($_ eq "message")) ? '# ' : '') . ($row->{$_} // "-") } @$keys) . "\n";
|
my $line = join(' ', map { ((defined($row->{$_}) && ($_ eq "message")) ? '# ' : '') . ($row->{$_} // "-") } @$keys);
|
||||||
|
if($format eq "syslog") { # dirty hack, ignore outfile on syslog format
|
||||||
|
syslog($line);
|
||||||
|
} else {
|
||||||
|
print $fh ($line . "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3621,7 +3656,8 @@ MAIN:
|
||||||
# thing used from the configuration is the SSH and transaction log
|
# thing used from the configuration is the SSH and transaction log
|
||||||
# stuff.
|
# stuff.
|
||||||
#
|
#
|
||||||
init_transaction_log(config_key($config, "transaction_log"));
|
init_transaction_log(config_key($config, "transaction_log"),
|
||||||
|
config_key($config, "transaction_syslog"));
|
||||||
|
|
||||||
my $src_url = $filter_args[0] || die;
|
my $src_url = $filter_args[0] || die;
|
||||||
my $archive_url = $filter_args[1] || die;
|
my $archive_url = $filter_args[1] || die;
|
||||||
|
@ -4521,7 +4557,8 @@ MAIN:
|
||||||
#
|
#
|
||||||
# identify and delete incomplete backups
|
# identify and delete incomplete backups
|
||||||
#
|
#
|
||||||
init_transaction_log(config_key($config, "transaction_log"));
|
init_transaction_log(config_key($config, "transaction_log"),
|
||||||
|
config_key($config, "transaction_syslog"));
|
||||||
|
|
||||||
my @out;
|
my @out;
|
||||||
foreach my $sroot (vinfo_subsection($config, 'volume')) {
|
foreach my $sroot (vinfo_subsection($config, 'volume')) {
|
||||||
|
@ -4618,7 +4655,8 @@ MAIN:
|
||||||
|
|
||||||
if($action_run)
|
if($action_run)
|
||||||
{
|
{
|
||||||
init_transaction_log(config_key($config, "transaction_log"));
|
init_transaction_log(config_key($config, "transaction_log"),
|
||||||
|
config_key($config, "transaction_syslog"));
|
||||||
|
|
||||||
if($resume_only) {
|
if($resume_only) {
|
||||||
INFO "Skipping snapshot creation (option \"-r\" present)";
|
INFO "Skipping snapshot creation (option \"-r\" present)";
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.TH "btrbk.conf" "5" "2016-04-25" "btrbk v0.23.1-dev" ""
|
.TH "btrbk.conf" "5" "2016-04-28" "btrbk v0.23.1-dev" ""
|
||||||
.\" disable hyphenation
|
.\" disable hyphenation
|
||||||
.nh
|
.nh
|
||||||
.\" disable justification (adjust text to left margin only)
|
.\" disable justification (adjust text to left margin only)
|
||||||
|
@ -72,7 +72,16 @@ allowed.
|
||||||
.RS 4
|
.RS 4
|
||||||
If set, all transactions (snapshot create, subvolume send-receive,
|
If set, all transactions (snapshot create, subvolume send-receive,
|
||||||
subvolume delete) as well as abort messages are logged to <file>, in a
|
subvolume delete) as well as abort messages are logged to <file>, in a
|
||||||
space-separated table format.
|
space-separated table format: "localtime type status duration
|
||||||
|
target_url source_url parent_url message".
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\fBtransaction_syslog\fR <facility>
|
||||||
|
.RS 4
|
||||||
|
If set, all transactions (as described in \fItransaction_log\fR above)
|
||||||
|
are logged to syslog. The facility parameter accepts a lowercase
|
||||||
|
syslog facility name, like \[lq]daemon\[rq] or \[lq]local7\[rq]. The
|
||||||
|
program name used in the messages is "btrbk".
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBtimestamp_format\fR short|long|long-iso
|
\fBtimestamp_format\fR short|long|long-iso
|
||||||
|
|
Loading…
Reference in New Issue