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.log;
019
020import java.io.*;
021import java.net.*;
022import java.util.regex.Pattern;
023
024import javax.servlet.*;
025import javax.servlet.http.*;
026
027import org.apache.commons.logging.*;
028import org.apache.commons.logging.impl.*;
029import org.apache.hadoop.classification.InterfaceAudience;
030import org.apache.hadoop.classification.InterfaceStability;
031import org.apache.hadoop.http.HttpServer2;
032import org.apache.hadoop.util.ServletUtil;
033
034/**
035 * Change log level in runtime.
036 */
037@InterfaceStability.Evolving
038public 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}