alluxio.cli.LogLevel.java Source code

Java tutorial

Introduction

Here is the source code for alluxio.cli.LogLevel.java

Source

/*
 * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
 * (the "License"). You may not use this work except in compliance with the License, which is
 * available at www.apache.org/licenses/LICENSE-2.0
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied, as more fully set forth in the License.
 *
 * See the NOTICE file distributed with this work for information regarding copyright ownership.
 */

package alluxio.cli;

import alluxio.Constants;
import alluxio.client.block.AlluxioBlockStore;
import alluxio.client.block.BlockWorkerInfo;
import alluxio.util.network.HttpUtils;
import alluxio.util.network.NetworkAddressUtils;
import alluxio.util.network.NetworkAddressUtils.ServiceType;
import alluxio.wire.LogInfo;
import alluxio.wire.WorkerNetAddress;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang.StringUtils;
import org.apache.http.client.utils.URIBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.concurrent.NotThreadSafe;

/**
 * Sets or gets the log level for the specified server.
 */
@NotThreadSafe
public final class LogLevel {
    private static final String LOG_LEVEL = "logLevel";
    private static final String ROLE_WORKERS = "workers";
    private static final String ROLE_MASTER = "master";
    private static final String ROLE_WORKER = "worker";
    private static final String TARGET_SEPARATOR = ",";
    private static final String TARGET_OPTION_NAME = "target";
    private static final Option TARGET_OPTION = Option.builder().required(false).longOpt(TARGET_OPTION_NAME)
            .hasArg(true)
            .desc("<master|workers|host:webPort>." + " A list of targets separated by " + TARGET_SEPARATOR
                    + " can be specified." + " host:webPort pair must be one of workers."
                    + " Default target is master and all workers")
            .build();
    private static final String LOG_NAME_OPTION_NAME = "logName";
    private static final Option LOG_NAME_OPTION = Option.builder().required(true).longOpt(LOG_NAME_OPTION_NAME)
            .hasArg(true).desc("The logger's name(e.g. alluxio.master.file.DefaultFileSystemMaster)"
                    + " you want to get or set level.")
            .build();
    private static final String LEVEL_OPTION_NAME = "level";
    private static final Option LEVEL_OPTION = Option.builder().required(false).longOpt(LEVEL_OPTION_NAME)
            .hasArg(true).desc("The log level to be set.").build();
    private static final Options OPTIONS = new Options().addOption(TARGET_OPTION).addOption(LOG_NAME_OPTION)
            .addOption(LEVEL_OPTION);

    /**
     * Prints the help message.
     *
     * @param message message before standard usage information
     */
    public static void printHelp(String message) {
        System.err.println(message);
        HelpFormatter help = new HelpFormatter();
        help.printHelp(LOG_LEVEL, OPTIONS, true);
    }

    /**
     * Implements log level setting and getting.
     *
     * @param args list of arguments contains target, logName and level
     * @exception ParseException if there is an error in parsing
     */
    public static void logLevel(String[] args) throws ParseException, IOException {
        CommandLineParser parser = new DefaultParser();
        CommandLine cmd = parser.parse(OPTIONS, args, true /* stopAtNonOption */);

        List<TargetInfo> targets = parseOptTarget(cmd);
        String logName = parseOptLogName(cmd);
        String level = parseOptLevel(cmd);

        for (TargetInfo targetInfo : targets) {
            setLogLevel(targetInfo, logName, level);
        }
    }

    private static List<TargetInfo> parseOptTarget(CommandLine cmd) throws IOException {
        String[] targets;
        if (cmd.hasOption(TARGET_OPTION_NAME)) {
            String argTarget = cmd.getOptionValue(TARGET_OPTION_NAME);
            if (StringUtils.isBlank(argTarget)) {
                throw new IOException("Option " + TARGET_OPTION_NAME + " can not be blank.");
            } else if (argTarget.contains(TARGET_SEPARATOR)) {
                targets = argTarget.split(TARGET_SEPARATOR);
            } else {
                targets = new String[] { argTarget };
            }
        } else {
            targets = new String[] { ROLE_MASTER, ROLE_WORKERS };
        }
        return getTargetInfos(targets);
    }

