/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef STATSPROCESSOR_H #define STATSPROCESSOR_H #include #include "thrift/lib/cpp/transport/TTransport.h" #include "thrift/lib/cpp/protocol/TProtocol.h" #include "thrift/lib/cpp/TProcessor.h" namespace apache { namespace thrift { namespace processor { /* * Class for keeping track of function call statistics and printing them if desired * */ class StatsProcessor : public apache::thrift::TProcessor { public: StatsProcessor(bool print, bool frequency) : print_(print), frequency_(frequency) {} virtual ~StatsProcessor() {}; virtual bool process(boost::shared_ptr piprot, boost::shared_ptr poprot, void* serverContext) { piprot_ = piprot; std::string fname; apache::thrift::protocol::TMessageType mtype; int32_t seqid; piprot_->readMessageBegin(fname, mtype, seqid); if (mtype != apache::thrift::protocol::T_CALL) { if (print_) { printf("Unknown message type\n"); } throw apache::thrift::TLibraryException("Unexpected message type"); } if (print_) { printf("%s (", fname.c_str()); } if (frequency_) { if (frequency_map_.find(fname) != frequency_map_.end()) { frequency_map_[fname]++; } else { frequency_map_[fname] = 1; } } apache::thrift::protocol::TType ftype; int16_t fid; while (true) { piprot_->readFieldBegin(fname, ftype, fid); if (ftype == apache::thrift::protocol::T_STOP) { break; } printAndPassToBuffer(ftype); if (print_) { printf(", "); } } if (print_) { printf("\b\b)\n"); } return true; } const std::map& get_frequency_map() { return frequency_map_; } protected: void printAndPassToBuffer(apache::thrift::protocol::TType ftype) { switch (ftype) { case apache::thrift::protocol::T_BOOL: { bool boolv; piprot_->readBool(boolv); if (print_) { printf("%d", boolv); } } break; case apache::thrift::protocol::T_BYTE: { int8_t bytev; piprot_->readByte(bytev); if (print_) { printf("%d", bytev); } } break; case apache::thrift::protocol::T_I16: { int16_t i16; piprot_->readI16(i16); if (print_) { printf("%d", i16); } } break; case apache::thrift::protocol::T_I32: { int32_t i32; piprot_->readI32(i32); if (print_) { printf("%d", i32); } } break; case apache::thrift::protocol::T_I64: { int64_t i64; piprot_->readI64(i64); if (print_) { printf("%ld", i64); } } break; case apache::thrift::protocol::T_DOUBLE: { double dub; piprot_->readDouble(dub); if (print_) { printf("%f", dub); } } break; case apache::thrift::protocol::T_STRING: { std::string str; piprot_->readString(str); if (print_) { printf("%s", str.c_str()); } } break; case apache::thrift::protocol::T_STRUCT: { std::string name; int16_t fid; apache::thrift::protocol::TType ftype; piprot_->readStructBegin(name); if (print_) { printf("<"); } while (true) { piprot_->readFieldBegin(name, ftype, fid); if (ftype == apache::thrift::protocol::T_STOP) { break; } printAndPassToBuffer(ftype); if (print_) { printf(","); } piprot_->readFieldEnd(); } piprot_->readStructEnd(); if (print_) { printf("\b>"); } } break; case apache::thrift::protocol::T_MAP: { apache::thrift::protocol::TType keyType; apache::thrift::protocol::TType valType; uint32_t i, size; piprot_->readMapBegin(keyType, valType, size); if (print_) { printf("{"); } for (i = 0; i < size; i++) { printAndPassToBuffer(keyType); if (print_) { printf("=>"); } printAndPassToBuffer(valType); if (print_) { printf(","); } } piprot_->readMapEnd(); if (print_) { printf("\b}"); } } break; case apache::thrift::protocol::T_SET: { apache::thrift::protocol::TType elemType; uint32_t i, size; piprot_->readSetBegin(elemType, size); if (print_) { printf("{"); } for (i = 0; i < size; i++) { printAndPassToBuffer(elemType); if (print_) { printf(","); } } piprot_->readSetEnd(); if (print_) { printf("\b}"); } } break; case apache::thrift::protocol::T_LIST: { apache::thrift::protocol::TType elemType; uint32_t i, size; piprot_->readListBegin(elemType, size); if (print_) { printf("["); } for (i = 0; i < size; i++) { printAndPassToBuffer(elemType); if (print_) { printf(","); } } piprot_->readListEnd(); if (print_) { printf("\b]"); } } break; default: break; } } boost::shared_ptr piprot_; std::map frequency_map_; bool print_; bool frequency_; }; }}} // apache::thrift::processor #endif