You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@zeppelin.apache.org by GitBox <gi...@apache.org> on 2018/12/29 03:26:37 UTC

[GitHub] jongyoul closed pull request #3272: [ZEPPELIN-3422] Add JMX Support

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:
users@infra.apache.org


With regards,
Apache Git Services