001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019package org.apache.hadoop.hbase.util;
020
021import java.lang.management.ManagementFactory;
022import java.lang.management.RuntimeMXBean;
023import java.util.Arrays;
024import java.util.HashSet;
025import java.util.Locale;
026import java.util.Map.Entry;
027import java.util.Set;
028
029import org.apache.hadoop.hbase.HConstants;
030import org.apache.hadoop.conf.Configuration;
031import org.apache.hadoop.conf.Configured;
032import org.apache.hadoop.hbase.HBaseConfiguration;
033import org.apache.hadoop.util.Tool;
034import org.apache.hadoop.util.ToolRunner;
035import org.apache.yetus.audience.InterfaceAudience;
036
037import org.slf4j.Logger;
038import org.slf4j.LoggerFactory;
039
040/**
041 * Base class for command lines that start up various HBase daemons.
042 */
043@InterfaceAudience.Private
044public abstract class ServerCommandLine extends Configured implements Tool {
045  private static final Logger LOG = LoggerFactory.getLogger(ServerCommandLine.class);
046  @SuppressWarnings("serial")
047  private static final Set<String> DEFAULT_SKIP_WORDS = new HashSet<String>() {
048    {
049      add("secret");
050      add("passwd");
051      add("password");
052      add("credential");
053    }
054  };
055
056  /**
057   * Implementing subclasses should return a usage string to print out.
058   */
059  protected abstract String getUsage();
060
061  /**
062   * Print usage information for this command line.
063   *
064   * @param message if not null, print this message before the usage info.
065   */
066  protected void usage(String message) {
067    if (message != null) {
068      System.err.println(message);
069      System.err.println("");
070    }
071
072    System.err.println(getUsage());
073  }
074
075  /**
076   * Log information about the currently running JVM.
077   */
078  public static void logJVMInfo() {
079    // Print out vm stats before starting up.
080    RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
081    if (runtime != null) {
082      LOG.info("vmName=" + runtime.getVmName() + ", vmVendor=" +
083               runtime.getVmVendor() + ", vmVersion=" + runtime.getVmVersion());
084      LOG.info("vmInputArguments=" + runtime.getInputArguments());
085    }
086  }
087
088  /**
089   * Print into log some of the important hbase attributes.
090   */
091  private static void logHBaseConfigs(Configuration conf) {
092    final String [] keys = new String [] {
093      // Expand this list as you see fit.
094      "hbase.tmp.dir",
095      HConstants.HBASE_DIR,
096      HConstants.CLUSTER_DISTRIBUTED,
097      HConstants.ZOOKEEPER_QUORUM,
098
099    };
100    for (String key: keys) {
101      LOG.info(key + ": " + conf.get(key));
102    }
103  }
104
105  /**
106   * Logs information about the currently running JVM process including
107   * the environment variables. Logging of env vars can be disabled by
108   * setting {@code "hbase.envvars.logging.disabled"} to {@code "true"}.
109   * <p>If enabled, you can also exclude environment variables containing
110   * certain substrings by setting {@code "hbase.envvars.logging.skipwords"}
111   * to comma separated list of such substrings.
112   */
113  public static void logProcessInfo(Configuration conf) {
114    logHBaseConfigs(conf);
115
116    // log environment variables unless asked not to
117    if (conf == null || !conf.getBoolean("hbase.envvars.logging.disabled", false)) {
118      Set<String> skipWords = new HashSet<>(DEFAULT_SKIP_WORDS);
119      if (conf != null) {
120        String[] confSkipWords = conf.getStrings("hbase.envvars.logging.skipwords");
121        if (confSkipWords != null) {
122          skipWords.addAll(Arrays.asList(confSkipWords));
123        }
124      }
125
126      nextEnv:
127      for (Entry<String, String> entry : System.getenv().entrySet()) {
128        String key = entry.getKey().toLowerCase(Locale.ROOT);
129        String value = entry.getValue().toLowerCase(Locale.ROOT);
130        // exclude variables which may contain skip words
131        for(String skipWord : skipWords) {
132          if (key.contains(skipWord) || value.contains(skipWord))
133            continue nextEnv;
134        }
135        LOG.info("env:"+entry);
136      }
137    }
138
139    // and JVM info
140    logJVMInfo();
141  }
142
143  /**
144   * Parse and run the given command line. This may exit the JVM if
145   * a nonzero exit code is returned from <code>run()</code>.
146   */
147  public void doMain(String args[]) {
148    try {
149      int ret = ToolRunner.run(HBaseConfiguration.create(), this, args);
150      if (ret != 0) {
151        System.exit(ret);
152      }
153    } catch (Exception e) {
154      LOG.error("Failed to run", e);
155      System.exit(-1);
156    }
157  }
158}