001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    package org.apache.hadoop.metrics2.sink.ganglia;
020    
021    import java.io.IOException;
022    
023    import org.apache.commons.logging.Log;
024    import org.apache.commons.logging.LogFactory;
025    
026    /**
027     * This code supports Ganglia 3.1
028     *
029     */
030    public class GangliaSink31 extends GangliaSink30 {
031    
032      public final Log LOG = LogFactory.getLog(this.getClass());    
033    
034      /**
035       * The method sends metrics to Ganglia servers. The method has been taken from
036       * org.apache.hadoop.metrics.ganglia.GangliaContext31 with minimal changes in
037       * order to keep it in sync.
038       * @param groupName The group name of the metric
039       * @param name The metric name
040       * @param type The type of the metric
041       * @param value The value of the metric
042       * @param gConf The GangliaConf for this metric
043       * @param gSlope The slope for this metric
044       * @throws IOException
045       */
046      protected void emitMetric(String groupName, String name, String type,
047          String value, GangliaConf gConf, GangliaSlope gSlope) 
048        throws IOException {
049    
050        if (name == null) {
051          LOG.warn("Metric was emitted with no name.");
052          return;
053        } else if (value == null) {
054          LOG.warn("Metric name " + name +" was emitted with a null value.");
055          return;
056        } else if (type == null) {
057          LOG.warn("Metric name " + name + ", value " + value + " has no type.");
058          return;
059        }
060    
061        if (LOG.isDebugEnabled()) {
062          LOG.debug("Emitting metric " + name + ", type " + type + ", value " + value
063              + ", slope " + gSlope.name()+ " from hostname " + getHostName());
064        }
065    
066        // The following XDR recipe was done through a careful reading of
067        // gm_protocol.x in Ganglia 3.1 and carefully examining the output of
068        // the gmetric utility with strace.
069    
070        // First we send out a metadata message
071        xdr_int(128);               // metric_id = metadata_msg
072        xdr_string(getHostName());       // hostname
073        xdr_string(name);           // metric name
074        xdr_int(0);                 // spoof = False
075        xdr_string(type);           // metric type
076        xdr_string(name);           // metric name
077        xdr_string(gConf.getUnits());    // units
078        xdr_int(gSlope.ordinal());  // slope
079        xdr_int(gConf.getTmax());        // tmax, the maximum time between metrics
080        xdr_int(gConf.getDmax());        // dmax, the maximum data value
081        xdr_int(1);                 /*Num of the entries in extra_value field for 
082                                      Ganglia 3.1.x*/
083        xdr_string("GROUP");        /*Group attribute*/
084        xdr_string(groupName);      /*Group value*/
085    
086        // send the metric to Ganglia hosts
087        emitToGangliaHosts();
088    
089        // Now we send out a message with the actual value.
090        // Technically, we only need to send out the metadata message once for
091        // each metric, but I don't want to have to record which metrics we did and
092        // did not send.
093        xdr_int(133);         // we are sending a string value
094        xdr_string(getHostName()); // hostName
095        xdr_string(name);     // metric name
096        xdr_int(0);           // spoof = False
097        xdr_string("%s");     // format field
098        xdr_string(value);    // metric value
099    
100        // send the metric to Ganglia hosts
101        emitToGangliaHosts();
102      }
103    }