You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by GitBox <gi...@apache.org> on 2022/02/10 04:07:53 UTC

[GitHub] [pulsar] Jason918 commented on a change in pull request #14200: Broker: support dynamic update log level at runtime

Jason918 commented on a change in pull request #14200:
URL: https://github.com/apache/pulsar/pull/14200#discussion_r803283040



##########
File path: pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdBrokers.java
##########
@@ -176,6 +176,19 @@ void run() throws Exception {
         }
     }
 
+    @Parameters(commandDescription = "Update dynamic log4j2 logger level in runtime by classname.")
+    private class UpdateLoggerLevelCmd extends CliCommand {
+        @Parameter(names = "--classname", description = "The except class name", required = true)

Review comment:
       Add "-c" for short? 

##########
File path: pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdBrokers.java
##########
@@ -176,6 +176,19 @@ void run() throws Exception {
         }
     }
 
+    @Parameters(commandDescription = "Update dynamic log4j2 logger level in runtime by classname.")
+    private class UpdateLoggerLevelCmd extends CliCommand {
+        @Parameter(names = "--classname", description = "The except class name", required = true)
+        private String classname;
+        @Parameter(names = "--level", description = "The target logger level", required = true)

Review comment:
       Add "-l" for short?

##########
File path: pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/BrokersBase.java
##########
@@ -437,5 +441,67 @@ private void doShutDownBrokerGracefully(int maxConcurrentUnloadPerSec,
         pulsar().getBrokerService().unloadNamespaceBundlesGracefully(maxConcurrentUnloadPerSec, forcedTerminateTopic);
         pulsar().closeAsync();
     }
+
+    /**
+     * dynamically update log4j2 logger level in runtime.
+     *
+     * @param targetClassName
+     * @param targetLevel
+     */
+    private synchronized void updateLoggerLevel(String targetClassName, String targetLevel) {
+        try {
+            String className;
+            if (targetClassName.trim().equalsIgnoreCase("ROOT")) {

Review comment:
       Please add this usage in command description.

##########
File path: pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/BrokersBase.java
##########
@@ -437,5 +441,67 @@ private void doShutDownBrokerGracefully(int maxConcurrentUnloadPerSec,
         pulsar().getBrokerService().unloadNamespaceBundlesGracefully(maxConcurrentUnloadPerSec, forcedTerminateTopic);
         pulsar().closeAsync();
     }
+
+    /**
+     * dynamically update log4j2 logger level in runtime.
+     *
+     * @param targetClassName
+     * @param targetLevel
+     */
+    private synchronized void updateLoggerLevel(String targetClassName, String targetLevel) {
+        try {
+            String className;
+            if (targetClassName.trim().equalsIgnoreCase("ROOT")) {
+                className = LogManager.ROOT_LOGGER_NAME;
+            } else {
+                try {
+                    className = targetClassName.trim();
+                    // Check if class name valid
+                    Class.forName(className);
+                } catch (ClassNotFoundException e) {
+                    // Logger not found
+                    throw new RestException(Status.NOT_FOUND, "Logger not found.");
+                }
+            }
+
+            Level level;
+            try {
+                level = Level.valueOf(targetLevel);
+            } catch (IllegalArgumentException e) {
+                // Level not found
+                throw new RestException(Status.PRECONDITION_FAILED, "Invalid logger level.");
+            }
+
+            if (level != null) {
+                Level originLevel = LogManager.getLogger(className).getLevel();
+                Configurator.setAllLevels(className, level);
+                LOG.info("[{}] Successfully update log level for className: {} ({} -> {}.)", clientAppId(), className, originLevel, level);
+            } else {
+                LOG.error("[{}] Failed to update log level for {}", clientAppId(), className);
+            }
+        } catch (RestException re) {
+            LOG.error("[{}] Failed to update log level for className: {}, targetLevel: {} due to rest exception.", clientAppId(), targetClassName, targetLevel);
+            throw re;
+        } catch (Exception ie) {
+            LOG.error("[{}] Failed to update log level for {} to {} due to internal error.",
+              clientAppId(), targetClassName, targetLevel);
+            throw new RestException(ie);
+        }
+    }
+
+    @POST
+    @Path("/log4j/{classname}/{level}")
+    @ApiOperation(value =
+      "update dynamic log4j2 logger level in runtime by classname. This operation requires Pulsar super-user privileges.")
+    @ApiResponses(value = {
+      @ApiResponse(code = 204, message = "class logger level updated successfully"),
+      @ApiResponse(code = 403, message = "You don't have admin permission to update log4j2 logger level."),
+      @ApiResponse(code = 500, message = "Internal server error")})
+    public void updateLoggerLevelDynamically(@PathParam("classname") String classname,

Review comment:
       Can you implement this in async? 

##########
File path: pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/BrokersBase.java
##########
@@ -437,5 +441,67 @@ private void doShutDownBrokerGracefully(int maxConcurrentUnloadPerSec,
         pulsar().getBrokerService().unloadNamespaceBundlesGracefully(maxConcurrentUnloadPerSec, forcedTerminateTopic);
         pulsar().closeAsync();
     }
+
+    /**
+     * dynamically update log4j2 logger level in runtime.
+     *
+     * @param targetClassName
+     * @param targetLevel
+     */
+    private synchronized void updateLoggerLevel(String targetClassName, String targetLevel) {
+        try {
+            String className;
+            if (targetClassName.trim().equalsIgnoreCase("ROOT")) {
+                className = LogManager.ROOT_LOGGER_NAME;
+            } else {
+                try {
+                    className = targetClassName.trim();
+                    // Check if class name valid
+                    Class.forName(className);
+                } catch (ClassNotFoundException e) {
+                    // Logger not found
+                    throw new RestException(Status.NOT_FOUND, "Logger not found.");
+                }
+            }
+
+            Level level;
+            try {
+                level = Level.valueOf(targetLevel);
+            } catch (IllegalArgumentException e) {
+                // Level not found
+                throw new RestException(Status.PRECONDITION_FAILED, "Invalid logger level.");
+            }
+
+            if (level != null) {
+                Level originLevel = LogManager.getLogger(className).getLevel();
+                Configurator.setAllLevels(className, level);
+                LOG.info("[{}] Successfully update log level for className: {} ({} -> {}.)", clientAppId(), className, originLevel, level);
+            } else {
+                LOG.error("[{}] Failed to update log level for {}", clientAppId(), className);

Review comment:
       throw exception for failure?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@pulsar.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org