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.hbase.thrift; 019 020import org.apache.hadoop.conf.Configuration; 021import org.apache.hadoop.hbase.CallDroppedException; 022import org.apache.hadoop.hbase.CallQueueTooBigException; 023import org.apache.hadoop.hbase.CompatibilitySingletonFactory; 024import org.apache.hadoop.hbase.MultiActionResultTooLarge; 025import org.apache.hadoop.hbase.NotServingRegionException; 026import org.apache.hadoop.hbase.RegionTooBusyException; 027import org.apache.hadoop.hbase.UnknownScannerException; 028import org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil; 029import org.apache.hadoop.hbase.exceptions.FailedSanityCheckException; 030import org.apache.hadoop.hbase.exceptions.OutOfOrderScannerNextException; 031import org.apache.hadoop.hbase.exceptions.RegionMovedException; 032import org.apache.hadoop.hbase.exceptions.RequestTooBigException; 033import org.apache.hadoop.hbase.exceptions.ScannerResetException; 034import org.apache.hadoop.hbase.quotas.QuotaExceededException; 035import org.apache.hadoop.hbase.quotas.RpcThrottlingException; 036import org.apache.hadoop.hbase.thrift.generated.IOError; 037import org.apache.hadoop.hbase.thrift2.generated.TIOError; 038import org.apache.yetus.audience.InterfaceAudience; 039import org.slf4j.Logger; 040import org.slf4j.LoggerFactory; 041 042/** 043 * This class is for maintaining the various statistics of thrift server and publishing them through 044 * the metrics interfaces. 045 */ 046@InterfaceAudience.Private 047public class ThriftMetrics { 048 049 private static final Logger LOG = LoggerFactory.getLogger(ThriftMetrics.class); 050 051 public enum ThriftServerType { 052 ONE, 053 TWO 054 } 055 056 public MetricsThriftServerSource getSource() { 057 return source; 058 } 059 060 public void setSource(MetricsThriftServerSource source) { 061 this.source = source; 062 } 063 064 protected MetricsThriftServerSource source; 065 protected final long slowResponseTime; 066 public static final String SLOW_RESPONSE_NANO_SEC = "hbase.thrift.slow.response.nano.second"; 067 public static final long DEFAULT_SLOW_RESPONSE_NANO_SEC = 10 * 1000 * 1000; 068 private final ThriftServerType thriftServerType; 069 070 public ThriftMetrics(Configuration conf, ThriftServerType t) { 071 slowResponseTime = conf.getLong(SLOW_RESPONSE_NANO_SEC, DEFAULT_SLOW_RESPONSE_NANO_SEC); 072 thriftServerType = t; 073 if (t == ThriftServerType.ONE) { 074 source = CompatibilitySingletonFactory.getInstance(MetricsThriftServerSourceFactory.class) 075 .createThriftOneSource(); 076 } else if (t == ThriftServerType.TWO) { 077 source = CompatibilitySingletonFactory.getInstance(MetricsThriftServerSourceFactory.class) 078 .createThriftTwoSource(); 079 } 080 081 } 082 083 public void incTimeInQueue(long time) { 084 source.incTimeInQueue(time); 085 } 086 087 public void setCallQueueLen(int len) { 088 source.setCallQueueLen(len); 089 } 090 091 public void incNumRowKeysInBatchGet(int diff) { 092 source.incNumRowKeysInBatchGet(diff); 093 } 094 095 public void incNumRowKeysInBatchMutate(int diff) { 096 source.incNumRowKeysInBatchMutate(diff); 097 } 098 099 public void incMethodTime(String name, long time) { 100 source.incMethodTime(name, time); 101 // inc general processTime 102 source.incCall(time); 103 if (time > slowResponseTime) { 104 source.incSlowCall(time); 105 } 106 } 107 108 public void incActiveWorkerCount() { 109 source.incActiveWorkerCount(); 110 } 111 112 public void decActiveWorkerCount() { 113 source.decActiveWorkerCount(); 114 } 115 116 /** 117 * Increment the count for a specific exception type. This is called for each exception type that 118 * is returned to the thrift handler. 119 * @param rawThrowable type of exception 120 */ 121 public void exception(Throwable rawThrowable) { 122 source.exception(); 123 124 Throwable throwable = unwrap(rawThrowable); 125 /** 126 * Keep some metrics for commonly seen exceptions Try and put the most common types first. Place 127 * child types before the parent type that they extend. If this gets much larger we might have 128 * to go to a hashmap 129 */ 130 if (throwable != null) { 131 if (throwable instanceof OutOfOrderScannerNextException) { 132 source.outOfOrderException(); 133 } else if (throwable instanceof RegionTooBusyException) { 134 source.tooBusyException(); 135 } else if (throwable instanceof UnknownScannerException) { 136 source.unknownScannerException(); 137 } else if (throwable instanceof ScannerResetException) { 138 source.scannerResetException(); 139 } else if (throwable instanceof RegionMovedException) { 140 source.movedRegionException(); 141 } else if (throwable instanceof NotServingRegionException) { 142 source.notServingRegionException(); 143 } else if (throwable instanceof FailedSanityCheckException) { 144 source.failedSanityException(); 145 } else if (throwable instanceof MultiActionResultTooLarge) { 146 source.multiActionTooLargeException(); 147 } else if (throwable instanceof CallQueueTooBigException) { 148 source.callQueueTooBigException(); 149 } else if (throwable instanceof QuotaExceededException) { 150 source.quotaExceededException(); 151 } else if (throwable instanceof RpcThrottlingException) { 152 source.rpcThrottlingException(); 153 } else if (throwable instanceof CallDroppedException) { 154 source.callDroppedException(); 155 } else if (throwable instanceof RequestTooBigException) { 156 source.requestTooBigException(); 157 } else { 158 source.otherExceptions(); 159 if (LOG.isDebugEnabled()) { 160 LOG.debug("Unknown exception type", throwable); 161 } 162 } 163 } 164 } 165 166 protected static Throwable unwrap(Throwable t) { 167 if (t == null) { 168 return t; 169 } 170 if (t instanceof TIOError || t instanceof IOError) { 171 t = t.getCause(); 172 } 173 return ClientExceptionsUtil.findException(t); 174 } 175 176 public ThriftServerType getThriftServerType() { 177 return thriftServerType; 178 } 179}