内容简介:本文主要研究一下ElasticsearchUncaughtExceptionHandlerelasticsearch-7.0.1/server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
序
本文主要研究一下ElasticsearchUncaughtExceptionHandler
ElasticsearchUncaughtExceptionHandler
class ElasticsearchUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { private static final Logger logger = LogManager.getLogger(ElasticsearchUncaughtExceptionHandler.class); @Override public void uncaughtException(Thread t, Throwable e) { if (isFatalUncaught(e)) { try { onFatalUncaught(t.getName(), e); } finally { // we use specific error codes in case the above notification failed, at least we // will have some indication of the error bringing us down if (e instanceof InternalError) { halt(128); } else if (e instanceof OutOfMemoryError) { halt(127); } else if (e instanceof StackOverflowError) { halt(126); } else if (e instanceof UnknownError) { halt(125); } else if (e instanceof IOError) { halt(124); } else { halt(1); } } } else { onNonFatalUncaught(t.getName(), e); } } static boolean isFatalUncaught(Throwable e) { return e instanceof Error; } void onFatalUncaught(final String threadName, final Throwable t) { logger.error(() -> new ParameterizedMessage("fatal error in thread [{}], exiting", threadName), t); } void onNonFatalUncaught(final String threadName, final Throwable t) { logger.warn(() -> new ParameterizedMessage("uncaught exception in thread [{}]", threadName), t); } void halt(int status) { AccessController.doPrivileged(new PrivilegedHaltAction(status)); } static class PrivilegedHaltAction implements PrivilegedAction<Void> { private final int status; private PrivilegedHaltAction(final int status) { this.status = status; } @SuppressForbidden(reason = "halt") @Override public Void run() { // we halt to prevent shutdown hooks from running Runtime.getRuntime().halt(status); return null; } } }
- ElasticsearchUncaughtExceptionHandler实现了Thread.UncaughtExceptionHandler接口
-
uncaughtException方法首先判断throwable是否是Error类型,是的话则执行onFatalUncaught(
logger.error
),然后执行halt方法,不是则执行onNonFatalUncaught(logger.warn
) - halt方法AccessController.doPrivileged来执行对应status的PrivilegedHaltAction,该action执行的是Runtime.getRuntime().halt(status)
Bootstrap.init
elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
final class Bootstrap { private static volatile Bootstrap INSTANCE; private volatile Node node; private final CountDownLatch keepAliveLatch = new CountDownLatch(1); private final Thread keepAliveThread; private final Spawner spawner = new Spawner(); //...... static void init( final boolean foreground, final Path pidFile, final boolean quiet, final Environment initialEnv) throws BootstrapException, NodeValidationException, UserException { // force the class initializer for BootstrapInfo to run before // the security manager is installed BootstrapInfo.init(); INSTANCE = new Bootstrap(); final SecureSettings keystore = loadSecureSettings(initialEnv); final Environment environment = createEnvironment(pidFile, keystore, initialEnv.settings(), initialEnv.configFile()); LogConfigurator.setNodeName(Node.NODE_NAME_SETTING.get(environment.settings())); try { LogConfigurator.configure(environment); } catch (IOException e) { throw new BootstrapException(e); } if (environment.pidFile() != null) { try { PidFile.create(environment.pidFile(), true); } catch (IOException e) { throw new BootstrapException(e); } } final boolean closeStandardStreams = (foreground == false) || quiet; try { if (closeStandardStreams) { final Logger rootLogger = LogManager.getRootLogger(); final Appender maybeConsoleAppender = Loggers.findAppender(rootLogger, ConsoleAppender.class); if (maybeConsoleAppender != null) { Loggers.removeAppender(rootLogger, maybeConsoleAppender); } closeSystOut(); } // fail if somebody replaced the lucene jars checkLucene(); // install the default uncaught exception handler; must be done before security is // initialized as we do not want to grant the runtime permission // setDefaultUncaughtExceptionHandler Thread.setDefaultUncaughtExceptionHandler(new ElasticsearchUncaughtExceptionHandler()); INSTANCE.setup(true, environment); try { // any secure settings must be read during node construction IOUtils.close(keystore); } catch (IOException e) { throw new BootstrapException(e); } INSTANCE.start(); if (closeStandardStreams) { closeSysError(); } } catch (NodeValidationException | RuntimeException e) { // disable console logging, so user does not see the exception twice (jvm will show it already) final Logger rootLogger = LogManager.getRootLogger(); final Appender maybeConsoleAppender = Loggers.findAppender(rootLogger, ConsoleAppender.class); if (foreground && maybeConsoleAppender != null) { Loggers.removeAppender(rootLogger, maybeConsoleAppender); } Logger logger = LogManager.getLogger(Bootstrap.class); // HACK, it sucks to do this, but we will run users out of disk space otherwise if (e instanceof CreationException) { // guice: log the shortened exc to the log file ByteArrayOutputStream os = new ByteArrayOutputStream(); PrintStream ps = null; try { ps = new PrintStream(os, false, "UTF-8"); } catch (UnsupportedEncodingException uee) { assert false; e.addSuppressed(uee); } new StartupException(e).printStackTrace(ps); ps.flush(); try { logger.error("Guice Exception: {}", os.toString("UTF-8")); } catch (UnsupportedEncodingException uee) { assert false; e.addSuppressed(uee); } } else if (e instanceof NodeValidationException) { logger.error("node validation exception\n{}", e.getMessage()); } else { // full exception logger.error("Exception", e); } // re-enable it if appropriate, so they can see any logging during the shutdown process if (foreground && maybeConsoleAppender != null) { Loggers.addAppender(rootLogger, maybeConsoleAppender); } throw e; } } //...... }
- Bootstrap的init静态方法使用Thread.setDefaultUncaughtExceptionHandler(new ElasticsearchUncaughtExceptionHandler())来给线程设置defaultUncaughtExceptionHandler
小结
-
ElasticsearchUncaughtExceptionHandler实现了Thread.UncaughtExceptionHandler接口;uncaughtException方法首先判断throwable是否是Error类型,是的话则执行onFatalUncaught(
logger.error
),然后执行halt方法,不是则执行onNonFatalUncaught(logger.warn
) - halt方法AccessController.doPrivileged来执行对应status的PrivilegedHaltAction,该action执行的是Runtime.getRuntime().halt(status)
- Bootstrap的init静态方法使用Thread.setDefaultUncaughtExceptionHandler(new ElasticsearchUncaughtExceptionHandler())来给线程设置defaultUncaughtExceptionHandler
doc
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。