    private static List<TargetInfo> getTargetInfos(String[] targets) throws IOException {
        List<TargetInfo> targetInfoList = new ArrayList<>();
        for (String target : targets) {
            if (target.equals(ROLE_MASTER)) {
                String masterHost = NetworkAddressUtils.getConnectHost(ServiceType.MASTER_WEB);
                int masterPort = NetworkAddressUtils.getPort(ServiceType.MASTER_WEB);
                targetInfoList.add(new TargetInfo(masterHost, masterPort, ROLE_MASTER));
            } else if (target.equals(ROLE_WORKERS)) {
                AlluxioBlockStore alluxioBlockStore = AlluxioBlockStore.create();
                List<BlockWorkerInfo> workerInfoList = alluxioBlockStore.getAllWorkers();
                for (BlockWorkerInfo workerInfo : workerInfoList) {
                    WorkerNetAddress netAddress = workerInfo.getNetAddress();
                    targetInfoList.add(new TargetInfo(netAddress.getHost(), netAddress.getWebPort(), ROLE_WORKER));
                }
            } else if (target.contains(":")) {
                String[] hostPortPair = target.split(":");
                int port = Integer.parseInt(hostPortPair[1]);
                targetInfoList.add(new TargetInfo(hostPortPair[0], port, ROLE_WORKER));
            } else {
                throw new IOException("Unrecognized target argument: " + target);
            }
        }
        return targetInfoList;
    }

    private static String parseOptLogName(CommandLine cmd) {
        String argName = cmd.getOptionValue(LOG_NAME_OPTION_NAME);
        if (StringUtils.isNotBlank(argName)) {
            return argName;
        }
        return "";
    }

    private static String parseOptLevel(CommandLine cmd) {
        if (cmd.hasOption(LEVEL_OPTION_NAME)) {
            String argLevel = cmd.getOptionValue(LEVEL_OPTION_NAME);
            if (StringUtils.isNotBlank(argLevel)) {
                return argLevel;
            }
        }
        return null;
    }

    private static void setLogLevel(final TargetInfo targetInfo, String logName, String level) throws IOException {
        URIBuilder uriBuilder = new URIBuilder();
        uriBuilder.setScheme("http");
        uriBuilder.setHost(targetInfo.getHost());
        uriBuilder.setPort(targetInfo.getPort());
        uriBuilder.setPath(Constants.REST_API_PREFIX + "/" + targetInfo.getRole() + "/" + LOG_LEVEL);
        uriBuilder.addParameter(LOG_NAME_OPTION_NAME, logName);
        if (level != null) {
            uriBuilder.addParameter(LEVEL_OPTION_NAME, level);
        }
        HttpUtils.post(uriBuilder.toString(), 5000, new HttpUtils.IProcessInputStream() {
            @Override
            public void process(InputStream inputStream) throws IOException {
                ObjectMapper mapper = new ObjectMapper();
                LogInfo logInfo = mapper.readValue(inputStream, LogInfo.class);
                System.out.println(targetInfo.toString() + logInfo.toString());
            }
        });
    }

    /**
     * Sets or gets log level of master and worker through their REST API.
     *
     * @param args same arguments as {@link LogLevel}
     */
    public static void main(String[] args) {
        int exitCode = 1;
        try {
            logLevel(args);
            exitCode = 0;
        } catch (ParseException e) {
            printHelp("Unable to parse input args: " + e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println(String.format("Failed to set log level: %s", e.getMessage()));
        }
        System.exit(exitCode);
    }

    private LogLevel() {
    } // this class is not intended for instantiation

    private static final class TargetInfo {
        private String mRole;
        private String mHost;
        private int mPort;

        public TargetInfo(String host, int port, String role) {
            mHost = host;
            mPort = port;
            mRole = role;
        }

        public int getPort() {
            return mPort;
        }

        public String getHost() {
            return mHost;
        }

        public String getRole() {
            return mRole;
        }

        @Override
        public String toString() {
            return mHost + ":" + mPort + "[" + mRole + "]";
        }
    }
}