jongyoul closed pull request #3272: [ZEPPELIN-3422] Add JMX Support URL: https://github.com/apache/zeppelin/pull/3272
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/bin/common.cmd b/bin/common.cmd index 21657c1133..13f33e5484 100644 --- a/bin/common.cmd +++ b/bin/common.cmd @@ -71,14 +71,6 @@ if not defined ZEPPELIN_JAVA_OPTS ( set ZEPPELIN_JAVA_OPTS=%ZEPPELIN_JAVA_OPTS% -Dfile.encoding=%ZEPPELIN_ENCODING% %ZEPPELIN_MEM% ) -if defined ZEPPELIN_JMX_ENABLE ( - if not defined ZEPPELIN_JMX_PORT ( - set ZEPPELIN_JMX_PORT="9996" - } - set JMX_JAVA_OPTS=" -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=${ZEPPELIN_JMX_PORT} -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" - set ZEPPELIN_JAVA_OPTS=%JMX_JAVA_OPTS% %ZEPPELIN_JAVA_OPTS -) - if not defined JAVA_OPTS ( set JAVA_OPTS=%ZEPPELIN_JAVA_OPTS% ) else ( diff --git a/bin/common.sh b/bin/common.sh index c56fbd40b2..6447ec8daf 100644 --- a/bin/common.sh +++ b/bin/common.sh @@ -121,18 +121,6 @@ JAVA_OPTS+=" ${ZEPPELIN_JAVA_OPTS} -Dfile.encoding=${ZEPPELIN_ENCODING} ${ZEPPEL JAVA_OPTS+=" -Dlog4j.configuration=file://${ZEPPELIN_CONF_DIR}/log4j.properties" export JAVA_OPTS -if [[ x"${ZEPPELIN_JMX_ENABLE}" == x"true" ]]; then - if [[ -z "${ZEPPELIN_JMX_PORT}" ]]; then - ZEPPELIN_JMX_PORT="9996" - fi - JMX_JAVA_OPTS+=" -Dcom.sun.management.jmxremote" - JMX_JAVA_OPTS+=" -Dcom.sun.management.jmxremote.port=${ZEPPELIN_JMX_PORT}" - JMX_JAVA_OPTS+=" -Dcom.sun.management.jmxremote.authenticate=false" - JMX_JAVA_OPTS+=" -Dcom.sun.management.jmxremote.ssl=false" - JAVA_OPTS="${JMX_JAVA_OPTS} ${JAVA_OPTS}" -fi -export JAVA_OPTS - JAVA_INTP_OPTS="${ZEPPELIN_INTP_JAVA_OPTS} -Dfile.encoding=${ZEPPELIN_ENCODING}" if [[ -z "${ZEPPELIN_SPARK_YARN_CLUSTER}" ]]; then JAVA_INTP_OPTS+=" -Dlog4j.configuration=file://${ZEPPELIN_CONF_DIR}/log4j.properties" diff --git a/conf/zeppelin-env.cmd.template b/conf/zeppelin-env.cmd.template index e69f23b071..83b5ee7411 100644 --- a/conf/zeppelin-env.cmd.template +++ b/conf/zeppelin-env.cmd.template @@ -23,7 +23,7 @@ REM set ZEPPELIN_MEM REM Zeppelin jvm mem options Default -Xms1024m REM set ZEPPELIN_INTP_MEM REM zeppelin interpreter process jvm mem options. Default -Xmx1024m -Xms1024m -XX:MaxPermSize=512m REM set ZEPPELIN_INTP_JAVA_OPTS REM zeppelin interpreter process jvm options. REM set ZEPPELIN_JMX_ENABLE REM Enable JMX feature by defining it like "true" -REM set ZEPPELIN_JMX_PORT REM Port number which JMX uses. Default: "9996" +REM set ZEPPELIN_JMX_PORT REM Port number which JMX uses. If not set, JMX won't be enabled REM set ZEPPELIN_LOG_DIR REM Where log files are stored. PWD by default. REM set ZEPPELIN_PID_DIR REM The pid files are stored. /tmp by default. diff --git a/conf/zeppelin-env.sh.template b/conf/zeppelin-env.sh.template index 5aab0e0220..74941b96d5 100644 --- a/conf/zeppelin-env.sh.template +++ b/conf/zeppelin-env.sh.template @@ -24,7 +24,7 @@ # export ZEPPELIN_INTP_JAVA_OPTS # zeppelin interpreter process jvm options. # export ZEPPELIN_SSL_PORT # ssl port (used when ssl environment variable is set to true) # export ZEPPELIN_JMX_ENABLE # Enable JMX feature by defining "true" -# export ZEPPELIN_JMX_PORT # Port number which JMX uses. Default: "9996" +# export ZEPPELIN_JMX_PORT # Port number which JMX uses. If not set, JMX won't be enabled # export ZEPPELIN_LOG_DIR # Where log files are stored. PWD by default. # export ZEPPELIN_PID_DIR # The pid files are stored. ${ZEPPELIN_HOME}/run by default. diff --git a/zeppelin-server/pom.xml b/zeppelin-server/pom.xml index b8da356184..75f0af6e24 100644 --- a/zeppelin-server/pom.xml +++ b/zeppelin-server/pom.xml @@ -227,6 +227,13 @@ <artifactId>jetty-webapp</artifactId> <version>${jetty.version}</version> </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-jmx</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> <groupId>org.eclipse.jetty.websocket</groupId> <artifactId>websocket-server</artifactId> diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java index c7f13a6017..f924fbd022 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java @@ -18,9 +18,13 @@ import java.io.File; import java.io.IOException; +import java.lang.management.ManagementFactory; import java.util.EnumSet; +import java.util.Objects; +import java.util.stream.Stream; import javax.inject.Inject; import javax.inject.Singleton; +import javax.management.remote.JMXServiceURL; import javax.servlet.DispatcherType; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @@ -57,6 +61,8 @@ import org.apache.zeppelin.socket.NotebookServer; import org.apache.zeppelin.user.Credentials; import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.jmx.ConnectorServer; +import org.eclipse.jetty.jmx.MBeanContainer; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.SecureRequestCustomizer; @@ -177,6 +183,51 @@ public void contextDestroyed(ServletContextEvent servletContextEvent) {} // Notebook server setupNotebookServer(webApp, conf, sharedServiceLocator); + // JMX Enable + Stream.of("ZEPPELIN_JMX_ENABLE") + .map(System::getenv) + .map(Boolean::parseBoolean) + .filter(Boolean::booleanValue) + .map(jmxEnabled -> "ZEPPELIN_JMX_PORT") + .map(System::getenv) + .map( + portString -> { + try { + return Integer.parseInt(portString); + } catch (Exception e) { + return null; + } + }) + .filter(Objects::nonNull) + .forEach( + port -> { + try { + MBeanContainer mbeanContainer = + new MBeanContainer(ManagementFactory.getPlatformMBeanServer()); + jettyWebServer.addEventListener(mbeanContainer); + jettyWebServer.addBean(mbeanContainer); + + JMXServiceURL jmxURL = + new JMXServiceURL( + String.format( + "service:jmx:rmi://0.0.0.0:%d/jndi/rmi://0.0.0.0:%d/jmxrmi", + port, port)); + ConnectorServer jmxServer = + new ConnectorServer(jmxURL, "org.eclipse.jetty.jmx:name=rmiconnectorserver"); + jettyWebServer.addBean(jmxServer); + + // Add JMX Beans + // TODO(jl): Need to investigate more about injection and jmx + jettyWebServer.addBean( + sharedServiceLocator.getService(InterpreterSettingManager.class)); + jettyWebServer.addBean(sharedServiceLocator.getService(NotebookServer.class)); + + LOG.info("JMX Enabled with port: {}", port); + } catch (Exception e) { + LOG.warn("Error while setting JMX", e); + } + }); + LOG.info("Starting zeppelin server"); try { jettyWebServer.start(); // Instantiates ZeppelinServer @@ -197,10 +248,7 @@ public void contextDestroyed(ServletContextEvent servletContextEvent) {} try { jettyWebServer.stop(); if (!conf.isRecoveryEnabled()) { - sharedServiceLocator - .getService(Notebook.class) - .getInterpreterSettingManager() - .close(); + sharedServiceLocator.getService(InterpreterSettingManager.class).close(); } sharedServiceLocator.getService(Notebook.class).close(); Thread.sleep(3000); @@ -223,7 +271,7 @@ public void contextDestroyed(ServletContextEvent servletContextEvent) {} jettyWebServer.join(); if (!conf.isRecoveryEnabled()) { - sharedServiceLocator.getService(Notebook.class).getInterpreterSettingManager().close(); + sharedServiceLocator.getService(InterpreterSettingManager.class).close(); } } diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java index 40c7461caf..e83f26f2a0 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java @@ -80,6 +80,9 @@ import org.apache.zeppelin.utils.CorsUtils; import org.apache.zeppelin.utils.InterpreterBindingUtils; import org.apache.zeppelin.utils.TestUtils; +import org.eclipse.jetty.util.annotation.ManagedAttribute; +import org.eclipse.jetty.util.annotation.ManagedObject; +import org.eclipse.jetty.util.annotation.ManagedOperation; import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.glassfish.hk2.api.ServiceLocator; @@ -90,14 +93,14 @@ * Zeppelin websocket service. This class used setter injection because all servlet should have * no-parameter constructor */ +@ManagedObject public class NotebookServer extends WebSocketServlet implements NotebookSocketListener, AngularObjectRegistryListener, RemoteInterpreterProcessListener, ApplicationEventListener, ParagraphJobListener, - NoteEventListener, - NotebookServerMBean { + NoteEventListener { /** * Job manager service type. @@ -1843,12 +1846,12 @@ public void onSuccess(Note note, ServiceContext context) throws IOException { }); } - @Override + @ManagedAttribute public Set<String> getConnectedUsers() { return connectionManager.getConnectedUsers(); } - @Override + @ManagedOperation public void sendMessage(String message) { Message m = new Message(OP.NOTICE); m.data.put("notice", message); diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServerMBean.java b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServerMBean.java deleted file mode 100644 index f94af89955..0000000000 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServerMBean.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.zeppelin.socket; - -import java.util.Set; - -public interface NotebookServerMBean { - Set<String> getConnectedUsers(); - - void sendMessage(String message); -} diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java index d4468ff49b..708fcb721c 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java @@ -54,6 +54,8 @@ import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.util.ReflectionUtils; import org.apache.zeppelin.storage.ConfigStorage; +import org.eclipse.jetty.util.annotation.ManagedAttribute; +import org.eclipse.jetty.util.annotation.ManagedObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonatype.aether.repository.Proxy; @@ -77,7 +79,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -88,8 +89,8 @@ * (load/create/update/remove/get) * TODO(zjffdu) We could move it into another separated component. */ -public class InterpreterSettingManager implements InterpreterSettingManagerMBean, - NoteEventListener { +@ManagedObject("interpreterSettingManager") +public class InterpreterSettingManager implements NoteEventListener { private static final Logger LOGGER = LoggerFactory.getLogger(InterpreterSettingManager.class); private static final Map<String, Object> DEFAULT_EDITOR = ImmutableMap.of( @@ -870,7 +871,7 @@ public void close() { } } - @Override + @ManagedAttribute public Set<String> getRunningInterpreters() { Set<String> runningInterpreters = Sets.newHashSet(); for (Map.Entry<String, InterpreterSetting> entry : interpreterSettings.entrySet()) { diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerMBean.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerMBean.java deleted file mode 100644 index 3cc3b08c0d..0000000000 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerMBean.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.zeppelin.interpreter; - -import java.util.Set; - -public interface InterpreterSettingManagerMBean { - Set<String> getRunningInterpreters(); -} ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services