blob: a80778f4c442ac22caca0bdc7b60707f081e72af [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.hadoop.chukwa.inputtools.log4j;
/**
* Log4JMetricsContext is a plugin for reporting Hadoop Metrics through
* syslog protocol. Usage:
*
* Copy hadoop-metrics.properties file from CHUKWA_HOME/conf to HADOOP_HOME/conf.
* Copy chukwa-hadoop-*-client.jar and json.jar to HADOOP_HOME/lib
*
*/
import org.apache.hadoop.metrics.ContextFactory;
import org.apache.hadoop.metrics.MetricsException;
import org.apache.hadoop.metrics.spi.AbstractMetricsContext;
import org.apache.hadoop.metrics.spi.OutputRecord;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.json.simple.JSONObject;
import java.util.TreeMap;
import java.util.Map;
import java.util.Collection;
import java.io.IOException;
import org.apache.hadoop.chukwa.util.ExceptionUtil;
public class Log4JMetricsContext extends AbstractMetricsContext {
Logger log = Logger.getLogger(Log4JMetricsContext.class);
Logger out = null;
static final Object lock = new Object();
/* Configuration attribute names */
protected static final String PERIOD_PROPERTY = "period";
protected static final String HOST_PROPERTY = "host";
protected static final String PORT_PROPERTY = "port";
protected int period = 0;
protected String host = "localhost";
protected int port = 9095;
/** Creates a new instance of MetricsContext */
public Log4JMetricsContext() {
}
public void init(String contextName, ContextFactory factory) {
super.init(contextName, factory);
String periodStr = getAttribute(PERIOD_PROPERTY);
if (periodStr != null) {
int period = 0;
try {
period = Integer.parseInt(periodStr);
} catch (NumberFormatException nfe) {
log.debug(ExceptionUtil.getStackTrace(nfe));
}
if (period <= 0) {
throw new MetricsException("Invalid period: " + periodStr);
}
setPeriod(period);
this.period = period;
log.info("Log4JMetricsContext." + contextName + ".period=" + period);
}
String host = getAttribute(HOST_PROPERTY);
if (host != null) {
this.host = host;
}
String port = getAttribute(PORT_PROPERTY);
if (port != null) {
this.port = Integer.parseInt(port);
}
}
@Override
protected void emitRecord(String contextName, String recordName,
OutputRecord outRec) throws IOException {
synchronized (lock) {
if (out == null) {
PatternLayout layout = new PatternLayout("%d{ISO8601} %p %c: %m%n");
org.apache.log4j.net.SocketAppender appender = new org.apache.log4j.net.SocketAppender(host, port);
appender.setName("chukwa.metrics." + contextName);
appender.setLayout(layout);
Logger logger = Logger.getLogger("chukwa.metrics." + contextName);
logger.setAdditivity(false);
logger.addAppender(appender);
appender.activateOptions();
out = logger;
}
JSONObject json = new JSONObject();
try {
json.put("contextName", contextName);
json.put("recordName", recordName);
json.put("timestamp", System.currentTimeMillis());
json.put("period", period);
for (String tagName : outRec.getTagNames()) {
json.put(tagName, outRec.getTag(tagName));
}
for (String metricName : outRec.getMetricNames()) {
json.put(metricName, outRec.getMetric(metricName));
}
} catch (Exception e) {
log.warn("exception in Log4jMetricsContext:" , e);
}
out.info(json.toString());
}
}
@Override
public synchronized Map<String, Collection<OutputRecord>> getAllRecords() {
Map<String, Collection<OutputRecord>> out = new TreeMap<String, Collection<OutputRecord>>();
/* for (String recordName : bufferedData.keySet()) {
RecordMap recordMap = bufferedData.get(recordName);
synchronized (recordMap) {
List<OutputRecord> records = new ArrayList<OutputRecord>();
Set<Entry<TagMap, MetricMap>> entrySet = recordMap.entrySet();
for (Entry<TagMap, MetricMap> entry : entrySet) {
OutputRecord outRec = new OutputRecord(entry.getKey(), entry.getValue());
records.add(outRec);
}
out.put(recordName, records);
}
}*/
return out;
}
}