use File::Basename;
use File::Spec::Functions;
use Safe;
-use Sys::Syslog qw(:DEFAULT);
use JSON::XS qw(decode_json);
use parent qw(Bugzilla::CPAN);
# The script should really generate these graphs directly...
'webdotdir' => "$datadir/webdot",
'extensionsdir' => "$libpath/extensions",
+ 'logsdir' => "$libpath/logs",
'assetsdir' => "$datadir/assets",
'confdir' => $confdir,
};
on_exception => on_exception( 'cereal', $exit_f ),
);
$exit_f->on_cancel( sub { $cereal->kill('TERM') } );
+ $exit_f->on_ready(
+ sub {
+ delete $ENV{LOG4PERL_STDERR_DISABLE};
+ }
+ );
$loop->add($cereal);
+ $ENV{LOG4PERL_STDERR_DISABLE} = 1;
return $exit_f;
}
sub ThrowCodeError {
my ($error, $vars) = @_;
- my $logfunc = _make_logfunc('User');
+ my $logfunc = _make_logfunc('Code');
_add_vars_to_logging_fields($vars);
_throw_error( 'global/code-error.html.tmpl', $error, $vars, $logfunc );
use File::Slurp;
use IO::File;
use POSIX ();
+use English qw(-no_match_vars $OSNAME);
use base qw(Exporter);
our @EXPORT = qw(
LOCALCONFIG_ENV
BUGZILLA_UNSAFE_AUTH_DELEGATION
LOG4PERL_CONFIG_FILE
+ LOG4PERL_STDERR_DISABLE
USE_NYTPROF
NYTPROF_DIR
);
# (or their subdirectories) to the user, via the webserver.
sub DIR_ALSO_WS_SERVE { _suexec() ? 0001 : 0 };
+sub DIR_ALSO_WS_STICKY { $OSNAME eq 'linux' ? 02000 : 0 }
+
# This looks like a constant because it effectively is, but
# it has to call other subroutines and read the current filesystem,
# so it's defined as a sub. This is not exported, so it doesn't have
my $template_cache = bz_locations()->{'template_cache'};
my $graphsdir = bz_locations()->{'graphsdir'};
my $assetsdir = bz_locations()->{'assetsdir'};
+ my $logsdir = bz_locations()->{'logsdir'};
# We want to set the permissions the same for all localconfig files
# across all PROJECTs, so we do something special with $localconfig,
dirs => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE },
"$datadir/db" => { files => CGI_WRITE,
dirs => DIR_CGI_WRITE },
+ $logsdir => { files => CGI_WRITE,
+ dirs => DIR_CGI_WRITE | DIR_ALSO_WS_STICKY },
$assetsdir => { files => WS_SERVE,
dirs => DIR_CGI_OVERWRITE | DIR_ALSO_WS_SERVE },
$webdotdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
$assetsdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
$template_cache => DIR_CGI_WRITE,
+ $logsdir => DIR_CGI_WRITE | DIR_ALSO_WS_STICKY,
# Directories that contain content served directly by the web server.
"$skinsdir/custom" => DIR_WS_SERVE,
"$skinsdir/contrib" => DIR_WS_SERVE,
use Log::Log4perl qw(:easy);
use Log::Log4perl::MDC;
-use File::Spec::Functions qw(rel2abs);
+use File::Spec::Functions qw(rel2abs catfile);
use Bugzilla::Constants qw(bz_locations);
use English qw(-no_match_vars $PROGRAM_NAME);
+use Taint::Util qw(untaint);
-sub is_interactive {
- return not exists $ENV{SERVER_SOFTWARE}
+sub logfile {
+ my ($class, $name) = @_;
+
+ my $file = rel2abs(catfile(bz_locations->{logsdir}, $name));
+ untaint($file);
+ return $file;
}
sub fields {
.. _`Devel::NYTProf`: https://metacpan.org/pod/Devel::NYTProf
.. _`Log::Log4perl`: https://metacpan.org/pod/Log::Log4perl
+LOG4PERL_STDERR_DISABLE
+ Boolean. By default log messages are logged as plain text to `STDERR`.
+ Setting this to a true value disables this behavior.
+
+ Note: For programs that run using the `cereal` log aggregator, this environemnt
+ variable will be ignored.
+
Persistent Data Volume
----------------------
config.vm.provision 'main', type: 'ansible_local', run: 'always' do |ansible|
ansible.playbook = 'vagrant_support/playbook.yml'
- ansible.version = 'latest'
ansible.extra_vars = {
WEB_IP: WEB_IP,
DB_IP: DB_IP,
if ARGV.include? '--provision-with'
config.vm.provision 'update', type: 'ansible_local', run: 'never' do |update|
update.playbook = 'vagrant_support/update.yml'
- update.version = 'latest'
end
end
PerlSwitches -wT
PerlRequire /app/mod_perl.pl
+PerlSetEnv LOG4PERL_STDERR_DISABLE 1
DirectoryIndex index.cgi
DocumentRoot "/app"
<IfDefine HTTPD_IN_SUBDIR>
--- /dev/null
+log4perl.rootLogger = DEBUG, Cereal, Screen
+log4perl.appender.Cereal = Log::Log4perl::Appender::Socket
+log4perl.appender.Cereal.PeerAddr=127.0.0.1
+log4perl.appender.Cereal.PeerPort=5880
+log4perl.appender.Cereal.defer_connection=1
+log4perl.appender.Cereal.layout = Log::Log4perl::Layout::PatternLayout
+log4perl.appender.Cereal.layout.ConversionPattern = %d %6p | %c | %m{chomp}%n
+
+log4perl.filter.LOG_TO_STDERR = sub { not $ENV{LOG4PERL_STDERR_DISABLE} }
+log4perl.appender.Screen = Log::Log4perl::Appender::Screen
+log4perl.appender.Screen.Filter = LOG_TO_STDERR
+log4perl.appender.Screen.stderr = 1
+log4perl.appender.Screen.layout = Log::Log4perl::Layout::PatternLayout
+log4perl.appender.Screen.layout.ConversionPattern = %d %6p | %c | %m{chomp}%n
# The default is Bugzilla. This is the "Logger" field
# in https://wiki.mozilla.org/Firefox/Services/Logging#MozLog_JSON_schema
#and it might be useful to pass in different values for different jobs.
-log4perl.appender.Cereal.layout.name = Bugzilla
+log4perl.appender.Cereal.layout.name = CEREAL
-log4perl.filter.IS_INTERACTIVE = sub { Bugzilla::Logging::is_interactive() }
+log4perl.filter.LOG_TO_STDERR = sub { not $ENV{LOG4PERL_STDERR_DISABLE} }
log4perl.appender.Screen = Log::Log4perl::Appender::Screen
-log4perl.appender.Screen.Filter = IS_INTERACTIVE
-log4perl.appender.Screen.layout = Log::Log4perl::Layout::PatternLayout
-log4perl.appender.Screen.layout.ConversionPattern = %-5.5p [%d] [%c] %m{chomp} at %F line %L (%M)%n
+log4perl.appender.Screen.Filter = LOG_TO_STDERR
+log4perl.appender.Screen.stderr = 1
+log4perl.appender.Screen.layout = Log::Log4perl::Layout::Mozilla
+log4perl.appender.Screen.layout.max_json_length = 16384
+log4perl.appender.Screen.layout.name = STDERR
log4perl.appender.Cereal.PeerPort=5880
log4perl.appender.Cereal.defer_connection=1
log4perl.appender.Cereal.layout = Log::Log4perl::Layout::PatternLayout
-log4perl.appender.Cereal.layout.ConversionPattern = %-5.5p [%d] [%c] %m{chomp} at %F line %L (%M)%n
+log4perl.appender.Cereal.layout.ConversionPattern = %d %6p | %c | %m{chomp}%n
-log4perl.filter.IS_INTERACTIVE = sub { Bugzilla::Logging::is_interactive() }
+log4perl.filter.LOG_TO_STDERR = sub { not $ENV{LOG4PERL_STDERR_DISABLE} }
log4perl.appender.Screen = Log::Log4perl::Appender::Screen
-log4perl.appender.Screen.Filter = IS_INTERACTIVE
+log4perl.appender.Screen.Filter = LOG_TO_STDERR
+log4perl.appender.Screen.stderr = 1
log4perl.appender.Screen.layout = Log::Log4perl::Layout::PatternLayout
-log4perl.appender.Screen.layout.ConversionPattern = %-5.5p [%d] [%c] %m{chomp} at %F line %L (%M)%n
+log4perl.appender.Screen.layout.ConversionPattern = %d %6p | %c | %m{chomp}%n
log4perl.appender.File = Log::Log4perl::Appender::File
log4perl.appender.File.layout = Log::Log4perl::Layout::Mozilla
--- /dev/null
+log4perl.rootLogger = DEBUG, TextFile, JSONFile, Screen
+
+log4perl.appender.TextFile = Log::Log4perl::Appender::File
+log4perl.appender.TextFile.layout = Log::Log4perl::Layout::PatternLayout
+log4perl.appender.TextFile.filename = sub { Bugzilla::Logging->logfile("bugzilla.log") }
+log4perl.appender.TextFile.layout.ConversionPattern = %-5.5p [%d] [%c] %m{chomp} at %F line %L (%M)%n
+log4perl.appender.TextFile.create_at_logtime = true
+log4perl.appender.TextFile.owner = vagrant
+log4perl.appender.TextFile.group = apache
+
+log4perl.appender.JSONFile = Log::Log4perl::Appender::File
+log4perl.appender.JSONFile.layout = Log::Log4perl::Layout::Mozilla
+log4perl.appender.JSONFile.filename = sub { Bugzilla::Logging->logfile("bugzilla-json.log") }
+log4perl.appender.JSONFile.mode = append
+log4perl.appender.JSONFile.create_at_logtime = true
+log4perl.appender.JSONFile.owner = vagrant
+log4perl.appender.JSONFile.group = apache
+
+log4perl.filter.LOG_TO_STDERR = sub { not $ENV{LOG4PERL_STDERR_DISABLE} }
+log4perl.appender.Screen = Log::Log4perl::Appender::Screen
+log4perl.appender.Screen.Filter = LOG_TO_STDERR
+log4perl.appender.Screen.stderr = 1
+log4perl.appender.Screen.layout = Log::Log4perl::Layout::PatternLayout
+log4perl.appender.Screen.layout.ConversionPattern = %d %6p | %c | %m{chomp}%n
- /run
environment: &bmo_env
- LOCALCONFIG_ENV=1
- - LOG4PERL_CONFIG_FILE=log4perl-test.conf
+ - LOG4PERL_CONFIG_FILE=log4perl-docker.conf
- BUGZILLA_UNSAFE_AUTH_DELEGATION=1
- PORT=80
- BMO_db_host=bmo-db.vm
# sharing with the other httpd processes.
my $limit = Bugzilla->localconfig->{apache_size_limit};
if ($OSNAME eq 'linux' && ! eval { require Linux::Smaps }) {
- warn "SizeLimit requires Linux::Smaps on linux. size limit set to 800MB";
+ WARN('SizeLimit requires Linux::Smaps on linux. size limit set to 800MB');
$limit = 800_000;
}
Apache2::SizeLimit->set_max_unshared_size($limit);
DB::enable_profile($file);
}
Bugzilla::init_page();
- my $start = Time::HiRes::time();
my $result = $class->SUPER::handler(@_);
if (Bugzilla::ModPerl::USE_NYTPROF) {
DB::disable_profile();
DB::finish_profile();
}
- warn "[request_time] ", Bugzilla->cgi->request_uri, " took ", Time::HiRes::time() - $start, " seconds to execute";
# When returning data from the REST api we must only return 200 or 304,
# which tells Apache not to append its error html documents to the
PerlSwitches -wT
PerlSetEnv USE_NYTPROF 0
PerlSetEnv BUGZILLA_UNSAFE_AUTH_DELEGATION 1
+PerlPassEnv LOG4PERL_CONFIG_FILE
+PerlSetEnv LOG4PERL_STDERR_DISABLE=1
PerlConfigRequire /vagrant/mod_perl.pl
<IfModule mpm_prefork_module>
group: root
mode: 0644
+ - name: 'add LOG4PERL_CONFIG_FILE'
+ lineinfile:
+ dest: /etc/environment
+ regexp: 'LOG4PERL_CONFIG_FILE='
+ line: 'LOG4PERL_CONFIG_FILE=log4perl-vagrant.conf'
+ owner: root
+ group: root
+ mode: 0644
+
- name: copy ntp.conf
copy:
src: ntp.conf