/*
* Copyright 2014 Cloudera Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kitesdk.cli.commands;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import org.apache.avro.generic.GenericRecord;
import org.slf4j.Logger;
@Parameters(commandDescription = "Build a log4j config to log events to a dataset")
public class Log4jConfigCommand extends BaseDatasetCommand {
@Parameter(description = "Dataset name or URI", required = true)
List<String> datasetName;
@Parameter(names={"--host"}, description = "Flume hostname", required = true)
String hostname;
@Parameter(names={"--port"}, description = "Flume port")
int port = 41415;
@Parameter(names={"--class", "--package"}, description = "Java class/package to log from")
String packageName;
@Parameter(names={"--log-all"}, description = "Configure the root logger to send to Flume")
boolean logAll;
@edu.umd.cs.findbugs.annotations.SuppressWarnings(
value="UWF_NULL_FIELD",
justification = "Field set by JCommander")
@Parameter(names={"-o", "--output"}, description="Save logging config to path")
String outputPath = null;
public Log4jConfigCommand(Logger console) {
super(console);
}
@Override
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="NP_NULL_ON_SOME_PATH",
justification="Null case checked by precondition")
public int run() throws IOException {
Preconditions.checkArgument(
datasetName != null && !datasetName.isEmpty(),
"Missing dataset uri");
Preconditions.checkArgument(
hostname != null,
"Missing Flume hostname");
Preconditions.checkArgument(
packageName != null || logAll,
"Must provide a class/package name or specify --log-all");
URL schemaUrl = load(datasetName.get(0), GenericRecord.class).getDataset()
.getDescriptor().getSchemaUrl();
if (schemaUrl == null) {
console.warn("Warning: The dataset {} does not have a schema URL. The schema will be sent with each event.", datasetName.get(0));
}
StringBuilder sb = new StringBuilder();
if (logAll) {
sb.append("# Log events from all classes:\n");
sb.append("log4j.rootLogger = INFO, flume\n");
sb.append("\n");
}
sb.append("log4j.appender.flume = org.apache.flume.clients.log4jappender.Log4jAppender\n");
sb.append("log4j.appender.flume.Hostname = ").append(hostname).append("\n");
sb.append("log4j.appender.flume.Port = ").append(port).append("\n");
sb.append("log4j.appender.flume.UnsafeMode = true").append("\n");
if (schemaUrl != null) {
sb.append("log4j.appender.flume.AvroSchemaUrl = ").append(schemaUrl).append("\n");
}
if (packageName != null) {
sb.append("\n");
sb.append("# Log events from the following Java class/package:\n");
sb.append("log4j.logger.").append(packageName).append(" = INFO, flume\n");
}
output(sb.toString(), console, outputPath);
return 0;
}
@Override
public List<String> getExamples() {
return Lists.newArrayList(
"# Print log4j configuration to log to dataset \"users\":",
"--host flume.cluster.com --class org.kitesdk.examples.MyLoggingApp users",
"# Save log4j configuration to the file \"log4j.properties\":",
"--host flume.cluster.com --package org.kitesdk.examples -o log4j.properties users",
"# Print log4j configuration to log from all classes:",
"--host flume.cluster.com --log-all users"
);
}
}