001/* 002 * GangliaContext.java 003 * 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020 021package org.apache.hadoop.metrics.ganglia; 022 023import java.io.IOException; 024import java.net.DatagramPacket; 025import java.net.SocketAddress; 026import java.net.UnknownHostException; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.apache.hadoop.conf.Configuration; 031import org.apache.hadoop.metrics.ContextFactory; 032import org.apache.hadoop.net.DNS; 033 034/** 035 * Context for sending metrics to Ganglia version 3.1.x. 036 * 037 * 3.1.1 has a slightly different wire portal compared to 3.0.x. 038 * 039 * @deprecated Use {@link org.apache.hadoop.metrics2.sink.ganglia.GangliaSink31} 040 * instead. 041 */ 042@Deprecated 043public class GangliaContext31 extends GangliaContext { 044 045 String hostName = "UNKNOWN.example.com"; 046 047 private static final Log LOG = 048 LogFactory.getLog("org.apache.hadoop.util.GangliaContext31"); 049 050 public void init(String contextName, ContextFactory factory) { 051 super.init(contextName, factory); 052 053 LOG.debug("Initializing the GangliaContext31 for Ganglia 3.1 metrics."); 054 055 // Take the hostname from the DNS class. 056 057 Configuration conf = new Configuration(); 058 059 if (conf.get("slave.host.name") != null) { 060 hostName = conf.get("slave.host.name"); 061 } else { 062 try { 063 hostName = DNS.getDefaultHost( 064 conf.get("dfs.datanode.dns.interface","default"), 065 conf.get("dfs.datanode.dns.nameserver","default")); 066 } catch (UnknownHostException uhe) { 067 LOG.error(uhe); 068 hostName = "UNKNOWN.example.com"; 069 } 070 } 071 } 072 073 protected void emitMetric(String name, String type, String value) 074 throws IOException 075 { 076 if (name == null) { 077 LOG.warn("Metric was emitted with no name."); 078 return; 079 } else if (value == null) { 080 LOG.warn("Metric name " + name +" was emitted with a null value."); 081 return; 082 } else if (type == null) { 083 LOG.warn("Metric name " + name + ", value " + value + " has no type."); 084 return; 085 } 086 087 if (LOG.isDebugEnabled()) { 088 LOG.debug("Emitting metric " + name + ", type " + type + ", value " + 089 value + " from hostname" + hostName); 090 } 091 092 String units = getUnits(name); 093 int slope = getSlope(name); 094 int tmax = getTmax(name); 095 int dmax = getDmax(name); 096 offset = 0; 097 String groupName = name.substring(0,name.lastIndexOf(".")); 098 099 // The following XDR recipe was done through a careful reading of 100 // gm_protocol.x in Ganglia 3.1 and carefully examining the output of 101 // the gmetric utility with strace. 102 103 // First we send out a metadata message 104 xdr_int(128); // metric_id = metadata_msg 105 xdr_string(hostName); // hostname 106 xdr_string(name); // metric name 107 xdr_int(0); // spoof = False 108 xdr_string(type); // metric type 109 xdr_string(name); // metric name 110 xdr_string(units); // units 111 xdr_int(slope); // slope 112 xdr_int(tmax); // tmax, the maximum time between metrics 113 xdr_int(dmax); // dmax, the maximum data value 114 115 xdr_int(1); /*Num of the entries in extra_value field for 116 Ganglia 3.1.x*/ 117 xdr_string("GROUP"); /*Group attribute*/ 118 xdr_string(groupName); /*Group value*/ 119 120 for (SocketAddress socketAddress : metricsServers) { 121 DatagramPacket packet = 122 new DatagramPacket(buffer, offset, socketAddress); 123 datagramSocket.send(packet); 124 } 125 126 // Now we send out a message with the actual value. 127 // Technically, we only need to send out the metadata message once for 128 // each metric, but I don't want to have to record which metrics we did and 129 // did not send. 130 offset = 0; 131 xdr_int(133); // we are sending a string value 132 xdr_string(hostName); // hostName 133 xdr_string(name); // metric name 134 xdr_int(0); // spoof = False 135 xdr_string("%s"); // format field 136 xdr_string(value); // metric value 137 138 for (SocketAddress socketAddress : metricsServers) { 139 DatagramPacket packet = 140 new DatagramPacket(buffer, offset, socketAddress); 141 datagramSocket.send(packet); 142 } 143 } 144 145}