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 */ 018package org.apache.hadoop.metrics.spi; 019 020import java.io.IOException; 021import java.lang.reflect.InvocationHandler; 022import java.lang.reflect.Method; 023import java.lang.reflect.Proxy; 024import java.util.ArrayList; 025 026import org.apache.commons.logging.Log; 027import org.apache.commons.logging.LogFactory; 028 029import org.apache.hadoop.classification.InterfaceAudience; 030import org.apache.hadoop.classification.InterfaceStability; 031import org.apache.hadoop.metrics.ContextFactory; 032import org.apache.hadoop.metrics.MetricsContext; 033import org.apache.hadoop.metrics.MetricsRecord; 034import org.apache.hadoop.metrics.MetricsUtil; 035import org.apache.hadoop.metrics.Updater; 036 037/** 038 * @deprecated Use org.apache.hadoop.metrics2 package instead. 039 */ 040@Deprecated 041@InterfaceAudience.Public 042@InterfaceStability.Evolving 043public class CompositeContext extends AbstractMetricsContext { 044 045 private static final Log LOG = LogFactory.getLog(CompositeContext.class); 046 private static final String ARITY_LABEL = "arity"; 047 private static final String SUB_FMT = "%s.sub%d"; 048 private final ArrayList<MetricsContext> subctxt = 049 new ArrayList<MetricsContext>(); 050 051 @InterfaceAudience.Private 052 public CompositeContext() { 053 } 054 055 @InterfaceAudience.Private 056 public void init(String contextName, ContextFactory factory) { 057 super.init(contextName, factory); 058 int nKids; 059 try { 060 String sKids = getAttribute(ARITY_LABEL); 061 nKids = Integer.parseInt(sKids); 062 } catch (Exception e) { 063 LOG.error("Unable to initialize composite metric " + contextName + 064 ": could not init arity", e); 065 return; 066 } 067 for (int i = 0; i < nKids; ++i) { 068 MetricsContext ctxt = MetricsUtil.getContext( 069 String.format(SUB_FMT, contextName, i), contextName); 070 if (null != ctxt) { 071 subctxt.add(ctxt); 072 } 073 } 074 } 075 076 @InterfaceAudience.Private 077 @Override 078 public MetricsRecord newRecord(String recordName) { 079 return (MetricsRecord) Proxy.newProxyInstance( 080 MetricsRecord.class.getClassLoader(), 081 new Class[] { MetricsRecord.class }, 082 new MetricsRecordDelegator(recordName, subctxt)); 083 } 084 085 @InterfaceAudience.Private 086 @Override 087 protected void emitRecord(String contextName, String recordName, 088 OutputRecord outRec) throws IOException { 089 for (MetricsContext ctxt : subctxt) { 090 try { 091 ((AbstractMetricsContext)ctxt).emitRecord( 092 contextName, recordName, outRec); 093 if (contextName == null || recordName == null || outRec == null) { 094 throw new IOException(contextName + ":" + recordName + ":" + outRec); 095 } 096 } catch (IOException e) { 097 LOG.warn("emitRecord failed: " + ctxt.getContextName(), e); 098 } 099 } 100 } 101 102 @InterfaceAudience.Private 103 @Override 104 protected void flush() throws IOException { 105 for (MetricsContext ctxt : subctxt) { 106 try { 107 ((AbstractMetricsContext)ctxt).flush(); 108 } catch (IOException e) { 109 LOG.warn("flush failed: " + ctxt.getContextName(), e); 110 } 111 } 112 } 113 114 @InterfaceAudience.Private 115 @Override 116 public void startMonitoring() throws IOException { 117 for (MetricsContext ctxt : subctxt) { 118 try { 119 ctxt.startMonitoring(); 120 } catch (IOException e) { 121 LOG.warn("startMonitoring failed: " + ctxt.getContextName(), e); 122 } 123 } 124 } 125 126 @InterfaceAudience.Private 127 @Override 128 public void stopMonitoring() { 129 for (MetricsContext ctxt : subctxt) { 130 ctxt.stopMonitoring(); 131 } 132 } 133 134 /** 135 * Return true if all subcontexts are monitoring. 136 */ 137 @InterfaceAudience.Private 138 @Override 139 public boolean isMonitoring() { 140 boolean ret = true; 141 for (MetricsContext ctxt : subctxt) { 142 ret &= ctxt.isMonitoring(); 143 } 144 return ret; 145 } 146 147 @InterfaceAudience.Private 148 @Override 149 public void close() { 150 for (MetricsContext ctxt : subctxt) { 151 ctxt.close(); 152 } 153 } 154 155 @InterfaceAudience.Private 156 @Override 157 public void registerUpdater(Updater updater) { 158 for (MetricsContext ctxt : subctxt) { 159 ctxt.registerUpdater(updater); 160 } 161 } 162 163 @InterfaceAudience.Private 164 @Override 165 public void unregisterUpdater(Updater updater) { 166 for (MetricsContext ctxt : subctxt) { 167 ctxt.unregisterUpdater(updater); 168 } 169 } 170 171 private static class MetricsRecordDelegator implements InvocationHandler { 172 private static final Method m_getRecordName = initMethod(); 173 private static Method initMethod() { 174 try { 175 return MetricsRecord.class.getMethod("getRecordName", new Class[0]); 176 } catch (Exception e) { 177 throw new RuntimeException("Internal error", e); 178 } 179 } 180 181 private final String recordName; 182 private final ArrayList<MetricsRecord> subrecs; 183 184 MetricsRecordDelegator(String recordName, ArrayList<MetricsContext> ctxts) { 185 this.recordName = recordName; 186 this.subrecs = new ArrayList<MetricsRecord>(ctxts.size()); 187 for (MetricsContext ctxt : ctxts) { 188 subrecs.add(ctxt.createRecord(recordName)); 189 } 190 } 191 192 public Object invoke(Object p, Method m, Object[] args) throws Throwable { 193 if (m_getRecordName.equals(m)) { 194 return recordName; 195 } 196 assert Void.TYPE.equals(m.getReturnType()); 197 for (MetricsRecord rec : subrecs) { 198 m.invoke(rec, args); 199 } 200 return null; 201 } 202 } 203 204}