*/ protected static $php_error_types = array( E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR,E_DEPRECATED, ); /** * Initialization * @param string|null $dsn Sentry DSN * (optional, default: from sentry.dsn config key if set, null otherwise) * @param float|null $traces_sample_rate Sentry traces sample rate * (optional, default: from sentry.traces_sample_rate config key if set, * 0.2 otherwise) * @param array|null $php_error_types Types of PHP error to log in Sentry * (optional, default: from sentry.php_error_types config key if set, * otherwise, see self::$php_error_types) * @return void */ public static function init($dsn=null, $traces_sample_rate=null, $php_error_types=null) { // In phpstan context, do not initialize if (defined('__PHPSTAN_RUNNING__') && constant('__PHPSTAN_RUNNING__')) return; \Sentry\init([ 'dsn' => $dsn?$dsn:App::get('sentry.dsn'), 'traces_sample_rate' => ( $traces_sample_rate? $traces_sample_rate: App::get('sentry.traces_sample_rate', 0.2, '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'], ]); }); if (!is_array($php_error_types)) $php_error_types = App::get( 'sentry.php_error_types', self :: $php_error_types, 'array' ); self :: $php_error_types = array(); foreach($php_error_types 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 occured : [%s] %s\nFile : %s (line : %d)", Log :: errno2type($errno), $errstr, $errfile, $errline ); return false; } } # vim: tabstop=2 shiftwidth=2 softtabstop=2 expandtab