diff --git a/contrib/fb303/cpp/FacebookBase.cpp b/contrib/fb303/cpp/FacebookBase.cpp
new file mode 100644
index 0000000..8003340
--- /dev/null
+++ b/contrib/fb303/cpp/FacebookBase.cpp
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+#include "FacebookBase.h"
+
+using namespace facebook::fb303;
+using apache::thrift::concurrency::Guard;
+
+FacebookBase::FacebookBase(std::string name) :
+  name_(name) {
+  aliveSince_ = (int64_t) time(NULL);
+}
+
+inline void FacebookBase::getName(std::string& _return) {
+  _return = name_;
+}
+
+void FacebookBase::setOption(const std::string& key, const std::string& value) {
+  Guard g(optionsLock_);
+  options_[key] = value;
+}
+
+void FacebookBase::getOption(std::string& _return, const std::string& key) {
+  Guard g(optionsLock_);
+  _return = options_[key];
+}
+
+void FacebookBase::getOptions(std::map<std::string, std::string> & _return) {
+  Guard g(optionsLock_);
+  _return = options_;
+}
+
+int64_t FacebookBase::incrementCounter(const std::string& key, int64_t amount) {
+  counters_.acquireRead();
+
+  // if we didn't find the key, we need to write lock the whole map to create it
+  ReadWriteCounterMap::iterator it = counters_.find(key);
+  if (it == counters_.end()) {
+    counters_.release();
+    counters_.acquireWrite();
+
+    // we need to check again to make sure someone didn't create this key
+    // already while we released the lock
+    it = counters_.find(key);
+    if(it == counters_.end()){
+      counters_[key].value = amount;
+      counters_.release();
+      return amount;
+    }
+  }
+
+  it->second.acquireWrite();
+  int64_t count = it->second.value + amount;
+  it->second.value = count;
+  it->second.release();
+  counters_.release();
+  return count;
+}
+
+int64_t FacebookBase::setCounter(const std::string& key, int64_t value) {
+  counters_.acquireRead();
+
+  // if we didn't find the key, we need to write lock the whole map to create it
+  ReadWriteCounterMap::iterator it = counters_.find(key);
+  if (it == counters_.end()) {
+    counters_.release();
+    counters_.acquireWrite();
+    counters_[key].value = value;
+    counters_.release();
+    return value;
+  }
+
+  it->second.acquireWrite();
+  it->second.value = value;
+  it->second.release();
+  counters_.release();
+  return value;
+}
+
+void FacebookBase::getCounters(std::map<std::string, int64_t>& _return) {
+  // we need to lock the whole thing and actually build the map since we don't
+  // want our read/write structure to go over the wire
+  counters_.acquireRead();
+  for(ReadWriteCounterMap::iterator it = counters_.begin();
+      it != counters_.end(); it++)
+  {
+    _return[it->first] = it->second.value;
+  }
+  counters_.release();
+}
+
+int64_t FacebookBase::getCounter(const std::string& key) {
+  int64_t rv = 0;
+  counters_.acquireRead();
+  ReadWriteCounterMap::iterator it = counters_.find(key);
+  if (it != counters_.end()) {
+    it->second.acquireRead();
+    rv = it->second.value;
+    it->second.release();
+  }
+  counters_.release();
+  return rv;
+}
+
+inline int64_t FacebookBase::aliveSince() {
+  return aliveSince_;
+}
+
diff --git a/contrib/fb303/cpp/FacebookBase.h b/contrib/fb303/cpp/FacebookBase.h
new file mode 100644
index 0000000..fd169e6
--- /dev/null
+++ b/contrib/fb303/cpp/FacebookBase.h
@@ -0,0 +1,103 @@
+/*
+ * 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 _FACEBOOK_TB303_FACEBOOKBASE_H_
+#define _FACEBOOK_TB303_FACEBOOKBASE_H_ 1
+
+#include "FacebookService.h"
+
+#include "server/TServer.h"
+#include "concurrency/Mutex.h"
+
+#include <time.h>
+#include <string>
+#include <map>
+
+namespace facebook { namespace fb303 {
+
+using apache::thrift::concurrency::Mutex;
+using apache::thrift::concurrency::ReadWriteMutex;
+using apache::thrift::server::TServer;
+
+struct ReadWriteInt : ReadWriteMutex {int64_t value;};
+struct ReadWriteCounterMap : ReadWriteMutex,
+                             std::map<std::string, ReadWriteInt> {};
+
+/**
+ * Base Facebook service implementation in C++.
+ *
+ */
+class FacebookBase : virtual public FacebookServiceIf {
+ protected:
+  FacebookBase(std::string name);
+  virtual ~FacebookBase() {}
+
+ public:
+  void getName(std::string& _return);
+  virtual void getVersion(std::string& _return) { _return = ""; }
+
+  virtual fb_status getStatus() = 0;
+  virtual void getStatusDetails(std::string& _return) { _return = ""; }
+
+  void setOption(const std::string& key, const std::string& value);
+  void getOption(std::string& _return, const std::string& key);
+  void getOptions(std::map<std::string, std::string> & _return);
+
+  int64_t aliveSince();
+
+  virtual void reinitialize() {}
+
+  virtual void shutdown() {
+    if (server_.get() != NULL) {
+      server_->stop();
+    }
+  }
+
+  int64_t incrementCounter(const std::string& key, int64_t amount = 1);
+  int64_t setCounter(const std::string& key, int64_t value);
+
+  void getCounters(std::map<std::string, int64_t>& _return);
+  int64_t getCounter(const std::string& key);
+
+  /**
+   * Set server handle for shutdown method
+   */
+  void setServer(boost::shared_ptr<TServer> server) {
+    server_ = server;
+  }
+
+  void getCpuProfile(std::string& _return, int32_t durSecs) { _return = ""; }
+
+ private:
+
+  std::string name_;
+  int64_t aliveSince_;
+
+  std::map<std::string, std::string> options_;
+  Mutex optionsLock_;
+
+  ReadWriteCounterMap counters_;
+
+  boost::shared_ptr<TServer> server_;
+
+};
+
+}} // facebook::tb303
+
+#endif // _FACEBOOK_TB303_FACEBOOKBASE_H_
diff --git a/contrib/fb303/cpp/Makefile.am b/contrib/fb303/cpp/Makefile.am
new file mode 100644
index 0000000..e62608c
--- /dev/null
+++ b/contrib/fb303/cpp/Makefile.am
@@ -0,0 +1,84 @@
+#
+# 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.
+#
+
+@GLOBAL_HEADER_MK@
+
+@PRODUCT_MK@
+
+
+# User specified path variables set in configure.ac.
+# thrift_home
+#
+THRIFT = $(thrift_home)/bin/thrift
+
+# User defined conditionals and conditonal statements set up in configure.ac.
+if DEBUG
+   DEBUG_CPPFLAGS = -DDEBUG_TIMING
+endif
+
+# Set common flags recognized by automake.
+# DO NOT USE CPPFLAGS, CXXFLAGS, CFLAGS, LDFLAGS here! Set in configure.ac and|or override on command line.
+# USE flags AM_CXXFLAGS, AM_CFLAGS, AM_CPPFLAGS, AM_LDFLAGS, LDADD in this section.
+
+AM_CPPFLAGS = -I..
+AM_CPPFLAGS += -Igen-cpp
+AM_CPPFLAGS += -I$(thrift_home)/include/thrift 
+AM_CPPFLAGS += $(BOOST_CPPFLAGS)
+AM_CPPFLAGS += $(FB_CPPFLAGS) $(DEBUG_CPPFLAGS)
+
+# GENERATE BUILD RULES
+# Set Program/library specific flags recognized by automake.
+# Use <progname|libname>_<FLAG> to set prog / lib specific flag s
+# foo_CXXFLAGS foo_CPPFLAGS foo_LDFLAGS foo_LDADD
+
+fb303_lib = gen-cpp/FacebookService.cpp gen-cpp/fb303_constants.cpp gen-cpp/fb303_types.cpp FacebookBase.cpp ServiceTracker.cpp
+
+# Static -- multiple libraries can be defined
+if STATIC
+lib_LIBRARIES = libfb303.a
+libfb303_a_SOURCES = $(fb303_lib)
+INTERNAL_LIBS = libfb303.a
+endif
+
+# Shared -- multiple libraries can be defined
+if SHARED
+shareddir = lib
+shared_PROGRAMS = libfb303.so
+libfb303_so_SOURCES = $(fb303_lib)
+libfb303_so_CXXFLAGS = $(SHARED_CXXFLAGS)
+libfb303_so_LDFLAGS = $(SHARED_LDFLAGS)
+INTERNAL_LIBS =  libfb303.so
+endif
+
+# Set up Thrift specific activity here.
+# We assume that a <name>+types.cpp will always be built from <name>.thrift.
+$(eval $(call thrift_template,.,../if/fb303.thrift,-I $(thrift_home)/share  --gen cpp ))
+
+include_fb303dir = $(includedir)/thrift/fb303
+include_fb303_HEADERS = FacebookBase.h ServiceTracker.h gen-cpp/FacebookService.h gen-cpp/fb303_constants.h gen-cpp/fb303_types.h
+
+include_fb303ifdir = $(prefix)/share/fb303/if
+include_fb303if_HEADERS = ../if/fb303.thrift
+
+BUILT_SOURCES = thriftstyle
+
+# Add to pre-existing target clean
+clean-local: clean-common
+
+@GLOBAL_FOOTER_MK@
diff --git a/contrib/fb303/cpp/ServiceTracker.cpp b/contrib/fb303/cpp/ServiceTracker.cpp
new file mode 100644
index 0000000..c20a068
--- /dev/null
+++ b/contrib/fb303/cpp/ServiceTracker.cpp
@@ -0,0 +1,481 @@
+/*
+ * 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.
+ */
+
+#include <sys/time.h>
+
+#include "FacebookBase.h"
+#include "ServiceTracker.h"
+#include "concurrency/ThreadManager.h"
+
+using namespace std;
+using namespace facebook::fb303;
+using namespace apache::thrift::concurrency;
+
+
+uint64_t ServiceTracker::CHECKPOINT_MINIMUM_INTERVAL_SECONDS = 60;
+int ServiceTracker::LOG_LEVEL = 5;
+
+
+ServiceTracker::ServiceTracker(facebook::fb303::FacebookBase *handler,
+                               void (*logMethod)(int, const string &),
+                               bool featureCheckpoint,
+                               bool featureStatusCheck,
+                               bool featureThreadCheck,
+                               Stopwatch::Unit stopwatchUnit)
+  : handler_(handler), logMethod_(logMethod),
+    featureCheckpoint_(featureCheckpoint),
+    featureStatusCheck_(featureStatusCheck),
+    featureThreadCheck_(featureThreadCheck),
+    stopwatchUnit_(stopwatchUnit),
+    checkpointServices_(0)
+{
+  if (featureCheckpoint_) {
+    time_t now = time(NULL);
+    checkpointTime_ = now;
+  } else {
+    checkpointTime_ = 0;
+  }
+}
+
+/**
+ * Registers the beginning of a "service method": basically, any of
+ * the implementations of Thrift remote procedure calls that a
+ * FacebookBase handler is handling.  Controls concurrent
+ * services and reports statistics (via log and via fb303 counters).
+ * Throws an exception if the server is not ready to handle service
+ * methods yet.
+ *
+ * note: The relationship between startService() and finishService()
+ * is currently defined so that a call to finishService() should only
+ * be matched to this call to startService() if this method returns
+ * without exception.  It wouldn't be a problem to implement things
+ * the other way, so that *every* start needed a finish, but this
+ * convention was chosen to match the way an object's constructor and
+ * destructor work together, i.e. to work well with ServiceMethod
+ * objects.
+ *
+ * @param const ServiceMethod &serviceMethod A reference to the ServiceMethod
+ *                                           object instantiated at the start
+ *                                           of the service method.
+ */
+void
+ServiceTracker::startService(const ServiceMethod &serviceMethod)
+{
+  // note: serviceMethod.timer_ automatically starts at construction.
+
+  // log service start
+  logMethod_(5, serviceMethod.signature_);
+
+  // check handler ready
+  if (featureStatusCheck_ && !serviceMethod.featureLogOnly_) {
+    // note: Throwing exceptions before counting statistics.  See note
+    // in method header.
+    // note: A STOPPING server is not accepting new connections, but it
+    // is still handling any already-connected threads -- so from the
+    // service method's point of view, a status of STOPPING is a green
+    // light.
+    facebook::fb303::fb_status status = handler_->getStatus();
+    if (status != facebook::fb303::ALIVE
+        && status != facebook::fb303::STOPPING) {
+      if (status == facebook::fb303::STARTING) {
+        throw ServiceException("Server starting up; please try again later");
+      } else {
+        throw ServiceException("Server not alive; please try again later");
+      }
+    }
+  }
+
+  // check server threads
+  if (featureThreadCheck_ && !serviceMethod.featureLogOnly_) {
+    // note: Might want to put these messages in reportCheckpoint() if
+    // log is getting spammed.
+    if (threadManager_ != NULL) {
+      size_t idle_count = threadManager_->idleWorkerCount();
+      if (idle_count == 0) {
+        stringstream message;
+        message << "service " << serviceMethod.signature_
+                << ": all threads (" << threadManager_->workerCount()
+                << ") in use";
+        logMethod_(3, message.str());
+      }
+    }
+  }
+}
+
+/**
+ * Logs a significant step in the middle of a "service method"; see
+ * startService.
+ *
+ * @param const ServiceMethod &serviceMethod A reference to the ServiceMethod
+ *                                           object instantiated at the start
+ *                                           of the service method.
+ * @return int64_t Elapsed units (see stopwatchUnit_) since ServiceMethod
+ *                 instantiation.
+ */
+int64_t
+ServiceTracker::stepService(const ServiceMethod &serviceMethod,
+                            const string &stepName)
+{
+  stringstream message;
+  string elapsed_label;
+  int64_t elapsed = serviceMethod.timer_.elapsedUnits(stopwatchUnit_,
+                                                      &elapsed_label);
+  message << serviceMethod.signature_
+          << ' ' << stepName
+          << " [" << elapsed_label << ']';
+  logMethod_(5, message.str());
+  return elapsed;
+}
+
+/**
+ * Registers the end of a "service method"; see startService().
+ *
+ * @param const ServiceMethod &serviceMethod A reference to the ServiceMethod
+ *                                           object instantiated at the start
+ *                                           of the service method.
+ */
+void
+ServiceTracker::finishService(const ServiceMethod &serviceMethod)
+{
+  // log end of service
+  stringstream message;
+  string duration_label;
+  int64_t duration = serviceMethod.timer_.elapsedUnits(stopwatchUnit_,
+                                                       &duration_label);
+  message << serviceMethod.signature_
+          << " finish [" << duration_label << ']';
+  logMethod_(5, message.str());
+
+  // count, record, and maybe report service statistics
+  if (!serviceMethod.featureLogOnly_) {
+
+    if (!featureCheckpoint_) {
+
+      // lifetime counters
+      // (note: No need to lock statisticsMutex_ if not doing checkpoint;
+      // FacebookService::incrementCounter() is already thread-safe.)
+      handler_->incrementCounter("lifetime_services");
+
+    } else {
+
+      statisticsMutex_.lock();
+      // note: No exceptions expected from this code block.  Wrap in a try
+      // just to be safe.
+      try {
+
+        // lifetime counters
+        // note: Good to synchronize this with the increment of
+        // checkpoint services, even though incrementCounter() is
+        // already thread-safe, for the sake of checkpoint reporting
+        // consistency (i.e.  since the last checkpoint,
+        // lifetime_services has incremented by checkpointServices_).
+        handler_->incrementCounter("lifetime_services");
+
+        // checkpoint counters
+        checkpointServices_++;
+        checkpointDuration_ += duration;
+
+        // per-service timing
+        // note kjv: According to my tests it is very slightly faster to
+        // call insert() once (and detect not-found) than calling find()
+        // and then maybe insert (if not-found).  However, the difference
+        // is tiny for small maps like this one, and the code for the
+        // faster solution is slightly less readable.  Also, I wonder if
+        // the instantiation of the (often unused) pair to insert makes
+        // the first algorithm slower after all.
+        map<string, pair<uint64_t, uint64_t> >::iterator iter;
+        iter = checkpointServiceDuration_.find(serviceMethod.name_);
+        if (iter != checkpointServiceDuration_.end()) {
+          iter->second.first++;
+          iter->second.second += duration;
+        } else {
+          checkpointServiceDuration_.insert(make_pair(serviceMethod.name_,
+                                                      make_pair(1, duration)));
+        }
+
+        // maybe report checkpoint
+        // note: ...if it's been long enough since the last report.
+        time_t now = time(NULL);
+        uint64_t check_interval = now - checkpointTime_;
+        if (check_interval >= CHECKPOINT_MINIMUM_INTERVAL_SECONDS) {
+          reportCheckpoint();
+        }
+
+      } catch (...) {
+        statisticsMutex_.unlock();
+        throw;
+      }
+      statisticsMutex_.unlock();
+
+    }
+  }
+}
+
+/**
+ * Logs some statistics gathered since the last call to this method.
+ *
+ * note: Thread race conditions on this method could cause
+ * misreporting and/or undefined behavior; the caller must protect
+ * uses of the object variables (and calls to this method) with a
+ * mutex.
+ *
+ */
+void
+ServiceTracker::reportCheckpoint()
+{
+  time_t now = time(NULL);
+
+  uint64_t check_count = checkpointServices_;
+  uint64_t check_interval = now - checkpointTime_;
+  uint64_t check_duration = checkpointDuration_;
+
+  // export counters for timing of service methods (by service name)
+  handler_->setCounter("checkpoint_time", check_interval);
+  map<string, pair<uint64_t, uint64_t> >::iterator iter;
+  uint64_t count;
+  for (iter = checkpointServiceDuration_.begin();
+       iter != checkpointServiceDuration_.end();
+       iter++) {
+    count = iter->second.first;
+    handler_->setCounter(string("checkpoint_count_") + iter->first, count);
+    if (count == 0) {
+      handler_->setCounter(string("checkpoint_speed_") + iter->first,
+                           0);
+    } else {
+      handler_->setCounter(string("checkpoint_speed_") + iter->first,
+                           iter->second.second / count);
+    }
+  }
+
+  // reset checkpoint variables
+  // note: Clearing the map while other threads are using it might
+  // cause undefined behavior.
+  checkpointServiceDuration_.clear();
+  checkpointTime_ = now;
+  checkpointServices_ = 0;
+  checkpointDuration_ = 0;
+
+  // get lifetime variables
+  uint64_t life_count = handler_->getCounter("lifetime_services");
+  uint64_t life_interval = now - handler_->aliveSince();
+
+  // log checkpoint
+  stringstream message;
+  message << "checkpoint_time:" << check_interval
+          << " checkpoint_services:" << check_count
+          << " checkpoint_speed_sum:" << check_duration
+          << " lifetime_time:" << life_interval
+          << " lifetime_services:" << life_count;
+  if (featureThreadCheck_ && threadManager_ != NULL) {
+    size_t worker_count = threadManager_->workerCount();
+    size_t idle_count = threadManager_->idleWorkerCount();
+    message << " total_workers:" << worker_count
+            << " active_workers:" << (worker_count - idle_count);
+  }
+  logMethod_(4, message.str());
+}
+
+/**
+ * Remembers the thread manager used in the server, for monitoring thread
+ * activity.
+ *
+ * @param shared_ptr<ThreadManager> threadManager The server's thread manager.
+ */
+void
+ServiceTracker::setThreadManager(boost::shared_ptr<ThreadManager>
+                                 threadManager)
+{
+  threadManager_ = threadManager;
+}
+
+/**
+ * Logs messages to stdout; the passed message will be logged if the
+ * passed level is less than or equal to LOG_LEVEL.
+ *
+ * This is the default logging method used by the ServiceTracker.  An
+ * alternate logging method (that accepts the same parameters) may be
+ * specified to the constructor.
+ *
+ * @param int level A level associated with the message: higher levels
+ *                  are used to indicate higher levels of detail.
+ * @param string message The message to log.
+ */
+void
+ServiceTracker::defaultLogMethod(int level, const string &message)
+{
+  if (level <= LOG_LEVEL) {
+    string level_string;
+    time_t now = time(NULL);
+    char now_pretty[26];
+    ctime_r(&now, now_pretty);
+    now_pretty[24] = '\0';
+    switch (level) {
+    case 1:
+      level_string = "CRITICAL";
+      break;
+    case 2:
+      level_string = "ERROR";
+      break;
+    case 3:
+      level_string = "WARNING";
+      break;
+    case 5:
+      level_string = "DEBUG";
+      break;
+    case 4:
+    default:
+      level_string = "INFO";
+      break;
+    }
+    cout << '[' << level_string << "] [" << now_pretty << "] "
+         << message << endl;
+  }
+}
+
+
+/**
+ * Creates a Stopwatch, which can report the time elapsed since its
+ * creation.
+ *
+ */
+Stopwatch::Stopwatch()
+{
+  gettimeofday(&startTime_, NULL);
+}
+
+void
+Stopwatch::reset()
+{
+  gettimeofday(&startTime_, NULL);
+}
+
+uint64_t
+Stopwatch::elapsedUnits(Stopwatch::Unit unit, string *label) const
+{
+  timeval now_time;
+  gettimeofday(&now_time, NULL);
+  time_t duration_secs = now_time.tv_sec - startTime_.tv_sec;
+
+  uint64_t duration_units;
+  switch (unit) {
+  case UNIT_SECONDS:
+    duration_units = duration_secs
+      + (now_time.tv_usec - startTime_.tv_usec + 500000) / 1000000;
+    if (NULL != label) {
+      stringstream ss_label;
+      ss_label << duration_units << " secs";
+      label->assign(ss_label.str());
+    }
+    break;
+  case UNIT_MICROSECONDS:
+    duration_units = duration_secs * 1000000
+      + now_time.tv_usec - startTime_.tv_usec;
+    if (NULL != label) {
+      stringstream ss_label;
+      ss_label << duration_units << " us";
+      label->assign(ss_label.str());
+    }
+    break;
+  case UNIT_MILLISECONDS:
+  default:
+    duration_units = duration_secs * 1000
+      + (now_time.tv_usec - startTime_.tv_usec + 500) / 1000;
+    if (NULL != label) {
+      stringstream ss_label;
+      ss_label << duration_units << " ms";
+      label->assign(ss_label.str());
+    }
+    break;
+  }
+  return duration_units;
+}
+
+/**
+ * Creates a ServiceMethod, used for tracking a single service method
+ * invocation (via the ServiceTracker).  The passed name of the
+ * ServiceMethod is used to group statistics (e.g. counts and durations)
+ * for similar invocations; the passed signature is used to uniquely
+ * identify the particular invocation in the log.
+ *
+ * note: A version of this constructor is provided that automatically
+ * forms a signature the name and a passed numeric id.  Silly, sure,
+ * but commonly used, since it often saves the caller a line or two of
+ * code.
+ *
+ * @param ServiceTracker *tracker The service tracker that will track this
+ *                                ServiceMethod.
+ * @param const string &name The service method name (usually independent
+ *                           of service method parameters).
+ * @param const string &signature A signature uniquely identifying the method
+ *                                invocation (usually name plus parameters).
+ */
+ServiceMethod::ServiceMethod(ServiceTracker *tracker,
+                             const string &name,
+                             const string &signature,
+                             bool featureLogOnly)
+  : tracker_(tracker), name_(name), signature_(signature),
+    featureLogOnly_(featureLogOnly)
+{
+  // note: timer_ automatically starts at construction.
+
+  // invoke tracker to start service
+  // note: Might throw.  If it throws, then this object's destructor
+  // won't be called, which is according to plan: finishService() is
+  // only supposed to be matched to startService() if startService()
+  // returns without error.
+  tracker_->startService(*this);
+}
+
+ServiceMethod::ServiceMethod(ServiceTracker *tracker,
+                             const string &name,
+                             uint64_t id,
+                             bool featureLogOnly)
+  : tracker_(tracker), name_(name), featureLogOnly_(featureLogOnly)
+{
+  // note: timer_ automatically starts at construction.
+  stringstream ss_signature;
+  ss_signature << name << " (" << id << ')';
+  signature_ = ss_signature.str();
+
+  // invoke tracker to start service
+  // note: Might throw.  If it throws, then this object's destructor
+  // won't be called, which is according to plan: finishService() is
+  // only supposed to be matched to startService() if startService()
+  // returns without error.
+  tracker_->startService(*this);
+}
+
+ServiceMethod::~ServiceMethod()
+{
+  // invoke tracker to finish service
+  // note: Not expecting an exception from this code, but
+  // finishService() might conceivably throw an out-of-memory
+  // exception.
+  try {
+    tracker_->finishService(*this);
+  } catch (...) {
+    // don't throw
+  }
+}
+
+uint64_t
+ServiceMethod::step(const std::string &stepName)
+{
+  return tracker_->stepService(*this, stepName);
+}
diff --git a/contrib/fb303/cpp/ServiceTracker.h b/contrib/fb303/cpp/ServiceTracker.h
new file mode 100644
index 0000000..9304386
--- /dev/null
+++ b/contrib/fb303/cpp/ServiceTracker.h
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+
+/**
+ * ServiceTracker is a utility class for logging and timing service
+ * calls to a fb303 Thrift server.  Currently, ServiceTracker offers
+ * the following features:
+ *
+ *   . Logging of service method start, end (and duration), and
+ *     optional steps in between.
+ *
+ *   . Automatic check of server status via fb303::getStatus()
+ *     with a ServiceException thrown if server not alive
+ *     (at method start).
+ *
+ *   . A periodic logged checkpoint reporting lifetime time, lifetime
+ *     service count, and per-method statistics since the last checkpoint
+ *     time (at method finish).
+ *
+ *   . Export of fb303 counters for lifetime and checkpoint statistics
+ *     (at method finish).
+ *
+ *   . For TThreadPoolServers, a logged warning when all server threads
+ *     are busy (at method start).  (Must call setThreadManager() after
+ *     ServiceTracker instantiation for this feature to be enabled.)
+ *
+ * Individual features may be enabled or disabled by arguments to the
+ * constructor.  The constructor also accepts a pointer to a logging
+ * method -- if no pointer is passed, the tracker will log to stdout.
+ *
+ * ServiceTracker defines private methods for service start, finish,
+ * and step, which are designed to be accessed by instantiating a
+ * friend ServiceMethod object, as in the following example:
+ *
+ *    #include <ServiceTracker.h>
+ *    class MyServiceHandler : virtual public MyServiceIf,
+ *                             public facebook::fb303::FacebookBase
+ *    {
+ *    public:
+ *      MyServiceHandler::MyServiceHandler() : mServiceTracker(this) {}
+ *      void MyServiceHandler::myServiceMethod(int userId) {
+ *        // note: Instantiating a ServiceMethod object starts a timer
+ *        // and tells the ServiceTracker to log the start.  Might throw
+ *        // a ServiceException.
+ *        ServiceMethod serviceMethod(&mServiceTracker,
+ *                                   "myServiceMethod",
+ *                                   userId);
+ *        ...
+ *        // note: Calling the step method tells the ServiceTracker to
+ *        // log the step, with a time elapsed since start.
+ *        serviceMethod.step("post parsing, begin processing");
+ *        ...
+ *        // note: When the ServiceMethod object goes out of scope, the
+ *        // ServiceTracker will log the total elapsed time of the method.
+ *      }
+ *      ...
+ *    private:
+ *      ServiceTracker mServiceTracker;
+ *    }
+ *
+ * The step() method call is optional; the startService() and
+ * finishService() methods are handled by the object's constructor and
+ * destructor.
+ *
+ * The ServiceTracker is (intended to be) thread-safe.
+ *
+ * Future:
+ *
+ *   . Come up with something better for logging than passing a
+ *     function pointer to the constructor.
+ *
+ *   . Add methods for tracking errors from service methods, e.g.
+ *     ServiceTracker::reportService().
+ */
+
+#ifndef SERVICETRACKER_H
+#define SERVICETRACKER_H
+
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <exception>
+#include <map>
+#include <boost/shared_ptr.hpp>
+
+#include "concurrency/Mutex.h"
+
+
+namespace apache { namespace thrift { namespace concurrency {
+  class ThreadManager;
+}}}
+
+
+namespace facebook { namespace fb303 {
+
+
+class FacebookBase;
+class ServiceMethod;
+
+
+class Stopwatch
+{
+public:
+  enum Unit { UNIT_SECONDS, UNIT_MILLISECONDS, UNIT_MICROSECONDS };
+  Stopwatch();
+  uint64_t elapsedUnits(Unit unit, std::string *label = NULL) const;
+  void reset();
+private:
+  timeval startTime_;
+};
+
+
+class ServiceTracker
+{
+  friend class ServiceMethod;
+
+public:
+
+  static uint64_t CHECKPOINT_MINIMUM_INTERVAL_SECONDS;
+  static int LOG_LEVEL;
+
+  ServiceTracker(facebook::fb303::FacebookBase *handler,
+                 void (*logMethod)(int, const std::string &)
+                 = &ServiceTracker::defaultLogMethod,
+                 bool featureCheckpoint = true,
+                 bool featureStatusCheck = true,
+                 bool featureThreadCheck = true,
+                 Stopwatch::Unit stopwatchUnit
+                 = Stopwatch::UNIT_MILLISECONDS);
+
+  void setThreadManager(boost::shared_ptr<apache::thrift::concurrency::ThreadManager> threadManager);
+
+private:
+
+  facebook::fb303::FacebookBase *handler_;
+  void (*logMethod_)(int, const std::string &);
+  boost::shared_ptr<apache::thrift::concurrency::ThreadManager> threadManager_;
+
+  bool featureCheckpoint_;
+  bool featureStatusCheck_;
+  bool featureThreadCheck_;
+  Stopwatch::Unit stopwatchUnit_;
+
+  apache::thrift::concurrency::Mutex statisticsMutex_;
+  time_t checkpointTime_;
+  uint64_t checkpointServices_;
+  uint64_t checkpointDuration_;
+  std::map<std::string, std::pair<uint64_t, uint64_t> > checkpointServiceDuration_;
+
+  void startService(const ServiceMethod &serviceMethod);
+  int64_t stepService(const ServiceMethod &serviceMethod,
+                      const std::string &stepName);
+  void finishService(const ServiceMethod &serviceMethod);
+  void reportCheckpoint();
+  static void defaultLogMethod(int level, const std::string &message);
+};
+
+
+class ServiceMethod
+{
+  friend class ServiceTracker;
+public:
+  ServiceMethod(ServiceTracker *tracker,
+                const std::string &name,
+                const std::string &signature,
+                bool featureLogOnly = false);
+  ServiceMethod(ServiceTracker *tracker,
+                const std::string &name,
+                uint64_t id,
+                bool featureLogOnly = false);
+  ~ServiceMethod();
+  uint64_t step(const std::string &stepName);
+private:
+  ServiceTracker *tracker_;
+  std::string name_;
+  std::string signature_;
+  bool featureLogOnly_;
+  Stopwatch timer_;
+};
+
+
+class ServiceException : public std::exception
+{
+public:
+  explicit ServiceException(const std::string &message, int code = 0)
+    : message_(message), code_(code) {}
+  ~ServiceException() throw() {}
+  virtual const char *what() const throw() { return message_.c_str(); }
+  int code() const throw() { return code_; }
+private:
+  std::string message_;
+  int code_;
+};
+
+
+}} // facebook::fb303
+
+#endif
