summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDylan William Hardison <dylan@hardison.net>2018-04-10 04:51:08 +0200
committerGitHub <noreply@github.com>2018-04-10 04:51:08 +0200
commit694df9c1c6ec244c416c2d8e85657651b6a28dab (patch)
tree2985dfd5ed865d9b2192982196e846efc0c56656
parent755bc194dcea3481fa41b5884a98a5aa086fe09e (diff)
downloadbugzilla-694df9c1c6ec244c416c2d8e85657651b6a28dab.tar.gz
bugzilla-694df9c1c6ec244c416c2d8e85657651b6a28dab.tar.xz
Bug 1450679 - Replace custom Sentry integration with Logging
-rw-r--r--Bugzilla.pm6
-rw-r--r--Bugzilla/Config/Advanced.pm6
-rw-r--r--Bugzilla/Constants.pm2
-rw-r--r--Bugzilla/Error.pm111
-rw-r--r--Bugzilla/Install/Filesystem.pm7
-rw-r--r--Bugzilla/Logging.pm8
-rw-r--r--Bugzilla/Sentry.pm374
-rw-r--r--Log/Log4perl/Layout/Mozilla.pm5
-rw-r--r--conf/log4perl-test.conf2
-rwxr-xr-xscripts/nagios_blocker_checker.pl4
-rwxr-xr-xsentry.pl94
-rw-r--r--template/en/default/admin/params/advanced.html.tmpl5
-rw-r--r--template/en/default/global/code-error.html.tmpl10
13 files changed, 66 insertions, 568 deletions
diff --git a/Bugzilla.pm b/Bugzilla.pm
index 1188102d3..a8b164b57 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -100,7 +100,7 @@ sub init_page {
}
if (i_am_cgi()) {
- Log::Log4perl::MDC->put(remote_ip => remote_ip());
+ Bugzilla::Logging->fields->{remote_ip} = remote_ip();
}
if (${^TAINT}) {
@@ -386,8 +386,8 @@ sub login {
my $authenticated_user = $authorizer->login($type);
- if (i_am_cgi()) {
- Log::Log4perl::MDC->put(user_id => $authenticated_user->id);
+ if (i_am_cgi() && $authenticated_user->id) {
+ Bugzilla::Logging->fields->{user_id} = $authenticated_user->id;
}
# At this point, we now know if a real person is logged in.
diff --git a/Bugzilla/Config/Advanced.pm b/Bugzilla/Config/Advanced.pm
index 2eec11dbe..9316d8e48 100644
--- a/Bugzilla/Config/Advanced.pm
+++ b/Bugzilla/Config/Advanced.pm
@@ -38,12 +38,6 @@ use constant get_param_list => (
},
{
- name => 'sentry_uri',
- type => 't',
- default => '',
- },
-
- {
name => 'metrics_enabled',
type => 'b',
default => 0
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 6e3a12736..80d9c4e0c 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -694,8 +694,6 @@ sub _bz_locations {
'webdotdir' => "$datadir/webdot",
'extensionsdir' => "$libpath/extensions",
'assetsdir' => "$datadir/assets",
- # error_reports store error/warnings destined for sentry
- 'error_reports' => "$libpath/error_reports",
'confdir' => $confdir,
};
}
diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm
index d67571848..ef57303e9 100644
--- a/Bugzilla/Error.pm
+++ b/Bugzilla/Error.pm
@@ -13,9 +13,10 @@ use warnings;
use base qw(Exporter);
-@Bugzilla::Error::EXPORT = qw(ThrowCodeError ThrowTemplateError ThrowUserError ThrowErrorPage);
+## no critic (Modules::ProhibitAutomaticExportation)
+our @EXPORT = qw( ThrowCodeError ThrowTemplateError ThrowUserError ThrowErrorPage);
+## use critic
-use Bugzilla::Sentry;
use Bugzilla::Constants;
use Bugzilla::WebService::Constants;
use Bugzilla::Util;
@@ -37,7 +38,7 @@ sub _in_eval {
}
sub _throw_error {
- my ($name, $error, $vars) = @_;
+ my ($name, $error, $vars, $logfunc) = @_;
$vars ||= {};
$vars->{error} = $error;
@@ -47,38 +48,6 @@ sub _throw_error {
my $dbh = eval { Bugzilla->dbh };
$dbh->bz_rollback_transaction() if ($dbh && $dbh->bz_in_transaction() && !_in_eval());
- my $datadir = bz_locations()->{'datadir'};
- # If a writable $datadir/errorlog exists, log error details there.
- if (-w "$datadir/errorlog") {
- require Data::Dumper;
- my $mesg = "";
- for (1..75) { $mesg .= "-"; };
- $mesg .= "\n[$$] " . time2str("%D %H:%M:%S ", time());
- $mesg .= "$name $error ";
- $mesg .= remote_ip();
- $mesg .= Bugzilla->user->login;
- $mesg .= (' actually ' . Bugzilla->sudoer->login) if Bugzilla->sudoer;
- $mesg .= "\n";
- my %params = Bugzilla->cgi->Vars;
- $Data::Dumper::Useqq = 1;
- for my $param (sort keys %params) {
- my $val = $params{$param};
- # obscure passwords
- $val = "*****" if $param =~ /password/i;
- # limit line length
- $val =~ s/^(.{512}).*$/$1\[CHOP\]/;
- $mesg .= "[$$] " . Data::Dumper->Dump([$val],["param($param)"]);
- }
- for my $var (sort keys %ENV) {
- my $val = $ENV{$var};
- $val = "*****" if $val =~ /password|http_pass/i;
- $mesg .= "[$$] " . Data::Dumper->Dump([$val],["env($var)"]);
- }
- open(ERRORLOGFID, ">>", "$datadir/errorlog");
- print ERRORLOGFID "$mesg\n";
- close ERRORLOGFID;
- }
-
my $template = Bugzilla->template;
my $message;
@@ -97,34 +66,24 @@ sub _throw_error {
message => \$message });
if ($Bugzilla::Template::is_processing) {
- $name =~ /^global\/(user|code)-error/;
- my $type = $1 // 'unknown';
+ my ($type) = $name =~ /^global\/(user|code)-error/;
+ $type //= 'unknown';
die Template::Exception->new("bugzilla.$type.$error", $vars);
}
if (Bugzilla->error_mode == ERROR_MODE_WEBPAGE) {
- if (sentry_should_notify($vars->{error})) {
- $vars->{maintainers_notified} = 1;
- $vars->{processed} = {};
- } else {
- $vars->{maintainers_notified} = 0;
- }
-
my $cgi = Bugzilla->cgi;
$cgi->close_standby_message('text/html', 'inline', 'error', 'html');
$template->process($name, $vars)
|| ThrowTemplateError($template->error());
print $cgi->multipart_final() if $cgi->{_multipart_in_progress};
-
- if ($vars->{maintainers_notified}) {
- sentry_handle_error($vars->{error}, $vars->{processed}->{error_message});
- }
+ $logfunc->("webpage error: $error");
}
elsif (Bugzilla->error_mode == ERROR_MODE_TEST) {
die Dumper($vars);
}
elsif (Bugzilla->error_mode == ERROR_MODE_DIE) {
- die("$message\n");
+ die "$message\n";
}
elsif (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT
|| Bugzilla->error_mode == ERROR_MODE_JSON_RPC
@@ -141,6 +100,7 @@ sub _throw_error {
}
if (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT) {
+ $logfunc->("XMLRPC error: $error ($code)");
die SOAP::Fault->faultcode($code)->faultstring($message);
}
else {
@@ -150,6 +110,11 @@ sub _throw_error {
if (Bugzilla->error_mode == ERROR_MODE_REST) {
my %status_code_map = %{ REST_STATUS_CODE_MAP() };
$status_code = $status_code_map{$code} || $status_code_map{'_default'};
+ $logfunc->("REST error: $error (HTTP $status_code, internal code $code)");
+ }
+ else {
+ my $fake_code = 100000 + $code;
+ $logfunc->("JSONRPC error: $error ($fake_code)");
}
# Technically JSON-RPC isn't allowed to have error numbers
# higher than 999, but we do this to avoid conflicts with
@@ -170,22 +135,44 @@ sub _throw_error {
exit;
}
+
+sub _add_vars_to_logging_fields {
+ my ($vars) = @_;
+
+ foreach my $key (keys %$vars) {
+ Bugzilla::Logging->fields->{"var_$key"} = $vars->{$key};
+ }
+}
+
+sub _make_logfunc {
+ my ($type) = @_;
+ my $logger = Log::Log4perl->get_logger("Bugzilla.Error.$type");
+ return sub {
+ local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 3;
+ if ($type eq 'User') {
+ $logger->warn(@_);
+ }
+ else {
+ $logger->error(@_);
+ }
+ };
+}
+
+
sub ThrowUserError {
- _throw_error("global/user-error.html.tmpl", @_);
+ my ($error, $vars) = @_;
+ my $logfunc = _make_logfunc('User');
+ _add_vars_to_logging_fields($vars);
+
+ _throw_error( 'global/user-error.html.tmpl', $error, $vars, $logfunc);
}
sub ThrowCodeError {
- my (undef, $vars) = @_;
-
- # Don't show function arguments, in case they contain
- # confidential data.
- local $Carp::MaxArgNums = -1;
- # Don't show the error as coming from Bugzilla::Error, show it
- # as coming from the caller.
- local $Carp::CarpInternal{'Bugzilla::Error'} = 1;
- $vars->{traceback} //= Carp::longmess();
+ my ($error, $vars) = @_;
+ my $logfunc = _make_logfunc('User');
+ _add_vars_to_logging_fields($vars);
- _throw_error("global/code-error.html.tmpl", @_);
+ _throw_error( 'global/code-error.html.tmpl', $error, $vars, $logfunc );
}
sub ThrowTemplateError {
@@ -211,10 +198,12 @@ sub ThrowTemplateError {
# we never want to display this to the user
exit if $template_err =~ /\bModPerl::Util::exit\b/;
+ state $logger = Log::Log4perl->get_logger('Bugzilla.Error.Template');
+ $logger->error($template_err);
+
$vars->{'template_error_msg'} = $template_err;
$vars->{'error'} = "template_error";
- sentry_handle_error('error', $template_err);
$vars->{'template_error_msg'} =~ s/ at \S+ line \d+\.\s*$//;
my $template = Bugzilla->template;
diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm
index 71169345b..70b195090 100644
--- a/Bugzilla/Install/Filesystem.pm
+++ b/Bugzilla/Install/Filesystem.pm
@@ -186,7 +186,6 @@ sub FILESYSTEM {
my $template_cache = bz_locations()->{'template_cache'};
my $graphsdir = bz_locations()->{'graphsdir'};
my $assetsdir = bz_locations()->{'assetsdir'};
- my $error_reports = bz_locations()->{'error_reports'};
# We want to set the permissions the same for all localconfig files
# across all PROJECTs, so we do something special with $localconfig,
@@ -221,7 +220,6 @@ sub FILESYSTEM {
'runtests.pl' => { perms => OWNER_EXECUTE },
'jobqueue.pl' => { perms => OWNER_EXECUTE },
'migrate.pl' => { perms => OWNER_EXECUTE },
- 'sentry.pl' => { perms => WS_EXECUTE },
'metrics.pl' => { perms => WS_EXECUTE },
'Makefile.PL' => { perms => OWNER_EXECUTE },
'gen-cpanfile.pl' => { perms => OWNER_EXECUTE },
@@ -271,8 +269,6 @@ sub FILESYSTEM {
# Writeable directories
$template_cache => { files => CGI_READ,
dirs => DIR_CGI_OVERWRITE },
- $error_reports => { files => CGI_READ,
- dirs => DIR_CGI_WRITE },
$attachdir => { files => CGI_WRITE,
dirs => DIR_CGI_WRITE },
$webdotdir => { files => WS_SERVE,
@@ -365,7 +361,6 @@ sub FILESYSTEM {
$webdotdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
$assetsdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
$template_cache => DIR_CGI_WRITE,
- $error_reports => DIR_CGI_WRITE,
# Directories that contain content served directly by the web server.
"$skinsdir/custom" => DIR_WS_SERVE,
"$skinsdir/contrib" => DIR_WS_SERVE,
@@ -466,8 +461,6 @@ sub FILESYSTEM {
contents => HT_DEFAULT_DENY },
"$datadir/.htaccess" => { perms => WS_SERVE,
contents => HT_DEFAULT_DENY },
- "$error_reports/.htaccess" => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
"$graphsdir/.htaccess" => { perms => WS_SERVE,
contents => HT_GRAPHS_DIR },
"$webdotdir/.htaccess" => { perms => WS_SERVE,
diff --git a/Bugzilla/Logging.pm b/Bugzilla/Logging.pm
index 769485c86..4a7abcb21 100644
--- a/Bugzilla/Logging.pm
+++ b/Bugzilla/Logging.pm
@@ -10,7 +10,7 @@ use 5.10.1;
use strict;
use warnings;
-use Log::Log4perl;
+use Log::Log4perl qw(:easy);
use Log::Log4perl::MDC;
use File::Spec::Functions qw(rel2abs);
use Bugzilla::Constants qw(bz_locations);
@@ -20,11 +20,15 @@ sub is_interactive {
return not exists $ENV{SERVER_SOFTWARE}
}
+sub fields {
+ return Log::Log4perl::MDC->get_context->{fields} //= {};
+}
+
BEGIN {
my $file = $ENV{LOG4PERL_CONFIG_FILE} // 'log4perl-syslog.conf';
Log::Log4perl::Logger::create_custom_level('NOTICE', 'WARN', 5, 2);
Log::Log4perl->init(rel2abs($file, bz_locations->{confdir}));
- Log::Log4perl->get_logger(__PACKAGE__)->trace("logging enabled in $PROGRAM_NAME");
+ TRACE("logging enabled in $PROGRAM_NAME");
}
# this is copied from Log::Log4perl's :easy handling,
diff --git a/Bugzilla/Sentry.pm b/Bugzilla/Sentry.pm
deleted file mode 100644
index 0d7a9c980..000000000
--- a/Bugzilla/Sentry.pm
+++ /dev/null
@@ -1,374 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#
-# This Source Code Form is "Incompatible With Secondary Licenses", as
-# defined by the Mozilla Public License, v. 2.0.
-
-package Bugzilla::Sentry;
-
-use 5.10.1;
-use strict;
-use warnings;
-
-use base qw(Exporter);
-our @EXPORT = qw(
- sentry_handle_error
- sentry_should_notify
-);
-
-use Carp;
-use DateTime;
-use File::Temp;
-use JSON ();
-use List::MoreUtils qw( any );
-use LWP::UserAgent;
-use Sys::Hostname;
-use URI;
-use URI::QueryParam;
-
-use Bugzilla::Constants;
-use Bugzilla::RNG qw(irand);
-use Bugzilla::Util;
-use Bugzilla::WebService::Constants;
-
-use constant CONFIG => {
- # 'codes' lists the code-errors which are sent to sentry
- codes => [qw(
- bug_error
- chart_datafile_corrupt
- chart_dir_nonexistent
- chart_file_open_fail
- illegal_content_type_method
- jobqueue_insert_failed
- ldap_bind_failed
- mail_send_error
- template_error
- token_generation_error
- param_must_be_numeric
- )],
-
- # any error/warning messages matching these regex's will not be logged or
- # sent to sentry
- ignore => [
- qr/^compiled template :\s*$/,
- qr/^Use of uninitialized value \$compiled in concatenation \(\.\) or string/,
- ],
-
- # any error/warning messages matching these regex's will be logged but not
- # sent to sentry
- sentry_ignore => [
- qr/Software caused connection abort/,
- qr/Could not check out .*\/cvsroot/,
- qr/Unicode character \S+ is illegal/,
- qr/Lost connection to MySQL server during query/,
- qr/Call me again when you have some data to chart/,
- qr/relative paths are not allowed/,
- qr/Illegal mix of collations for operation/,
- ],
-
- # (ab)use the logger to classify error/warning types
- logger => [
- {
- match => [
- qr/DBD::mysql/,
- qr/Can't connect to the database/,
- ],
- logger => 'database_error',
- },
- {
- match => [ qr/PatchReader/ ],
- logger => 'patchreader',
- },
- {
- match => [ qr/Use of uninitialized value/ ],
- logger => 'uninitialized_warning',
- },
- ],
-};
-
-sub sentry_generate_id {
- return sprintf('%04x%04x%04x%04x%04x%04x%04x%04x',
- irand(0xffff), irand(0xffff),
- irand(0xffff),
- irand(0x0fff) | 0x4000,
- irand(0x3fff) | 0x8000,
- irand(0xffff), irand(0xffff), irand(0xffff)
- );
-}
-
-sub sentry_should_notify {
- my $code_error = shift;
- return grep { $_ eq $code_error } @{ CONFIG->{codes} };
-}
-
-sub sentry_handle_error {
- my $level = shift;
- my @message = split(/\n/, shift);
- my $id = sentry_generate_id();
-
- my $is_error = $level eq 'error';
- if ($level ne 'error' && $level ne 'warning') {
- # it's a code-error
- return 0 unless sentry_should_notify($level);
- $is_error = 1;
- $level = 'error';
- }
-
- # build traceback
- my $traceback;
- {
- # for now don't show function arguments, in case they contain
- # confidential data. waiting on bug 700683
- #local $Carp::MaxArgLen = 256;
- #local $Carp::MaxArgNums = 0;
- local $Carp::MaxArgNums = -1;
- local $Carp::CarpInternal{'CGI::Carp'} = 1;
- local $Carp::CarpInternal{'Bugzilla::Error'} = 1;
- local $Carp::CarpInternal{'Bugzilla::Sentry'} = 1;
- $traceback = trim(Carp::longmess());
- }
-
- # strip timestamp
- foreach my $line (@message) {
- $line =~ s/^\[[^\]]+\] //;
- }
- my $message = join(" ", map { trim($_) } grep { $_ ne '' } @message);
-
- # message content filtering
- foreach my $re (@{ CONFIG->{ignore} }) {
- return 0 if $message =~ $re;
- }
-
- # determine logger
- my $logger;
- foreach my $config (@{ CONFIG->{logger} }) {
- foreach my $re (@{ $config->{match} }) {
- if ($message =~ $re) {
- $logger = $config->{logger};
- last;
- }
- }
- last if $logger;
- }
- $logger ||= $level;
-
- # don't send to sentry unless configured
- my $send_to_sentry = Bugzilla->params->{sentry_uri} ? 1 : 0;
-
- # web service filtering
- if ($send_to_sentry
- && (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT || Bugzilla->error_mode == ERROR_MODE_JSON_RPC))
- {
- my ($code) = $message =~ /^(-?\d+): /;
- if ($code
- && !($code == ERROR_UNKNOWN_FATAL || $code == ERROR_UNKNOWN_TRANSIENT))
- {
- $send_to_sentry = 0;
- }
- }
-
- # message content filtering
- if ($send_to_sentry) {
- foreach my $re (@{ CONFIG->{sentry_ignore} }) {
- if ($message =~ $re) {
- $send_to_sentry = 0;
- last;
- }
- }
- }
-
- # invalid boolean search errors need special handling
- if ($message =~ /selectcol_arrayref failed: syntax error/
- && $message =~ /IN BOOLEAN MODE/
- && $message =~ /Bugzilla\/Search\.pm/)
- {
- $send_to_sentry = 0;
- }
-
- # for now, don't send patchreader errors to sentry
- $send_to_sentry = 0
- if $logger eq 'patchreader';
-
- # log to apache's error_log
- if ($send_to_sentry) {
- _write_to_error_log("$message [#$id]", $is_error);
- } else {
- $traceback =~ s/\n/ /g;
- _write_to_error_log("$message $traceback", $is_error);
- }
-
- return 0 unless $send_to_sentry;
-
- my $user_data = undef;
- eval {
- my $user = Bugzilla->user;
- if ($user->id) {
- $user_data = {
- id => $user->login,
- name => $user->name,
- };
- }
- };
-
- my $uri = URI->new(Bugzilla->cgi->self_url);
- $uri->query(undef);
-
- # sanitise
-
- # sanitise these query-string params
- # names are checked as-is as well as prefixed by BUGZILLA_
- my @sanitise_params = qw( PASSWORD TOKEN API_KEY );
-
- # remove these ENV vars
- my @sanitise_vars = qw( HTTP_COOKIE HTTP_X_BUGZILLA_PASSWORD HTTP_X_BUGZILLA_API_KEY HTTP_X_BUGZILLA_TOKEN );
-
- foreach my $var (qw( QUERY_STRING REDIRECT_QUERY_STRING )) {
- next unless exists $ENV{$var};
- my @pairs = split('&', $ENV{$var});
- foreach my $pair (@pairs) {
- next unless $pair =~ /^([^=]+)=(.+)$/;
- my ($param, $value) = ($1, $2);
- if (any { uc($param) eq $_ || uc($param) eq "BUGZILLA_$_" } @sanitise_params) {
- $value = '*';
- }
- $pair = $param . '=' . $value;
- }
- $ENV{$var} = join('&', @pairs);
- }
- foreach my $var (qw( REQUEST_URI HTTP_REFERER )) {
- next unless exists $ENV{$var};
- my $uri = URI->new($ENV{$var});
- foreach my $param ($uri->query_param) {
- if (any { uc($param) eq $_ || uc($param) eq "BUGZILLA_$_" } @sanitise_params) {
- $uri->query_param($param, '*');
- }
- }
- $ENV{$var} = $uri->as_string;
- }
- foreach my $var (@sanitise_vars) {
- delete $ENV{$var};
- }
-
- my $now = DateTime->now();
- my $data = {
- event_id => $id,
- message => $message,
- timestamp => $now->iso8601(),
- level => $level,
- platform => 'Other',
- logger => $logger,
- server_name => hostname(),
- 'sentry.interfaces.User' => $user_data,
- 'sentry.interfaces.Http' => {
- url => $uri->as_string,
- method => $ENV{REQUEST_METHOD},
- query_string => $ENV{QUERY_STRING},
- env => \%ENV,
- },
- extra => {
- stacktrace => $traceback,
- },
- };
-
- my $fh = File::Temp->new(
- DIR => bz_locations()->{error_reports},
- TEMPLATE => $now->ymd('') . $now->hms('') . '-XXXX',
- SUFFIX => '.dump',
- UNLINK => 0,
-
- );
- if (!$fh) {
- warn "Failed to create dump file: $!\n";
- return;
- }
- print $fh JSON->new->utf8(1)->pretty(0)->allow_nonref(1)->encode($data);
- close($fh);
- return 1;
-}
-
-sub _write_to_error_log {
- my ($message, $is_error) = @_;
- if ($ENV{MOD_PERL}) {
- require Apache2::Log;
- if ($is_error) {
- Apache2::ServerRec::log_error($message);
- } else {
- Apache2::ServerRec::warn($message);
- }
- } else {
- print STDERR $message, "\n";
- }
-}
-
-# lifted from Bugzilla::Error
-sub _in_eval {
- my $in_eval = 0;
- for (my $stack = 1; my $sub = (caller($stack))[3]; $stack++) {
- last if $sub =~ /^ModPerl/;
- last if $sub =~ /^Bugzilla::Template/;
- $in_eval = 1 if $sub =~ /^\(eval\)/;
- }
- return $in_eval;
-}
-
-sub _sentry_die_handler {
- my $message = shift;
- $message =~ s/^undef error - //;
-
- # avoid recursion, and check for CGI::Carp::die failures
- my $in_cgi_carp_die = 0;
- for (my $stack = 1; my $sub = (caller($stack))[3]; $stack++) {
- return if $sub =~ /:_sentry_die_handler$/;
- $in_cgi_carp_die = 1 if $sub =~ /CGI::Carp::die$/;
- }
-
- return if $Bugzilla::Template::is_processing;
- return if _in_eval();
-
- # mod_perl overrides exit to call die with this string
- exit if $message =~ /\bModPerl::Util::exit\b/;
-
- my $nested_error = '';
- my $is_compilation_failure = $message =~ /\bcompilation (aborted|failed)\b/i;
-
- # if we are called via CGI::Carp::die chances are something is seriously
- # wrong, so skip trying to use ThrowTemplateError
- if (!$in_cgi_carp_die && !$is_compilation_failure) {
- eval {
- my $cgi = Bugzilla->cgi;
- $cgi->close_standby_message('text/html', 'inline', 'error', 'html');
- Bugzilla::Error::ThrowTemplateError($message);
- print $cgi->multipart_final() if $cgi->{_multipart_in_progress};
- };
- $nested_error = $@ if $@;
- }
-
- if ($is_compilation_failure ||
- $in_cgi_carp_die ||
- ($nested_error && $nested_error !~ /\bModPerl::Util::exit\b/)
- ) {
- sentry_handle_error('error', $message);
-
- # and call the normal error management
- # (ISE for web pages, error response for web services, etc)
- CORE::die($message);
- }
- exit;
-}
-
-sub install_sentry_handler {
- $SIG{__DIE__} = \&sentry_die_handler;
- $SIG{__WARN__} = sub {
- return if _in_eval();
- sentry_handle_error('warning', shift);
- };
-}
-
-BEGIN {
- if ($ENV{SCRIPT_NAME} || $ENV{MOD_PERL}) {
- install_sentry_handler();
- }
-}
-
-1;
diff --git a/Log/Log4perl/Layout/Mozilla.pm b/Log/Log4perl/Layout/Mozilla.pm
index 67a070c54..b625c54f4 100644
--- a/Log/Log4perl/Layout/Mozilla.pm
+++ b/Log/Log4perl/Layout/Mozilla.pm
@@ -52,6 +52,7 @@ sub render {
);
my $mdc = Log::Log4perl::MDC->get_context;
+ my $fields = $mdc->{fields} // {};
my %out = (
EnvVersion => LOGGING_FORMAT_VERSION,
Hostname => $HOSTNAME,
@@ -60,12 +61,12 @@ sub render {
Severity => $Log::Log4perl::Level::SYSLOG{$priority},
Timestamp => time() * 1e9,
Type => $category,
- Fields => { msg => $msg, %$mdc },
+ Fields => { msg => $msg, %$fields },
);
my $json_text = $JSON->encode(\%out) . "\n";
if (length($json_text) > $self->max_json_length) {
- my $scary_msg = sprintf( "DANGER! LOG MESSAGE TOO BIG %d > %d", length($json_text), $self->max_json_length );
+ my $scary_msg = sprintf 'DANGER! LOG MESSAGE TOO BIG %d > %d', length($json_text), $self->max_json_length;
$out{Fields} = { remote_ip => $mdc->{remote_ip}, msg => $scary_msg };
$out{Severity} = 1; # alert
$json_text = $JSON->encode(\%out) . "\n";
diff --git a/conf/log4perl-test.conf b/conf/log4perl-test.conf
index 65558ba4f..34b163073 100644
--- a/conf/log4perl-test.conf
+++ b/conf/log4perl-test.conf
@@ -16,3 +16,5 @@ log4perl.appender.File = Log::Log4perl::Appender::File
log4perl.appender.File.layout = Log::Log4perl::Layout::Mozilla
log4perl.appender.File.filename = /app/bugzilla.log
log4perl.appender.File.mode = append
+log4perl.appender.File.syswrite = 1
+log4perl.appender.File.autoflush = 1
diff --git a/scripts/nagios_blocker_checker.pl b/scripts/nagios_blocker_checker.pl
index 0a9ec96b6..a02a1602a 100755
--- a/scripts/nagios_blocker_checker.pl
+++ b/scripts/nagios_blocker_checker.pl
@@ -12,10 +12,10 @@ use warnings;
use lib qw(. lib local/lib/perl5);
use Bugzilla;
+use Bugzilla::Logging;
use Bugzilla::Constants;
use Bugzilla::Product;
use Bugzilla::User;
-use Bugzilla::Sentry;
use Getopt::Long;
use English qw(-no_match_vars);
@@ -141,7 +141,7 @@ try {
# nagios check does no good, we terminate if we stick around too long.
local $SIG{ALRM} = sub {
my $message = "$PROGRAM_NAME ran for longer than $config->{max_runtime} seconds and was auto-terminated.";
- sentry_handle_error('error', $message);
+ FATAL($message);
die "$message\n";
};
alarm($config->{max_runtime});
diff --git a/sentry.pl b/sentry.pl
deleted file mode 100755
index ebb221cfd..000000000
--- a/sentry.pl
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/perl
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#
-# This Source Code Form is "Incompatible With Secondary Licenses", as
-# defined by the Mozilla Public License, v. 2.0.
-
-#
-# report errors to sentry
-# expects a filename with a Data::Dumper serialised parameters
-# called by Bugzilla::Sentry
-#
-
-use 5.10.1;
-use strict;
-use warnings;
-use lib qw(. lib local/lib/perl5);
-
-BEGIN {
- delete $ENV{SERVER_SOFTWARE};
-
- use Bugzilla::Constants;
- exit(0) unless glob(bz_locations()->{error_reports} . '/*.dump');
-}
-
-use Bugzilla;
-use Fcntl qw(:flock);
-use File::Slurp qw(read_file);
-use HTTP::Request::Common;
-use LWP::UserAgent;
-use POSIX qw(nice);
-use URI;
-
-Bugzilla->usage_mode(USAGE_MODE_CMDLINE);
-nice(19);
-
-exit(1) unless Bugzilla->params->{sentry_uri};
-my $uri = URI->new(Bugzilla->params->{sentry_uri});
-my $header = build_header($uri);
-exit(1) unless $header;
-
-my $ua = LWP::UserAgent->new(timeout => 10);
-if (my $proxy_url = Bugzilla->params->{proxy_url}) {
- $ua->proxy(['http', 'https'], $proxy_url);
-}
-
-flock(DATA, LOCK_EX);
-foreach my $file (glob(bz_locations()->{error_reports} . '/*.dump')) {
- eval {
- send_file($uri, $header, $file);
- };
-}
-
-sub build_header {
- my ($uri) = @_;
-
- # split the sentry uri
- return undef unless $uri->userinfo && $uri->path;
- my ($public_key, $secret_key) = split(/:/, $uri->userinfo);
- $uri->userinfo(undef);
- my $project_id = $uri->path;
- $project_id =~ s/^\///;
- $uri->path("/api/$project_id/store/");
-
- # build the header
- return {
- 'X-Sentry-Auth' => sprintf(
- "Sentry sentry_version=%s, sentry_timestamp=%s, sentry_key=%s, sentry_client=%s, sentry_secret=%s",
- '2.0',
- (time),
- $public_key,
- 'bmo/' . BUGZILLA_VERSION,
- $secret_key,
- ),
- 'Content-Type' => 'application/json'
- };
-}
-
-sub send_file {
- my ($uri, $header, $filename) = @_;
- # read data dump
- my $message = read_file($filename);
- unlink($filename);
-
- # and post to sentry
- my $request = POST $uri->canonical, %$header, Content => $message;
- my $response = $ua->request($request);
-}
-
-__DATA__
-this exists so the flock() code works.
-do not remove this data section.
diff --git a/template/en/default/admin/params/advanced.html.tmpl b/template/en/default/admin/params/advanced.html.tmpl
index 92c84d703..7c85881d7 100644
--- a/template/en/default/admin/params/advanced.html.tmpl
+++ b/template/en/default/admin/params/advanced.html.tmpl
@@ -68,11 +68,6 @@
disable_bug_updates =>
"When enabled, all updates to $terms.bugs will be blocked.",
- sentry_uri =>
- "When set, important errors and warnings will be sent to the"
- _ " specified Sentry server. Enter the full API KEY URL."
- _ " eg <kbd>https://01234567890123456780123456780123:01234567890123456780123456780123@errormill.mozilla.org/10</kbd>.",
-
metrics_enabled =>
"Collect metrics for reporting to ElasticSearch",
metrics_user_ids =>
diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl
index bf1ff5ad3..b37e7ca7b 100644
--- a/template/en/default/global/code-error.html.tmpl
+++ b/template/en/default/global/code-error.html.tmpl
@@ -532,9 +532,6 @@
admindocslinks = admindocslinks
%]
-[%# return the generated error_message for sentry %]
-[% processed.error_message = error_message %]
-
<p>
[% terms.Bugzilla %] has suffered an internal error:
</p>
@@ -543,13 +540,6 @@
[% error_message FILTER none %]
</p>
-[% IF maintainers_notified %]
-<p>
- The [% terms.Bugzilla %] maintainers have been notified of this error
- [#[% uid FILTER html %]].
-</p>
-[% END %]
-
[% IF variables %]
<pre>
Variables: