ElasticsearchUncaught Exception Handler에 대해 얘기를 나눠보도록 하겠습니다.

8560 단어 elasticsearch

순서


본고는 주로 ElasticsearchUncaught ExceptionHandler를 연구하고자 합니다.

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 {

        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에 대응하는 PrivilegedHalt 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
    {}", 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에 대응하는 PrivilegedHalt Action을 실행합니다. 이 동작은 Runtime입니다.getRuntime().halt(status)
  • Bootstrap의 init 정적 방법은Thread를 사용합니다.setDefaultUncaughtExceptionHandler(new ElasticsearchUncaughtExceptionHandler)스레드에 defaultUncaughtExceptionHandler
  • 를 설정합니다.

    doc

  • ElasticsearchUncaughtExceptionHandler
  • 좋은 웹페이지 즐겨찾기