*/ protected static $php_error_types; /** * Initialization * @return void */ public static function init() { // In phpstan context, do not initialize if (defined('__PHPSTAN_RUNNING__') && constant('__PHPSTAN_RUNNING__')) // @phpstan-ignore-line return; // Set config default values App :: set_default( 'sentry', array( 'dsn' => null, 'traces_sample_rate' => 0.2, 'php_error_types' => array( 'E_ERROR', 'E_PARSE', 'E_CORE_ERROR', 'E_COMPILE_ERROR', 'E_USER_ERROR', 'E_RECOVERABLE_ERROR', 'E_DEPRECATED', ), ) ); self :: $dsn = App::get('sentry.dsn'); if (!self :: $dsn) { Log :: trace("SentryIntegration::init(): no DSN configured"); return; } \Sentry\init([ 'dsn' => self :: $dsn, 'traces_sample_rate' => App::get('sentry.traces_sample_rate', null, 'float'), ]); \Sentry\configureScope(function (\Sentry\State\Scope $scope): void { $scope->setUser([ 'username' => Auth::user()?Auth::user()->username:null, 'ip_address' => php_sapi_name()=='cli'?null:$_SERVER['REMOTE_ADDR'], ]); }); self :: $php_error_types = array(); foreach(App::get('sentry.php_error_types', null, 'array') as $php_error_type) { if (is_string($php_error_type) && defined($php_error_type)) $php_error_type = constant($php_error_type); if (!is_int($php_error_type)) continue; if (in_array($php_error_type, self :: $php_error_types)) continue; self :: $php_error_types[] = $php_error_type; } set_error_handler( array('EesyPHP\\SentryIntegration', 'on_php_error'), E_ALL ); } /** * Log an exception or a message in Sentry * @param string|Throwable $message * @param array $extra_args Extra arguments to use to compute message using sprintf * @return void */ public static function log($message, ...$extra_args) { if (!self :: $dsn) { Log :: trace('Sentry DSN not configured, do not log this error'); return; } if (is_string($message)) { // Extra arguments passed, format message using sprintf if ($extra_args) { $message = call_user_func_array( 'sprintf', array_merge(array($message), $extra_args) ); } Log :: debug('Error logged in Sentry'); \Sentry\captureMessage($message); } elseif ($message instanceof Exception) { Log :: debug('Exception logged in Sentry'); \Sentry\captureException($message); } } /** * Log a PHP error in Sentry * Note: method design to be used as callable by set_error_handler() * @param int $errno The error number * @param string $errstr The error message * @param string $errfile The filename that the error was raised in * @param int $errline The line number where the error was raised * @return false Return false to let the normal error handler continues. */ public static function on_php_error($errno, $errstr, $errfile, $errline) { if (in_array($errno, self :: $php_error_types)) self :: log( "A PHP error occurred : [%s] %s\nFile : %s (line : %d)", Log :: errno2type($errno), $errstr, $errfile, $errline ); return false; } } # vim: tabstop=2 shiftwidth=2 softtabstop=2 expandtab