001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.logging; 019 020import java.io.File; 021import java.io.IOException; 022import java.lang.reflect.InvocationTargetException; 023import java.lang.reflect.Method; 024import java.util.Set; 025import org.apache.yetus.audience.InterfaceAudience; 026 027/** 028 * A bridge class for operating on log4j, such as changing log level, etc. 029 * <p/> 030 * Will call the methods in {@link InternalLog4jUtils} to actually operate on the log4j stuff. 031 */ 032@InterfaceAudience.Private 033public final class Log4jUtils { 034 035 private static final String INTERNAL_UTILS_CLASS_NAME = 036 "org.apache.hadoop.hbase.logging.InternalLog4jUtils"; 037 038 private Log4jUtils() { 039 } 040 041 // load class when calling to avoid introducing class not found exception on log4j when loading 042 // this class even without calling any of the methods below. 043 private static Method getMethod(String methodName, Class<?>... args) { 044 try { 045 Class<?> clazz = Class.forName(INTERNAL_UTILS_CLASS_NAME); 046 return clazz.getDeclaredMethod(methodName, args); 047 } catch (ClassNotFoundException | NoSuchMethodException e) { 048 throw new AssertionError("should not happen", e); 049 } 050 } 051 052 private static void throwUnchecked(Throwable throwable) { 053 if (throwable instanceof RuntimeException) { 054 throw (RuntimeException) throwable; 055 } 056 if (throwable instanceof Error) { 057 throw (Error) throwable; 058 } 059 } 060 061 public static void setLogLevel(String loggerName, String levelName) { 062 Method method = getMethod("setLogLevel", String.class, String.class); 063 try { 064 method.invoke(null, loggerName, levelName); 065 } catch (IllegalAccessException e) { 066 throw new AssertionError("should not happen", e); 067 } catch (InvocationTargetException e) { 068 throwUnchecked(e.getCause()); 069 throw new AssertionError("should not happen", e.getCause()); 070 } 071 } 072 073 public static String getEffectiveLevel(String loggerName) { 074 Method method = getMethod("getEffectiveLevel", String.class); 075 try { 076 return (String) method.invoke(null, loggerName); 077 } catch (IllegalAccessException e) { 078 throw new AssertionError("should not happen", e); 079 } catch (InvocationTargetException e) { 080 throwUnchecked(e.getCause()); 081 throw new AssertionError("should not happen", e.getCause()); 082 } 083 } 084 085 @SuppressWarnings("unchecked") 086 public static Set<File> getActiveLogFiles() throws IOException { 087 Method method = getMethod("getActiveLogFiles"); 088 try { 089 return (Set<File>) method.invoke(null); 090 } catch (IllegalAccessException e) { 091 throw new AssertionError("should not happen", e); 092 } catch (InvocationTargetException e) { 093 Throwable cause = e.getCause(); 094 throwUnchecked(cause); 095 if (cause instanceof IOException) { 096 throw (IOException) cause; 097 } 098 throw new AssertionError("should not happen", cause); 099 } 100 } 101 102 /** 103 * Disables Zk- and HBase client logging 104 */ 105 public static void disableZkAndClientLoggers() { 106 // disable zookeeper log to avoid it mess up command output 107 setLogLevel("org.apache.zookeeper", "OFF"); 108 // disable hbase zookeeper tool log to avoid it mess up command output 109 setLogLevel("org.apache.hadoop.hbase.zookeeper", "OFF"); 110 // disable hbase client log to avoid it mess up command output 111 setLogLevel("org.apache.hadoop.hbase.client", "OFF"); 112 } 113 114 /** 115 * Switches the logger for the given class to DEBUG level. 116 * @param clazz The class for which to switch to debug logging. 117 */ 118 public static void enableDebug(Class<?> clazz) { 119 setLogLevel(clazz.getName(), "DEBUG"); 120 } 121}