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