View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.chukwa.inputtools.log4j;
19  
20  /**
21   * Log4JMetricsContext is a plugin for reporting Hadoop Metrics through
22   * syslog protocol.  Usage:
23   * 
24   * Copy hadoop-metrics.properties file from CHUKWA_HOME/conf to HADOOP_HOME/conf.
25   * Copy chukwa-hadoop-*-client.jar and json.jar to HADOOP_HOME/lib
26   * 
27   */
28  import org.apache.hadoop.metrics.ContextFactory;
29  import org.apache.hadoop.metrics.MetricsException;
30  import org.apache.hadoop.metrics.spi.AbstractMetricsContext;
31  import org.apache.hadoop.metrics.spi.OutputRecord;
32  import org.apache.log4j.Logger;
33  import org.apache.log4j.PatternLayout;
34  import org.json.simple.JSONObject;
35  import java.util.TreeMap;
36  import java.util.Map;
37  import java.util.Collection;
38  import java.io.IOException;
39  import org.apache.hadoop.chukwa.util.ExceptionUtil;
40  
41  public class Log4JMetricsContext extends AbstractMetricsContext {
42    Logger log = Logger.getLogger(Log4JMetricsContext.class);
43    Logger out = null; 
44    static final Object lock = new Object();
45  
46    /* Configuration attribute names */
47    protected static final String PERIOD_PROPERTY = "period";
48    protected static final String HOST_PROPERTY = "host";
49    protected static final String PORT_PROPERTY = "port";  
50  
51    protected int period = 0;
52    protected String host = "localhost";
53    protected int port = 9095;
54    
55    /** Creates a new instance of MetricsContext */
56    public Log4JMetricsContext() {
57    }
58  
59    public void init(String contextName, ContextFactory factory) {
60      super.init(contextName, factory);
61     
62      String periodStr = getAttribute(PERIOD_PROPERTY);
63      if (periodStr != null) {
64        int period = 0;
65        try {
66          period = Integer.parseInt(periodStr);
67        } catch (NumberFormatException nfe) {
68          log.debug(ExceptionUtil.getStackTrace(nfe));
69        }
70        if (period <= 0) {
71          throw new MetricsException("Invalid period: " + periodStr);
72        }
73        setPeriod(period);
74        this.period = period;
75        log.info("Log4JMetricsContext." + contextName + ".period=" + period);
76      }
77      String host = getAttribute(HOST_PROPERTY);
78      if (host != null) {
79        this.host = host;
80      }
81      String port = getAttribute(PORT_PROPERTY);
82      if (port != null) {
83        this.port = Integer.parseInt(port);
84      }
85    }
86  
87    @Override
88    protected void emitRecord(String contextName, String recordName,
89        OutputRecord outRec) throws IOException {
90      synchronized (lock) {
91        if (out == null) {
92          PatternLayout layout = new PatternLayout("%d{ISO8601} %p %c: %m%n");
93            
94          org.apache.log4j.net.SocketAppender appender = new org.apache.log4j.net.SocketAppender(host, port);
95            
96          appender.setName("chukwa.metrics." + contextName);
97          appender.setLayout(layout);
98            
99          Logger logger = Logger.getLogger("chukwa.metrics." + contextName);
100         logger.setAdditivity(false);
101         logger.addAppender(appender);
102         appender.activateOptions();
103         out = logger;
104       }
105       JSONObject json = new JSONObject();
106       try {
107         json.put("contextName", contextName);
108         json.put("recordName", recordName);
109         json.put("chukwa_timestamp", System.currentTimeMillis());
110         json.put("period", period);
111         for (String tagName : outRec.getTagNames()) {
112           json.put(tagName, outRec.getTag(tagName));
113         }
114         for (String metricName : outRec.getMetricNames()) {
115           json.put(metricName, outRec.getMetric(metricName));
116         }
117       } catch (Exception e) {
118         log.warn("exception in Log4jMetricsContext:" , e);
119       }
120       out.info(json.toString());
121     }
122   }
123 
124   @Override
125   public synchronized Map<String, Collection<OutputRecord>> getAllRecords() {
126     Map<String, Collection<OutputRecord>> out = new TreeMap<String, Collection<OutputRecord>>();
127 /*    for (String recordName : bufferedData.keySet()) {
128       RecordMap recordMap = bufferedData.get(recordName);
129       synchronized (recordMap) {
130         List<OutputRecord> records = new ArrayList<OutputRecord>();
131         Set<Entry<TagMap, MetricMap>> entrySet = recordMap.entrySet();
132         for (Entry<TagMap, MetricMap> entry : entrySet) {
133           OutputRecord outRec = new OutputRecord(entry.getKey(), entry.getValue());
134           records.add(outRec);
135         }
136         out.put(recordName, records);
137       }
138     }*/
139     return out;
140   }
141 }