From d07b2dda47346c3c5b94c3019d0fdfa5165247eb Mon Sep 17 00:00:00 2001 From: Byron Jones Date: Tue, 23 Apr 2013 00:54:36 +0800 Subject: Bug 750170: switch from arecibo to sentry for error reporting --- Bugzilla/Arecibo.pm | 301 --------------------- Bugzilla/Config/Advanced.pm | 2 +- Bugzilla/Error.pm | 14 +- Bugzilla/Install/Filesystem.pm | 2 +- Bugzilla/Sentry.pm | 301 +++++++++++++++++++++ arecibo.pl | 65 ----- sentry.pl | 89 ++++++ .../en/default/admin/params/advanced.html.tmpl | 6 +- template/en/default/global/code-error.html.tmpl | 2 +- 9 files changed, 401 insertions(+), 381 deletions(-) delete mode 100644 Bugzilla/Arecibo.pm create mode 100644 Bugzilla/Sentry.pm delete mode 100755 arecibo.pl create mode 100644 sentry.pl diff --git a/Bugzilla/Arecibo.pm b/Bugzilla/Arecibo.pm deleted file mode 100644 index 08ff11c20..000000000 --- a/Bugzilla/Arecibo.pm +++ /dev/null @@ -1,301 +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::Arecibo; - -use strict; -use warnings; - -use base qw(Exporter); -our @EXPORT = qw( - arecibo_handle_error - arecibo_generate_id - arecibo_should_notify -); - -use Apache2::Log; -use Apache2::SubProcess; -use Carp; -use Data::Dumper; -use Email::Date::Format qw(email_gmdate); -use File::Temp; -use LWP::UserAgent; -use Sys::Hostname; - -use Bugzilla::Constants; -use Bugzilla::Util; -use Bugzilla::WebService::Constants; - -use constant CONFIG => { - # 'types' maps from the error message to types and priorities - types => [ - { - type => 'the_schwartz', - boost => -10, - match => [ - qr/TheSchwartz\.pm/, - ], - }, - { - type => 'database_error', - boost => -10, - match => [ - qr/DBD::mysql/, - qr/Can't connect to the database/, - ], - }, - { - type => 'patch_reader', - boost => +5, - match => [ - qr#/PatchReader/#, - ], - }, - { - type => 'uninitialized_warning', - boost => 0, - match => [ - qr/Use of uninitialized value/, - ], - }, - ], - - # 'codes' lists the code-errors which are sent to arecibo - 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 - )], - - # any error messages matching these regex's will not be sent to arecibo - ignore => [ - qr/Software caused connection abort/, - qr/Could not check out .*\/cvsroot/, - ], -}; - -sub arecibo_generate_id { - return sprintf("%s.%s", (time), $$); -} - -sub arecibo_should_notify { - my $code_error = shift; - return grep { $_ eq $code_error } @{CONFIG->{codes}}; -} - -sub arecibo_handle_error { - my $class = shift; - my @message = split(/\n/, shift); - my $id = arecibo_generate_id(); - - my $is_error = $class eq 'error'; - if ($class ne 'error' && $class ne 'warning') { - # it's a code-error - return 0 unless arecibo_should_notify($class); - $is_error = 1; - } - - # 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::Arecibo'} = 1; - $traceback = Carp::longmess(); - } - - # strip timestamp - foreach my $line (@message) { - $line =~ s/^\[[^\]]+\] //; - } - my $message = join(" ", map { trim($_) } grep { $_ ne '' } @message); - - # don't send to arecibo unless configured - my $arecibo_server = Bugzilla->params->{arecibo_server} || ''; - my $send_to_arecibo = $arecibo_server ne ''; - - # web service filtering - if ($send_to_arecibo - && (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_arecibo = 0; - } - } - - # message content filtering - if ($send_to_arecibo) { - foreach my $re (@{CONFIG->{ignore}}) { - if ($message =~ $re) { - $send_to_arecibo = 0; - last; - } - } - } - - # log to apache's error_log - if ($send_to_arecibo) { - $message .= " [#$id]"; - } else { - $traceback =~ s/\n/ /g; - $message .= " $traceback"; - } - _write_to_error_log($message, $is_error); - - return 0 unless $send_to_arecibo; - - # set the error type and priority from the message content - $message = join("\n", grep { $_ ne '' } @message); - my $type = ''; - my $priority = $class eq 'error' ? 3 : 10; - foreach my $rh_type (@{CONFIG->{types}}) { - foreach my $re (@{$rh_type->{match}}) { - if ($message =~ $re) { - $type = $rh_type->{type}; - $priority += $rh_type->{boost}; - last; - } - } - last if $type ne ''; - } - $type ||= $class; - $priority = 1 if $priority < 1; - $priority = 10 if $priority > 10; - - my $username = ''; - eval { $username = Bugzilla->user->login }; - - my $request = ''; - foreach my $name (sort { lc($a) cmp lc($b) } keys %ENV) { - $request .= "$name=$ENV{$name}\n"; - } - chomp($request); - - my $data = [ - ip => remote_ip(), - msg => $message, - priority => $priority, - server => hostname(), - request => $request, - status => '500', - timestamp => email_gmdate(), - traceback => $traceback, - type => $type, - uid => $id, - url => Bugzilla->cgi->self_url, - user_agent => $ENV{HTTP_USER_AGENT}, - username => $username, - ]; - - my $fh = File::Temp->new( UNLINK => 0 ); - if (!$fh) { - warn "Failed to create temp file: $!\n"; - return; - } - print $fh Dumper($data); - close($fh) or die $!; - my $filename = $fh->filename; - - my $command = bz_locations()->{'cgi_path'} . "/arecibo.pl '$filename' &"; - system($command); - return 1; -} - -sub _write_to_error_log { - my ($message, $is_error) = @_; - if ($ENV{MOD_PERL}) { - 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 _arecibo_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 =~ /:_arecibo_die_handler$/; - $in_cgi_carp_die = 1 if $sub =~ /CGI::Carp::die$/; - } - - 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 { Bugzilla::Error::ThrowTemplateError($message) }; - $nested_error = $@ if $@; - } - - if ($is_compilation_failure || - $in_cgi_carp_die || - ($nested_error && $nested_error !~ /\bModPerl::Util::exit\b/) - ) { - arecibo_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_arecibo_handler { - require CGI::Carp; - CGI::Carp::set_die_handler(\&_arecibo_die_handler); - $main::SIG{__WARN__} = sub { - return if _in_eval(); - arecibo_handle_error('warning', shift); - }; -} - -BEGIN { - if ($ENV{SCRIPT_NAME} || $ENV{MOD_PERL}) { - install_arecibo_handler(); - } -} - -1; diff --git a/Bugzilla/Config/Advanced.pm b/Bugzilla/Config/Advanced.pm index a5ae3048a..5e51fbecc 100644 --- a/Bugzilla/Config/Advanced.pm +++ b/Bugzilla/Config/Advanced.pm @@ -71,7 +71,7 @@ use constant get_param_list => ( }, { - name => 'arecibo_server', + name => 'sentry_uri', type => 't', default => '', }, diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm index e49f466d6..08978fa93 100644 --- a/Bugzilla/Error.pm +++ b/Bugzilla/Error.pm @@ -28,7 +28,7 @@ use base qw(Exporter); @Bugzilla::Error::EXPORT = qw(ThrowCodeError ThrowTemplateError ThrowUserError ThrowErrorPage); -use Bugzilla::Arecibo; +use Bugzilla::Sentry; use Bugzilla::Constants; use Bugzilla::WebService::Constants; use Bugzilla::Util; @@ -110,9 +110,8 @@ sub _throw_error { message => \$message }); if (Bugzilla->error_mode == ERROR_MODE_WEBPAGE) { - if (arecibo_should_notify($vars->{error})) { + if (sentry_should_notify($vars->{error})) { $vars->{maintainers_notified} = 1; - $vars->{uid} = arecibo_generate_id(); $vars->{processed} = {}; } else { $vars->{maintainers_notified} = 0; @@ -123,8 +122,7 @@ sub _throw_error { || ThrowTemplateError($template->error()); if ($vars->{maintainers_notified}) { - arecibo_handle_error( - $vars->{error}, $vars->{processed}->{error_message}, $vars->{uid}); + sentry_handle_error($vars->{error}, $vars->{processed}->{error_message}); } } elsif (Bugzilla->error_mode == ERROR_MODE_TEST) { @@ -206,8 +204,7 @@ sub ThrowTemplateError { $vars->{'template_error_msg'} = $template_err; $vars->{'error'} = "template_error"; - $vars->{'uid'} = arecibo_generate_id(); - arecibo_handle_error('error', $template_err, $vars->{'uid'}); + sentry_handle_error('error', $template_err); $vars->{'template_error_msg'} =~ s/ at \S+ line \d+\.\s*$//; my $template = Bugzilla->template; @@ -218,7 +215,6 @@ sub ThrowTemplateError { my $maintainer = html_quote(Bugzilla->params->{'maintainer'}); my $error = html_quote($vars->{'template_error_msg'}); my $error2 = html_quote($template->error()); - my $uid = html_quote($vars->{'uid'}); print <

@@ -232,7 +228,7 @@ sub ThrowTemplateError { -->

The Bugzilla maintainers have - been notified of this error [#$uid]. + been notified of this error.

END diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm index 86978163b..1abac0154 100644 --- a/Bugzilla/Install/Filesystem.pm +++ b/Bugzilla/Install/Filesystem.pm @@ -159,7 +159,7 @@ sub FILESYSTEM { 'runtests.pl' => { perms => OWNER_EXECUTE }, 'jobqueue.pl' => { perms => OWNER_EXECUTE }, 'migrate.pl' => { perms => OWNER_EXECUTE }, - 'arecibo.pl' => { perms => OWNER_EXECUTE }, + 'sentry.pl' => { perms => OWNER_EXECUTE }, 'install-module.pl' => { perms => OWNER_EXECUTE }, 'Bugzilla.pm' => { perms => CGI_READ }, diff --git a/Bugzilla/Sentry.pm b/Bugzilla/Sentry.pm new file mode 100644 index 000000000..e07c2eb44 --- /dev/null +++ b/Bugzilla/Sentry.pm @@ -0,0 +1,301 @@ +# 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 strict; +use warnings; + +use base qw(Exporter); +our @EXPORT = qw( + sentry_handle_error + sentry_should_notify +); + +use Apache2::Log; +use Apache2::SubProcess; +use Carp; +use Data::Dumper; +use DateTime; +use File::Temp; +use LWP::UserAgent; +use Sys::Hostname; +use URI; + +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 + )], + + # any error messages matching these regex's will not be sent to sentry + ignore => [ + qr/Software caused connection abort/, + qr/Could not check out .*\/cvsroot/, + ], + + # (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); + + # 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->{ignore} }) { + if ($message =~ $re) { + $send_to_sentry = 0; + last; + } + } + } + + # 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); + + my $data = { + event_id => $id, + message => $message, + timestamp => DateTime->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( UNLINK => 0 ); + if (!$fh) { + warn "Failed to create temp file: $!\n"; + return; + } + print $fh Dumper($data); + close($fh) or die $!; + my $filename = $fh->filename; + + my $command = bz_locations()->{'cgi_path'} . "/sentry.pl '$filename' &"; + system($command); + return 1; +} + +sub _write_to_error_log { + my ($message, $is_error) = @_; + if ($ENV{MOD_PERL}) { + 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 _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 { Bugzilla::Error::ThrowTemplateError($message) }; + $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 { + require CGI::Carp; + CGI::Carp::set_die_handler(\&_sentry_die_handler); + $main::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/arecibo.pl b/arecibo.pl deleted file mode 100755 index 93c34c999..000000000 --- a/arecibo.pl +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/perl -w - -# 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 arecibo -# expects a filename with a Data::Dumper serialised parameters -# called by Bugzilla::Arecibo -# - -use strict; -use warnings; - -use FindBin qw($Bin); -use lib $Bin; -use lib "$Bin/lib"; - -use Bugzilla; -use Bugzilla::Constants; -use File::Slurp; -use POSIX qw(setsid nice); -use Safe; -use Fcntl qw(:flock); - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); -nice(19); - -# detach -open(STDIN, '/dev/null'); -open(STDERR, '>/dev/null'); -setsid(); - -# grab arecibo server url -my $arecibo_server = Bugzilla->params->{arecibo_server} || ''; -exit(1) unless $arecibo_server; - -# read data dump -exit(1) unless my $filename = shift; -my $dump = read_file($filename); -unlink($filename); - -# deserialise -my $cpt = new Safe; -$cpt->reval($dump) || exit(1); -my $data = ${$cpt->varglob('VAR1')}; - -# ensure we send warnings one at a time per webhead -flock(DATA, LOCK_EX); - -# and post to arecibo -my $agent = LWP::UserAgent->new( - agent => 'bugzilla.mozilla.org', - timeout => 10, # seconds -); -$agent->post($arecibo_server, $data); - -__DATA__ -this exists so the flock() code works. -do not remove this data section. diff --git a/sentry.pl b/sentry.pl new file mode 100644 index 000000000..b5b9c3f31 --- /dev/null +++ b/sentry.pl @@ -0,0 +1,89 @@ +#!/usr/bin/perl -w + +# 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 strict; +use warnings; + +use FindBin qw($Bin); +use lib $Bin; +use lib "$Bin/lib"; + +use Bugzilla; +use Bugzilla::Constants; +use Bugzilla::RNG qw(irand); +use Fcntl qw(:flock); +use File::Slurp; +use HTTP::Request::Common; +use JSON (); +use LWP::UserAgent; +use POSIX qw(setsid nice); +use Safe; +use URI; + +Bugzilla->usage_mode(USAGE_MODE_CMDLINE); +nice(19); + +# detach +open(STDIN, '/dev/null'); +open(STDERR, '>/dev/null'); +setsid(); + +# grab sentry server url +my $sentry_uri = Bugzilla->params->{sentry_uri} || ''; +exit(1) unless $sentry_uri; + +# read data dump +exit(1) unless my $filename = shift; +my $dump = read_file($filename); +unlink($filename); + +# deserialise +my $cpt = new Safe; +$cpt->reval($dump) || exit(1); +my $data = ${$cpt->varglob('VAR1')}; + +# split the sentry uri +my $uri = URI->new($sentry_uri); +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 message +my $message = JSON->new->utf8(1)->pretty(0)->allow_nonref(1)->encode($data); +my %header = ( + '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, + 'bugzilla/4.2', + $secret_key, + ), + 'Content-Type' => 'application/json' +); + +# ensure we send warnings one at a time per webhead +flock(DATA, LOCK_EX); + +# and post to sentry +my $request = POST $uri->canonical, %header, Content => $message; +my $response = LWP::UserAgent->new->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 1cf0c344f..5301ff2cf 100644 --- a/template/en/default/admin/params/advanced.html.tmpl +++ b/template/en/default/admin/params/advanced.html.tmpl @@ -82,8 +82,8 @@ disable_bug_updates => "When enabled, all updates to $terms.bugs will be blocked.", - arecibo_server => + sentry_uri => "When set, important errors and warnings will be sent to the" - _ " specified Arecibo server. Enter the Arecibo server's full URL;" - _ " eg https://arecibo.example.com/v/1/.", + _ " specified Sentry server. Enter the full API KEY URL." + _ " eg https://01234567890123456780123456780123:01234567890123456780123456780123@errormill.mozilla.org/10.", } %] diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl index 704d3ad16..d98f2578c 100644 --- a/template/en/default/global/code-error.html.tmpl +++ b/template/en/default/global/code-error.html.tmpl @@ -506,7 +506,7 @@ admindocslinks = admindocslinks %] -[%# return the generated error_message for arecibo %] +[%# return the generated error_message for sentry %] [% processed.error_message = error_message %]

-- cgit v1.2.3-24-g4f1b