]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1450679 - Replace custom Sentry integration with Logging
authorDylan William Hardison <dylan@hardison.net>
Tue, 10 Apr 2018 02:51:08 +0000 (22:51 -0400)
committerGitHub <noreply@github.com>
Tue, 10 Apr 2018 02:51:08 +0000 (22:51 -0400)
13 files changed:
Bugzilla.pm
Bugzilla/Config/Advanced.pm
Bugzilla/Constants.pm
Bugzilla/Error.pm
Bugzilla/Install/Filesystem.pm
Bugzilla/Logging.pm
Bugzilla/Sentry.pm [deleted file]
Log/Log4perl/Layout/Mozilla.pm
conf/log4perl-test.conf
scripts/nagios_blocker_checker.pl
sentry.pl [deleted file]
template/en/default/admin/params/advanced.html.tmpl
template/en/default/global/code-error.html.tmpl

index 1188102d3d2b70437cb64014bb73c113a20cd3e0..a8b164b573421038f842d22148491803fdf0a114 100644 (file)
@@ -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.
index 2eec11dbe19ee11d1511caeeaebe14348cb5f344..9316d8e48c9a7f4fbb19dfae39005c94afcc1a95 100644 (file)
@@ -37,12 +37,6 @@ use constant get_param_list => (
         default => 0
     },
 
-    {
-        name    => 'sentry_uri',
-        type    => 't',
-        default => '',
-    },
-
     {
         name    => 'metrics_enabled',
         type    => 'b',
index 6e3a1273623f97af498c60446198b6f8ee6d4997..80d9c4e0c24acf171132474d3fa575159ec8d971 100644 (file)
@@ -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,
     };
 }
index d675718489ae4935026be7937242ddb7f48d1f42..ef57303e98133172d065066d94fd5f4713ed204a 100644 (file)
@@ -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;
index 71169345b04348f0552b8806fa64a801d567b66e..70b195090e7956151dcc3113ab84bab2adb00a3f 100644 (file)
@@ -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,
index 769485c8640c636cbc6ec71a0d5f2f2d5cfcac62..4a7abcb21e256819fe2c0be9d938aaf855d46081 100644 (file)
@@ -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 (file)
index 0d7a9c9..0000000
+++ /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;
index 67a070c54633aaaa6c39e680b88209bd03e39e12..b625c54f489568b4e3028d66f6906105a5e3975d 100644 (file)
@@ -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";
index 65558ba4fc7706d391ed04db38247106a27730b4..34b16307327d7322a8c0bd76f4317c12d4c542da 100644 (file)
@@ -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
index 0a9ec96b6352c54d5051dfc713a54529b01cfd0b..a02a1602a32a9ea6224329f36fb81523aab29ab7 100755 (executable)
@@ -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 (executable)
index ebb221c..0000000
--- 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.
index 92c84d7031b7c0f20af4ef357d49065dd6976408..7c85881d7e8def9dbd46cf528991d28cb09e312c 100644 (file)
   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 =>
index bf1ff5ad37b10fff37b1424c0647a7adac42b9b2..b37e7ca7bf5d637be4df37ecfd402b86ca33d3c1 100644 (file)
    admindocslinks = admindocslinks
 %]
 
-[%# return the generated error_message for sentry %]
-[% processed.error_message = error_message %]
-
 <p>
   [% terms.Bugzilla %] has suffered an internal error:
 </p>
   [% 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: