feat: add full Zonemaster stack with Docker and Spanish UI
- Clone all 5 Zonemaster component repos (LDNS, Engine, CLI, Backend, GUI) - Dockerfile.backend: 8-stage multi-stage build LDNS→Engine→CLI→Backend - Dockerfile.gui: Astro static build served via nginx - docker-compose.yml: backend (internal) + frontend (port 5353) - nginx.conf: root redirects to /es/, /api/ proxied to backend - zonemaster-gui/config.ts: defaultLanguage set to 'es' (Spanish) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
127
zonemaster-backend/lib/Zonemaster/Backend/Log.pm
Normal file
127
zonemaster-backend/lib/Zonemaster/Backend/Log.pm
Normal file
@@ -0,0 +1,127 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
package Zonemaster::Backend::Log;
|
||||
|
||||
use English qw( $PID );
|
||||
use POSIX;
|
||||
use JSON::PP;
|
||||
use IO::Handle;
|
||||
use Log::Any::Adapter::Util ();
|
||||
use Carp;
|
||||
use Data::Dumper;
|
||||
|
||||
use base qw(Log::Any::Adapter::Base);
|
||||
|
||||
|
||||
my $default_level = Log::Any::Adapter::Util::numeric_level('info');
|
||||
|
||||
sub init {
|
||||
my ($self) = @_;
|
||||
|
||||
if ( defined $self->{log_level} && $self->{log_level} =~ /\D/ ) {
|
||||
$self->{log_level} = lc $self->{log_level};
|
||||
my $numeric_level = Log::Any::Adapter::Util::numeric_level( $self->{log_level} );
|
||||
if ( !defined($numeric_level) ) {
|
||||
croak "Error: Unrecognized log level " . $self->{log_level} . "\n";
|
||||
}
|
||||
$self->{log_level} = $numeric_level;
|
||||
}
|
||||
|
||||
$self->{log_level} //= $default_level;
|
||||
|
||||
my $fd;
|
||||
if ( !exists $self->{file} || $self->{file} eq '-') {
|
||||
if ( $self->{stderr} ) {
|
||||
$fd = fileno(STDERR);
|
||||
} else {
|
||||
$fd = fileno(STDOUT);
|
||||
}
|
||||
} else {
|
||||
open( $fd, '>>', $self->{file} ) or croak "Can't open log file: $!";
|
||||
}
|
||||
|
||||
$self->{handle} = IO::Handle->new_from_fd( $fd, "w" ) or croak "Can't fdopen file: $!";
|
||||
$self->{handle}->autoflush(1);
|
||||
|
||||
if ( !exists $self->{formatter} ) {
|
||||
if ( $self->{json} ) {
|
||||
$self->{formatter} = \&format_json;
|
||||
} else {
|
||||
$self->{formatter} = \&format_text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub format_text {
|
||||
my ($self, $log_params) = @_;
|
||||
my $msg;
|
||||
$msg .= sprintf "%s ", $log_params->{timestamp};
|
||||
delete $log_params->{timestamp};
|
||||
$msg .= sprintf(
|
||||
"[%d] [%s] [%s] %s",
|
||||
delete $log_params->{pid},
|
||||
uc delete $log_params->{level},
|
||||
delete $log_params->{category},
|
||||
delete $log_params->{message}
|
||||
);
|
||||
|
||||
if ( %$log_params ) {
|
||||
local $Data::Dumper::Indent = 0;
|
||||
local $Data::Dumper::Terse = 1;
|
||||
my $data = Dumper($log_params);
|
||||
|
||||
$msg .= " Extra parameters: $data";
|
||||
}
|
||||
|
||||
return $msg
|
||||
}
|
||||
|
||||
sub format_json {
|
||||
my ($self, $log_params) = @_;
|
||||
|
||||
my $js = JSON::PP->new;
|
||||
$js->canonical( 1 );
|
||||
|
||||
return $js->encode( $log_params );
|
||||
}
|
||||
|
||||
|
||||
sub structured {
|
||||
my ($self, $level, $category, $string, @items) = @_;
|
||||
|
||||
my $log_level = Log::Any::Adapter::Util::numeric_level($level);
|
||||
|
||||
return if $log_level > $self->{log_level};
|
||||
|
||||
my %log_params = (
|
||||
timestamp => strftime( "%FT%TZ", gmtime ),
|
||||
level => $level,
|
||||
category => $category,
|
||||
message => $string,
|
||||
pid => $PID,
|
||||
);
|
||||
|
||||
for my $item ( @items ) {
|
||||
if (ref($item) eq 'HASH') {
|
||||
for my $key (keys %$item) {
|
||||
$log_params{$key} = $item->{$key};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $msg = $self->{formatter}->($self, \%log_params);
|
||||
$self->{handle}->print($msg . "\n");
|
||||
}
|
||||
|
||||
# From Log::Any::Adapter::File
|
||||
foreach my $method ( Log::Any::Adapter::Util::detection_methods() ) {
|
||||
no strict 'refs';
|
||||
my $base = substr($method,3);
|
||||
my $method_level = Log::Any::Adapter::Util::numeric_level( $base );
|
||||
*{$method} = sub {
|
||||
return !!( $method_level <= $_[0]->{log_level} );
|
||||
};
|
||||
}
|
||||
|
||||
1;
|
||||
Reference in New Issue
Block a user