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     */
018    package org.apache.hadoop.log;
019    
020    import java.io.*;
021    import java.net.*;
022    import java.util.regex.Pattern;
023    
024    import javax.servlet.*;
025    import javax.servlet.http.*;
026    
027    import org.apache.commons.logging.*;
028    import org.apache.commons.logging.impl.*;
029    import org.apache.hadoop.classification.InterfaceAudience;
030    import org.apache.hadoop.classification.InterfaceStability;
031    import org.apache.hadoop.http.HttpServer2;
032    import org.apache.hadoop.util.ServletUtil;
033    
034    /**
035     * Change log level in runtime.
036     */
037    @InterfaceStability.Evolving
038    public class LogLevel {
039      public static final String USAGES = "\nUsage: General options are:\n"
040          + "\t[-getlevel <host:httpPort> <name>]\n"
041          + "\t[-setlevel <host:httpPort> <name> <level>]\n";
042    
043      /**
044       * A command line implementation
045       */
046      public static void main(String[] args) {
047        if (args.length == 3 && "-getlevel".equals(args[0])) {
048          process("http://" + args[1] + "/logLevel?log=" + args[2]);
049          return;
050        }
051        else if (args.length == 4 && "-setlevel".equals(args[0])) {
052          process("http://" + args[1] + "/logLevel?log=" + args[2]
053                  + "&level=" + args[3]);
054          return;
055        }
056    
057        System.err.println(USAGES);
058        System.exit(-1);
059      }
060    
061      private static void process(String urlstring) {
062        try {
063          URL url = new URL(urlstring);
064          System.out.println("Connecting to " + url);
065          URLConnection connection = url.openConnection();
066          connection.connect();
067    
068          BufferedReader in = new BufferedReader(new InputStreamReader(
069              connection.getInputStream()));
070          for(String line; (line = in.readLine()) != null; )
071            if (line.startsWith(MARKER)) {
072              System.out.println(TAG.matcher(line).replaceAll(""));
073            }
074          in.close();
075        } catch (IOException ioe) {
076          System.err.println("" + ioe);
077        }
078      }
079    
080      static final String MARKER = "<!-- OUTPUT -->";
081      static final Pattern TAG = Pattern.compile("<[^>]*>");
082    
083      /**
084       * A servlet implementation
085       */
086      @InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
087      @InterfaceStability.Unstable
088      public static class Servlet extends HttpServlet {
089        private static final long serialVersionUID = 1L;
090    
091        @Override
092        public void doGet(HttpServletRequest request, HttpServletResponse response
093            ) throws ServletException, IOException {
094    
095          // Do the authorization
096          if (!HttpServer2.hasAdministratorAccess(getServletContext(), request,
097              response)) {
098            return;
099          }
100    
101          PrintWriter out = ServletUtil.initHTML(response, "Log Level");
102          String logName = ServletUtil.getParameter(request, "log");
103          String level = ServletUtil.getParameter(request, "level");
104    
105          if (logName != null) {
106            out.println("<br /><hr /><h3>Results</h3>");
107            out.println(MARKER
108                + "Submitted Log Name: <b>" + logName + "</b><br />");
109    
110            Log log = LogFactory.getLog(logName);
111            out.println(MARKER
112                + "Log Class: <b>" + log.getClass().getName() +"</b><br />");
113            if (level != null) {
114              out.println(MARKER + "Submitted Level: <b>" + level + "</b><br />");
115            }
116    
117            if (log instanceof Log4JLogger) {
118              process(((Log4JLogger)log).getLogger(), level, out);
119            }
120            else if (log instanceof Jdk14Logger) {
121              process(((Jdk14Logger)log).getLogger(), level, out);
122            }
123            else {
124              out.println("Sorry, " + log.getClass() + " not supported.<br />");
125            }
126          }
127    
128          out.println(FORMS);
129          out.println(ServletUtil.HTML_TAIL);
130        }
131    
132        static final String FORMS = "\n<br /><hr /><h3>Get / Set</h3>"
133            + "\n<form>Log: <input type='text' size='50' name='log' /> "
134            + "<input type='submit' value='Get Log Level' />"
135            + "</form>"
136            + "\n<form>Log: <input type='text' size='50' name='log' /> "
137            + "Level: <input type='text' name='level' /> "
138            + "<input type='submit' value='Set Log Level' />"
139            + "</form>";
140    
141        private static void process(org.apache.log4j.Logger log, String level,
142            PrintWriter out) throws IOException {
143          if (level != null) {
144            if (!level.equals(org.apache.log4j.Level.toLevel(level).toString())) {
145              out.println(MARKER + "Bad level : <b>" + level + "</b><br />");
146            } else {
147              log.setLevel(org.apache.log4j.Level.toLevel(level));
148              out.println(MARKER + "Setting Level to " + level + " ...<br />");
149            }
150          }
151          out.println(MARKER
152              + "Effective level: <b>" + log.getEffectiveLevel() + "</b><br />");
153        }
154    
155        private static void process(java.util.logging.Logger log, String level,
156            PrintWriter out) throws IOException {
157          if (level != null) {
158            log.setLevel(java.util.logging.Level.parse(level));
159            out.println(MARKER + "Setting Level to " + level + " ...<br />");
160          }
161    
162          java.util.logging.Level lev;
163          for(; (lev = log.getLevel()) == null; log = log.getParent());
164          out.println(MARKER + "Effective level: <b>" + lev + "</b><br />");
165        }
166      }
167    }