summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/thrift/contrib/fb303
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/jaegertracing/thrift/contrib/fb303
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/jaegertracing/thrift/contrib/fb303')
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/LICENSE16
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/Makefile.am46
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/README.md37
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/TClientInfo.cpp178
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/TClientInfo.h320
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/acinclude.m4258
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/aclocal/ax_boost_base.m4198
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/aclocal/ax_cxx_compile_stdcxx_11.m4134
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/aclocal/ax_javac_and_java.m4121
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/aclocal/ax_thrift_internal.m428
-rwxr-xr-xsrc/jaegertracing/thrift/contrib/fb303/bootstrap.sh26
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/configure.ac164
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/cpp/FacebookBase.cpp124
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/cpp/FacebookBase.h104
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/cpp/Makefile.am84
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/cpp/ServiceTracker.cpp481
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/cpp/ServiceTracker.h215
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/global_footer.mk21
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/global_header.mk38
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/if/fb303.thrift113
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/java/build.properties5
-rwxr-xr-xsrc/jaegertracing/thrift/contrib/fb303/java/build.xml199
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/java/src/FacebookBase.java114
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/php/FacebookBase.php89
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/py/Makefile.am44
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/py/fb303/FacebookBase.py83
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/py/fb303_scripts/__init__.py20
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py191
-rw-r--r--src/jaegertracing/thrift/contrib/fb303/py/setup.py48
29 files changed, 3499 insertions, 0 deletions
diff --git a/src/jaegertracing/thrift/contrib/fb303/LICENSE b/src/jaegertracing/thrift/contrib/fb303/LICENSE
new file mode 100644
index 000000000..4eacb6431
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/LICENSE
@@ -0,0 +1,16 @@
+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.
diff --git a/src/jaegertracing/thrift/contrib/fb303/Makefile.am b/src/jaegertracing/thrift/contrib/fb303/Makefile.am
new file mode 100644
index 000000000..e773e522c
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/Makefile.am
@@ -0,0 +1,46 @@
+#
+# 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@
+
+SUBDIRS = .
+
+if WITH_CPP
+SUBDIRS += cpp
+endif
+
+if WITH_JAVA
+SUBDIRS += java
+endif
+
+if WITH_PHP
+SUBDIRS += php
+endif
+
+if WITH_PYTHON
+SUBDIRS += py
+endif
+
+BUILT_SOURCES =
+
+clean-local: clean-common
+
+@GLOBAL_FOOTER_MK@
diff --git a/src/jaegertracing/thrift/contrib/fb303/README.md b/src/jaegertracing/thrift/contrib/fb303/README.md
new file mode 100644
index 000000000..8ade560c9
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/README.md
@@ -0,0 +1,37 @@
+Project FB303: The Facebook Bassline
+------------------------------------
+
+* Curious about the 303? *
+http://en.wikipedia.org/wiki/Roland_TB-303
+
+* Why the name? *
+The TB303 makes bass lines.
+.Bass is what lies underneath any strong tune.
+..fb303 is the shared root of all thrift services.
+...fb303 => FacebookBase303.
+
+* How do I use this? *
+Take a look at the examples to see how your backend project can
+and should inherit from this service.
+
+* What does it provide? *
+A standard interface to monitoring, dynamic options and configuration,
+uptime reports, activity, etc.
+
+* I want more. *
+Think carefully first about whether the functionality you are going to add
+belongs here or in your application. If it can be abstracted and is generally
+useful, then it probably belongs somewhere in the fb303 tree. Keep in mind,
+not every product has to use ALL the functionality of fb303, but every product
+CANNOT use functionality that is NOT in fb303.
+
+* Is this open source? *
+Yes. fb303 is distributed under the Thrift Software License. See the
+LICENSE file for more details.
+
+* Installation *
+fb303 is configured/built/installed similar to Thrift. See the README
+in the Thrift root directory for more information.
+
+* Who wrote this README? *
+mcslee@facebook.com
diff --git a/src/jaegertracing/thrift/contrib/fb303/TClientInfo.cpp b/src/jaegertracing/thrift/contrib/fb303/TClientInfo.cpp
new file mode 100644
index 000000000..1fc661251
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/TClientInfo.cpp
@@ -0,0 +1,178 @@
+/*
+ * 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 <thrift/server/TClientInfo.h>
+
+namespace apache { namespace thrift { namespace server {
+
+using namespace apache::thrift;
+using namespace apache::thrift::transport;
+
+TClientInfoConnection::TClientInfoConnection() {
+ call_[kNameLen - 1] = '\0'; // insure NUL terminator is there
+ eraseAddr();
+ eraseCall();
+}
+
+void TClientInfoConnection::recordAddr(const sockaddr* addr) {
+ eraseAddr();
+ initTime();
+ ncalls_ = 0;
+ if (addr != NULL) {
+ if (addr->sa_family == AF_INET) {
+ memcpy((void*)&addr_.ipv4, (const void *)addr, sizeof(sockaddr_in));
+ }
+ else if (addr->sa_family == AF_INET6) {
+ memcpy((void*)&addr_.ipv6, (const void *)addr, sizeof(sockaddr_in6));
+ }
+ }
+}
+
+void TClientInfoConnection::eraseAddr() {
+ addr_.ipv4.sin_family = AF_UNSPEC;
+}
+
+const char* TClientInfoConnection::getAddr(char* buf, int len) const {
+ switch (addr_.ipv4.sin_family) {
+ case AF_INET:
+ return inet_ntop(AF_INET, &addr_.ipv4.sin_addr, buf, len);
+ case AF_INET6:
+ return inet_ntop(AF_INET6, &addr_.ipv6.sin6_addr, buf, len);
+ default:
+ return NULL;
+ }
+}
+
+void TClientInfoConnection::recordCall(const char* name) {
+ strncpy(call_, name, kNameLen - 1); // NUL terminator set in constructor
+ ncalls_++;
+}
+
+void TClientInfoConnection::eraseCall() {
+ call_[0] = '\0';
+}
+
+const char* TClientInfoConnection::getCall() const {
+ if (call_[0] == '\0') {
+ return NULL;
+ }
+ return call_;
+}
+
+void TClientInfoConnection::getTime(timespec* time) const {
+ *time = time_;
+}
+
+uint64_t TClientInfoConnection::getNCalls() const {
+ return ncalls_;
+}
+
+void TClientInfoConnection::initTime() {
+ clock_gettime(CLOCK_REALTIME, &time_);
+}
+
+
+TClientInfoConnection* TClientInfo::getConnection(int fd, bool grow) {
+ if (fd < 0 || (!grow && fd >= info_.size())) {
+ return NULL;
+ }
+ return &info_[fd];
+}
+
+size_t TClientInfo::size() const {
+ return info_.size();
+}
+
+void* TClientInfoServerHandler::createContext(boost::shared_ptr<TProtocol> input,
+ boost::shared_ptr<TProtocol> output) {
+ (void)input;
+ (void)output;
+ return (void*) new Connect(&clientInfo_);
+}
+
+void TClientInfoServerHandler::deleteContext(void* connectionContext,
+ boost::shared_ptr<TProtocol> input,
+ boost::shared_ptr<TProtocol> output) {
+ Connect* call = static_cast<Connect*>(connectionContext);
+ if (call->callInfo_) {
+ call->callInfo_->eraseCall();
+ }
+ delete call;
+}
+
+void TClientInfoServerHandler::processContext(void* connectionContext,
+ shared_ptr<TTransport> transport) {
+ Connect* call = static_cast<Connect*>(connectionContext);
+ if (call->callInfo_ == NULL) {
+ if (typeid(*(transport.get())) == typeid(TSocket)) {
+ TSocket* tsocket = static_cast<TSocket*>(transport.get());
+ int fd = tsocket->getSocketFD();
+ if (fd < 0) {
+ return;
+ }
+ call->callInfo_ = call->clientInfo_->getConnection(fd, true);
+ assert(call->callInfo_ != NULL);
+ socklen_t len;
+ call->callInfo_->recordAddr(tsocket->getCachedAddress(&len));
+ }
+ }
+}
+
+void TClientInfoServerHandler::getStatsStrings(vector<string>& result) {
+ result.clear();
+ timespec now;
+ clock_gettime(CLOCK_REALTIME, &now);
+
+ for (int i = 0; i < clientInfo_.size(); ++i) {
+ TClientInfoConnection* info = clientInfo_.getConnection(i, false);
+ const char* callStr = info->getCall();
+ if (callStr == NULL) {
+ continue;
+ }
+
+ char addrBuf[INET6_ADDRSTRLEN];
+ const char* addrStr = info->getAddr(addrBuf, sizeof addrBuf);
+ if (addrStr == NULL) {
+ // cerr << "no addr!" << endl;
+ continue;
+ }
+
+ timespec start;
+ info->getTime(&start);
+ double secs = (double)(now.tv_sec - start.tv_sec) + (now.tv_nsec - start.tv_nsec)*0.000000001;
+
+ char buf[256];
+ snprintf(buf, sizeof buf, "%d %s %s %.3f %llu", i, addrStr, callStr, secs,
+ (uint64_t)info->getNCalls());
+
+ result.push_back(buf);
+ }
+}
+
+void* TClientInfoCallHandler::getContext(const char* fn_name, void* serverContext) {
+ if (serverContext) {
+ TClientInfoConnection* callInfo = static_cast<TClientInfoServerHandler::Connect*>(serverContext)->callInfo_;
+ if (callInfo != NULL) {
+ callInfo->recordCall(fn_name);
+ }
+ }
+ return NULL;
+}
+
+} } } // namespace apache::thrift::server
diff --git a/src/jaegertracing/thrift/contrib/fb303/TClientInfo.h b/src/jaegertracing/thrift/contrib/fb303/TClientInfo.h
new file mode 100644
index 000000000..6668c1921
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/TClientInfo.h
@@ -0,0 +1,320 @@
+/*
+ * 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_THRIFT_SERVER_TCLIENTINFO_H_
+#define _FACEBOOK_THRIFT_SERVER_TCLIENTINFO_H_ 1
+
+// for inet_ntop --
+#include <arpa/inet.h>
+#include <thrift/server/TServer.h>
+#include <thrift/transport/TSocket.h>
+#include <thrift/concurrency/Mutex.h>
+
+namespace apache { namespace thrift { namespace server {
+
+using namespace apache::thrift;
+using namespace apache::thrift::transport;
+using namespace apache::thrift::concurrency;
+using boost::shared_ptr;
+using std::string;
+using std::vector;
+
+/**
+ * StableVector -- a minimal vector class where growth is automatic and
+ * vector elements never move as the vector grows. Allocates new space
+ * as needed, but does not copy old values.
+ *
+ * A level vector stores a list of storage vectors containing the actual
+ * elements. Levels are added as needed, doubling in size each time.
+ * Locking is only done when a level is added. Access is amortized
+ * constant time.
+ */
+template <typename T>
+class StableVector {
+ /// The initial allocation as an exponent of 2
+ static const uint32_t kInitialSizePowOf2 = 10;
+ /// The initial allocation size
+ static const uint32_t kInitialVectorSize = 1 << kInitialSizePowOf2;
+ /// This bound is guaranteed not to be exceeded on 64-bit archs
+ static const int kMaxLevels = 64;
+
+ /// Values are kept in one or more of these
+ typedef vector<T> Vect;
+ /// One or more value vectors are kept in one of these
+ typedef vector<Vect*> LevelVector;
+
+ Mutex mutex_;
+ /// current size
+ size_t size_;
+ _Atomic_word vectLvl_;
+ LevelVector vects_;
+
+ public:
+ /**
+ * Constructor -- initialize the level vector and allocate the
+ * initial storage vector
+ */
+ StableVector()
+ : size_(0)
+ , vectLvl_(0) {
+ vects_.reserve(kMaxLevels);
+ Vect* storageVector(new Vect(1 << kInitialSizePowOf2));
+ vects_.push_back(storageVector);
+ }
+
+ private:
+ /**
+ * make sure the requested number of storage levels have been allocated.
+ */
+ void expand(uint32_t level) {
+ // we need the guard to insure that we only allocate once.
+ Guard g(mutex_);
+ while (level > vectLvl_) {
+ Vect* levelVect(new Vect(1 << (vectLvl_ + kInitialSizePowOf2)));
+ vects_.push_back(levelVect);
+ // we need to make sure this is done after levelVect is inserted
+ // (what we want is effectively a memory barrier here).
+ __gnu_cxx::__atomic_add(&vectLvl_, 1);
+ }
+ }
+
+ /**
+ * Given an index, determine which level and element of that level is
+ * required. Grows if needed.
+ */
+ void which(uint32_t n, uint32_t* vno, uint32_t* idx) {
+ if (n >= size_) {
+ size_ = n + 1;
+ }
+ if (n < kInitialVectorSize) {
+ *idx = n;
+ *vno = 0;
+ } else {
+ uint32_t upper = n >> kInitialSizePowOf2;
+ *vno = CHAR_BIT*sizeof(upper) - __builtin_clz(upper);
+ *idx = n - (1 << (*vno + kInitialSizePowOf2 - 1));
+ if (*vno > vectLvl_) {
+ expand(*vno);
+ }
+ }
+ }
+
+ public:
+ /**
+ * Given an index, return a reference to that element, perhaps after
+ * allocating additional space.
+ *
+ * @param n a positive integer
+ */
+ T& operator[](uint32_t n) {
+ uint32_t vno;
+ uint32_t idx;
+ which(n, &vno, &idx);
+ return (*vects_[vno])[idx];
+ }
+
+ /**
+ * Return the present size of the vector.
+ */
+ size_t size() const { return size_; }
+};
+
+
+/**
+ * This class embodies the representation of a single connection during
+ * processing. We'll keep one of these per file descriptor in TClientInfo.
+ */
+class TClientInfoConnection {
+ public:
+ const static int kNameLen = 32;
+
+ private:
+ typedef union IPAddrUnion {
+ sockaddr_in ipv4;
+ sockaddr_in6 ipv6;
+ };
+
+ char call_[kNameLen]; ///< The name of the thrift call
+ IPAddrUnion addr_; ///< The client's IP address
+ timespec time_; ///< Time processing started
+ uint64_t ncalls_; ///< # of calls processed
+
+ public:
+ /**
+ * Constructor; insure that no client address or thrift call name is
+ * represented.
+ */
+ TClientInfoConnection();
+
+ /**
+ * A connection has been made; record its address. Since this is the
+ * first we'll know of a connection we start the timer here as well.
+ */
+ void recordAddr(const sockaddr* addr);
+
+ /**
+ * Mark the address as empty/unknown.
+ */
+ void eraseAddr();
+
+ /**
+ * Return a string representing the present address, or NULL if none.
+ * Copies the string into the buffer provided.
+ */
+ const char* getAddr(char* buf, int len) const;
+
+ /**
+ * A call has been made on this connection; record its name. Since this is
+ * called for every thrift call processed, we also do our call count here.
+ */
+ void recordCall(const char* name);
+
+ /**
+ * Invoked when processing has ended to clear the call name.
+ */
+ void eraseCall();
+
+ /**
+ * Return as string the thrift call either currently being processed or
+ * most recently processed if the connection is still open for additional
+ * calls. Returns NULL if a call hasn't been made yet or processing
+ * has ended.
+ */
+ const char* getCall() const;
+
+ /**
+ * Get the timespec for the start of this connection (specifically, when
+ * recordAddr() was first called).
+ */
+ void getTime(timespec* time) const;
+
+ /**
+ * Return the number of calls made on this connection.
+ */
+ uint64_t getNCalls() const;
+
+ private:
+ void initTime();
+};
+
+
+/**
+ * Store for info about a server's clients -- specifically, the client's IP
+ * address and the call it is executing. This information is indexed by
+ * socket file descriptor and in the present implementation is updated
+ * asynchronously, so it may only approximate reality.
+ */
+class TClientInfo {
+ private:
+ StableVector<TClientInfoConnection> info_;
+
+ public:
+ /**
+ * Return the info object for a given file descriptor. If "grow" is true
+ * extend the info vector if required (such as for a file descriptor not seen
+ * before). If "grow" is false and the info vector isn't large enough,
+ * or if "fd" is negative, return NULL.
+ */
+ TClientInfoConnection* getConnection(int fd, bool grow);
+
+ size_t size() const;
+};
+
+/**
+ * This derivation of TServerEventHandler encapsulates the main status vector
+ * and provides context to the server's processing loop via overrides.
+ * Together with TClientInfoCallHandler (derived from TProcessorEventHandler)
+ * it integrates client info collection into the server.
+ */
+class TClientInfoServerHandler : public TServerEventHandler {
+ private:
+ TClientInfo clientInfo_;
+
+ public:
+ /**
+ * One of these is constructed for each open connection/descriptor and links
+ * to both the status vector (clientInfo_) and that descriptor's entry
+ * within it.
+ */
+ struct Connect {
+ TClientInfo* clientInfo_;
+ TClientInfoConnection* callInfo_;
+
+ explicit Connect(TClientInfo* clientInfo)
+ : clientInfo_(clientInfo)
+ , callInfo_(NULL) {
+ }
+ };
+
+ /**
+ * Generate processor context; we don't know what descriptor we belong to
+ * yet -- we'll get hooked up in contextProcess().
+ */
+ void* createContext(boost::shared_ptr<TProtocol> input,
+ boost::shared_ptr<TProtocol> output);
+
+ /**
+ * Mark our slot as unused and delete the context created in createContext().
+ */
+ void deleteContext(void* processorContext,
+ boost::shared_ptr<TProtocol> input,
+ boost::shared_ptr<TProtocol> output);
+
+ /**
+ * Called in the processing loop just before the server invokes the
+ * processor itself, on the first call we establish which descriptor
+ * we correspond to and set it to that socket's peer IP address. This
+ * also has the side effect of initializing call counting and connection
+ * timing. We won't know which call we're handling until the handler
+ * first gets called in TClientInfoCallHandler::getContext().
+ */
+ void processContext(void* processorContext,
+ shared_ptr<TTransport> transport);
+
+ /**
+ * Get status report for server in the form of a vector of strings.
+ * Each active client appears as one string in the format:
+ *
+ * FD IPADDR CALLNAME DURATION NCALLS
+ *
+ * where "FD" is the file descriptor for the client's socket, "IPADDR"
+ * is the IP address (as reported by accept()), "CALLNAME" is the
+ * current or most recent Thrift function name, "DURATION" is the
+ * duration of the connection, while NCALLS is the number of Thrift
+ * calls made since the connection was made. A single space separates
+ * fields.
+ */
+ void getStatsStrings(vector<string>& result);
+};
+
+/**
+ * This class derives from TProcessorEventHandler to gain access to the
+ * function name for the current Thrift call. We need two versions of
+ * this -- TClientInfoCallStatsHandler is the other -- since in the latter
+ * case we pass through to TFunctionStatHandler to perform Thrift call
+ * stats.
+ */
+class TClientInfoCallHandler : public TProcessorEventHandler {
+ public:
+ virtual void* getContext(const char* fn_name, void* serverContext);
+};
+
+} } } // namespace apache::thrift::server
+
+#endif // !_FACEBOOK_THRIFT_SERVER_TCLIENTINFO_H_
diff --git a/src/jaegertracing/thrift/contrib/fb303/acinclude.m4 b/src/jaegertracing/thrift/contrib/fb303/acinclude.m4
new file mode 100644
index 000000000..faafba6b3
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/acinclude.m4
@@ -0,0 +1,258 @@
+dnl Copyright (C) 2009 Facebook
+dnl Copying and distribution of this file, with or without modification,
+dnl are permitted in any medium without royalty provided the copyright
+dnl notice and this notice are preserved.
+
+AC_DEFUN([FB_INITIALIZE],
+[
+AM_INIT_AUTOMAKE([ foreign 1.9.5 no-define ])
+if test "x$1" = "xlocalinstall"; then
+wdir=`pwd`
+# To use $wdir undef quote.
+#
+##########
+AC_PREFIX_DEFAULT([`pwd`/install])
+echo
+fi
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_RANLIB(RANLIB, ranlib)
+AC_PATH_PROGS(BASH, bash)
+AC_PATH_PROGS(PERL, perl)
+AC_PATH_PROGS(PYTHON, python)
+AC_PATH_PROGS(AR, ar)
+AC_PATH_PROGS(ANT, ant)
+PRODUCT_MK=""
+])
+
+AC_DEFUN([FB_WITH_EXTERNAL_PATH],
+[
+cdir=`pwd`
+AC_MSG_CHECKING([Checking EXTERNAL_PATH set to])
+AC_ARG_WITH([externalpath],
+ [ --with-externalpath=DIR User specified path to external facebook components.],
+ [
+ if test "x${EXTERNAL_PATH}" != "x"; then
+ echo ""
+ echo "ERROR: You have already set EXTERNAL_PATH in your environment"
+ echo "Cannot override it using --with-externalpath. Unset EXTERNAL_PATH to use this option"
+ exit 1
+ fi
+ EXTERNAL_PATH=$withval
+ ],
+ [
+ if test "x${EXTERNAL_PATH}" = "x"; then
+ EXTERNAL_PATH=$1
+ fi
+ ]
+)
+if test "x${EXTERNAL_PATH}" = "x"; then
+ export EXTERNAL_PATH="$cdir/external"
+ GLOBAL_HEADER_MK="include ${EXTERNAL_PATH}/global_header.mk"
+ GLOBAL_FOOTER_MK="include ${EXTERNAL_PATH}/global_footer.mk"
+else
+ export EXTERNAL_PATH
+ GLOBAL_HEADER_MK="include ${EXTERNAL_PATH}/global_header.mk"
+ GLOBAL_FOOTER_MK="include ${EXTERNAL_PATH}/global_footer.mk"
+fi
+AC_MSG_RESULT($EXTERNAL_PATH)
+if test ! -d ${EXTERNAL_PATH}; then
+ echo ""
+ echo "ERROR: EXTERNAL_PATH set to an nonexistent directory ${EXTERNAL_PATH}"
+ exit 1
+fi
+AC_SUBST(EXTERNAL_PATH)
+AC_SUBST(GLOBAL_HEADER_MK)
+AC_SUBST(GLOBAL_FOOTER_MK)
+])
+
+# Set option to enable shared mode. Set DEBUG and OPT for use in Makefile.am.
+AC_DEFUN([FB_ENABLE_DEFAULT_OPT_BUILD],
+[
+AC_MSG_CHECKING([whether to enable optimized build])
+AC_ARG_ENABLE([opt],
+ [ --disable-opt Set up debug mode.],
+ [
+ ENABLED_OPT=$enableval
+ ],
+ [
+ ENABLED_OPT="yes"
+ ]
+)
+if test "$ENABLED_OPT" = "yes"
+then
+ CFLAGS="-Wall -O3"
+ CXXFLAGS="-Wall -O3"
+else
+ CFLAGS="-Wall -g"
+ CXXFLAGS="-Wall -g"
+fi
+AC_MSG_RESULT($ENABLED_OPT)
+AM_CONDITIONAL([OPT], [test "$ENABLED_OPT" = yes])
+AM_CONDITIONAL([DEBUG], [test "$ENABLED_OPT" = no])
+])
+
+# Set option to enable debug mode. Set DEBUG and OPT for use in Makefile.am.
+AC_DEFUN([FB_ENABLE_DEFAULT_DEBUG_BUILD],
+[
+AC_MSG_CHECKING([whether to enable debug build])
+AC_ARG_ENABLE([debug],
+ [ --disable-debug Set up opt mode.],
+ [
+ ENABLED_DEBUG=$enableval
+ ],
+ [
+ ENABLED_DEBUG="yes"
+ ]
+)
+if test "$ENABLED_DEBUG" = "yes"
+then
+ CFLAGS="-Wall -g"
+ CXXFLAGS="-Wall -g"
+else
+ CFLAGS="-Wall -O3"
+ CXXFLAGS="-Wall -O3"
+fi
+AC_MSG_RESULT($ENABLED_DEBUG)
+AM_CONDITIONAL([DEBUG], [test "$ENABLED_DEBUG" = yes])
+AM_CONDITIONAL([OPT], [test "$ENABLED_DEBUG" = no])
+])
+
+# Set option to enable static libs.
+AC_DEFUN([FB_ENABLE_DEFAULT_STATIC],
+[
+SHARED=""
+STATIC=""
+AC_MSG_CHECKING([whether to enable static mode])
+AC_ARG_ENABLE([static],
+ [ --disable-static Set up shared mode.],
+ [
+ ENABLED_STATIC=$enableval
+ ],
+ [
+ ENABLED_STATIC="yes"
+ ]
+)
+if test "$ENABLED_STATIC" = "yes"
+then
+ LTYPE=".a"
+else
+ LTYPE=".so"
+ SHARED_CXXFLAGS="-fPIC"
+ SHARED_CFLAGS="-fPIC"
+ SHARED_LDFLAGS="-shared -fPIC"
+ AC_SUBST(SHARED_CXXFLAGS)
+ AC_SUBST(SHARED_CFLAGS)
+ AC_SUBST(SHARED_LDFLAGS)
+fi
+AC_MSG_RESULT($ENABLED_STATIC)
+AC_SUBST(LTYPE)
+AM_CONDITIONAL([STATIC], [test "$ENABLED_STATIC" = yes])
+AM_CONDITIONAL([SHARED], [test "$ENABLED_STATIC" = no])
+])
+
+# Set option to enable shared libs.
+AC_DEFUN([FB_ENABLE_DEFAULT_SHARED],
+[
+SHARED=""
+STATIC=""
+AC_MSG_CHECKING([whether to enable shared mode])
+AC_ARG_ENABLE([shared],
+ [ --disable-shared Set up static mode.],
+ [
+ ENABLED_SHARED=$enableval
+ ],
+ [
+ ENABLED_SHARED="yes"
+ ]
+)
+if test "$ENABLED_SHARED" = "yes"
+then
+ LTYPE=".so"
+ SHARED_CXXFLAGS="-fPIC"
+ SHARED_CFLAGS="-fPIC"
+ SHARED_LDFLAGS="-shared -fPIC"
+ AC_SUBST(SHARED_CXXFLAGS)
+ AC_SUBST(SHARED_CFLAGS)
+ AC_SUBST(SHARED_LDFLAGS)
+else
+ LTYPE=".a"
+fi
+AC_MSG_RESULT($ENABLED_SHARED)
+AC_SUBST(LTYPE)
+AM_CONDITIONAL([SHARED], [test "$ENABLED_SHARED" = yes])
+AM_CONDITIONAL([STATIC], [test "$ENABLED_SHARED" = no])
+])
+
+# Generates define flags and conditionals as specified by user.
+# This gets enabled *only* if user selects --enable-<FEATURE> otion.
+AC_DEFUN([FB_ENABLE_FEATURE],
+[
+ENABLE=""
+flag="$1"
+value="$3"
+AC_MSG_CHECKING([whether to enable $1])
+AC_ARG_ENABLE([$2],
+ [ --enable-$2 Enable $2.],
+ [
+ ENABLE=$enableval
+ ],
+ [
+ ENABLE="no"
+ ]
+)
+AM_CONDITIONAL([$1], [test "$ENABLE" = yes])
+if test "$ENABLE" = "yes"
+then
+ if test "x${value}" = "x"
+ then
+ AC_DEFINE([$1])
+ else
+ AC_DEFINE_UNQUOTED([$1], [$value])
+ fi
+fi
+AC_MSG_RESULT($ENABLE)
+])
+
+
+# can also use eval $2=$withval;AC_SUBST($2)
+AC_DEFUN([FB_WITH_PATH],
+[
+USRFLAG=""
+USRFLAG=$1
+AC_MSG_CHECKING([Checking $1 set to])
+AC_ARG_WITH([$2],
+ [ --with-$2=DIR User specified path.],
+ [
+ LOC=$withval
+ eval $USRFLAG=$withval
+ ],
+ [
+ LOC=$3
+ eval $USRFLAG=$3
+ ]
+)
+AC_SUBST([$1])
+AC_MSG_RESULT($LOC)
+])
+
+AC_DEFUN([FB_SET_FLAG_VALUE],
+[
+SETFLAG=""
+AC_MSG_CHECKING([Checking $1 set to])
+SETFLAG=$1
+eval $SETFLAG=\"$2\"
+AC_SUBST([$SETFLAG])
+AC_MSG_RESULT($2)
+])
+
+# NOTES
+# if using if else bourne stmt you must have more than a macro in it.
+# EX1 is not correct. EX2 is correct
+# EX1: if test "$XX" = "yes"; then
+# AC_SUBST(xx)
+# fi
+# EX2: if test "$XX" = "yes"; then
+# xx="foo"
+# AC_SUBST(xx)
+# fi
diff --git a/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_boost_base.m4 b/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_boost_base.m4
new file mode 100644
index 000000000..e56bb7380
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_boost_base.m4
@@ -0,0 +1,198 @@
+##### http://autoconf-archive.cryp.to/ax_boost_base.html
+#
+# SYNOPSIS
+#
+# AX_BOOST_BASE([MINIMUM-VERSION])
+#
+# DESCRIPTION
+#
+# Test for the Boost C++ libraries of a particular version (or newer)
+#
+# If no path to the installed boost library is given the macro
+# searchs under /usr, /usr/local, /opt and /opt/local and evaluates
+# the $BOOST_ROOT environment variable. Further documentation is
+# available at <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
+#
+# And sets:
+#
+# HAVE_BOOST
+#
+# LAST MODIFICATION
+#
+# 2007-07-28
+#
+# COPYLEFT
+#
+# Copyright (c) 2007 Thomas Porschberg <thomas@randspringer.de>
+#
+# Copying and distribution of this file, with or without
+# modification, are permitted in any medium without royalty provided
+# the copyright notice and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_BASE],
+[
+AC_ARG_WITH([boost],
+ AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ac_boost_path=""
+ else
+ want_boost="yes"
+ ac_boost_path="$withval"
+ fi
+ ],
+ [want_boost="yes"])
+
+if test "x$want_boost" = "xyes"; then
+ boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
+ boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
+ boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
+ boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
+ boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+ if test "x$boost_lib_version_req_sub_minor" = "x" ; then
+ boost_lib_version_req_sub_minor="0"
+ fi
+ WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
+ AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
+ succeeded=no
+
+ dnl first we check the system location for boost libraries
+ dnl this location ist chosen if boost libraries are installed with the --layout=system option
+ dnl or if you install boost with RPM
+ if test "$ac_boost_path" != ""; then
+ BOOST_LDFLAGS="-L$ac_boost_path/lib"
+ BOOST_CPPFLAGS="-I$ac_boost_path/include"
+ else
+ for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
+ if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
+ BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
+ BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
+ break;
+ fi
+ done
+ fi
+
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= $WANT_BOOST_VERSION
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ succeeded=yes
+ found_system=yes
+ ],[
+ ])
+ AC_LANG_POP([C++])
+
+
+
+ dnl if we found no boost with system layout we search for boost libraries
+ dnl built and installed without the --layout=system option or for a staged(not installed) version
+ if test "x$succeeded" != "xyes"; then
+ _version=0
+ if test "$ac_boost_path" != ""; then
+ BOOST_LDFLAGS="-L$ac_boost_path/lib"
+ if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
+ for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
+ _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+ V_CHECK=`expr $_version_tmp \> $_version`
+ if test "$V_CHECK" = "1" ; then
+ _version=$_version_tmp
+ fi
+ VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
+ BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
+ done
+ fi
+ else
+ for ac_boost_path in /usr /usr/local /opt /opt/local ; do
+ if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
+ for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
+ _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+ V_CHECK=`expr $_version_tmp \> $_version`
+ if test "$V_CHECK" = "1" ; then
+ _version=$_version_tmp
+ best_path=$ac_boost_path
+ fi
+ done
+ fi
+ done
+
+ VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
+ BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
+ BOOST_LDFLAGS="-L$best_path/lib"
+
+ if test "x$BOOST_ROOT" != "x"; then
+ if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then
+ version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
+ stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
+ stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
+ V_CHECK=`expr $stage_version_shorten \>\= $_version`
+ if test "$V_CHECK" = "1" ; then
+ AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
+ BOOST_CPPFLAGS="-I$BOOST_ROOT"
+ BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib"
+ fi
+ fi
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= $WANT_BOOST_VERSION
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ succeeded=yes
+ found_system=yes
+ ],[
+ ])
+ AC_LANG_POP([C++])
+ fi
+
+ if test "$succeeded" != "yes" ; then
+ if test "$_version" = "0" ; then
+ AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
+ else
+ AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).])
+ fi
+ else
+ AC_SUBST(BOOST_CPPFLAGS)
+ AC_SUBST(BOOST_LDFLAGS)
+ AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+fi
+
+])
diff --git a/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_cxx_compile_stdcxx_11.m4 b/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_cxx_compile_stdcxx_11.m4
new file mode 100644
index 000000000..a4c9189c9
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_cxx_compile_stdcxx_11.m4
@@ -0,0 +1,134 @@
+# ============================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
+#
+# DESCRIPTION
+#
+# Check for baseline language coverage in the compiler for the C++11
+# standard; if necessary, add switches to CXXFLAGS to enable support.
+#
+# The first argument, if specified, indicates whether you insist on an
+# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+# -std=c++11). If neither is specified, you get whatever works, with
+# preference for an extended mode.
+#
+# The second argument, if specified 'mandatory' or if left unspecified,
+# indicates that baseline C++11 support is required and that the macro
+# should error out if no mode with that support is found. If specified
+# 'optional', then configuration proceeds regardless, after defining
+# HAVE_CXX11 if and only if a supporting mode is found.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 3
+
+m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
+ template <typename T>
+ struct check
+ {
+ static_assert(sizeof(int) <= sizeof(T), "not big enough");
+ };
+
+ typedef check<check<bool>> right_angle_brackets;
+
+ int a;
+ decltype(a) b;
+
+ typedef check<int> check_type;
+ check_type c;
+ check_type&& cr = static_cast<check_type&&>(c);
+
+ auto d = a;
+])
+
+AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
+ m4_if([$1], [], [],
+ [$1], [ext], [],
+ [$1], [noext], [],
+ [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
+ m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
+ [$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
+ [$2], [optional], [ax_cxx_compile_cxx11_required=false],
+ [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
+ AC_LANG_PUSH([C++])dnl
+ ac_success=no
+ AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
+ ax_cv_cxx_compile_cxx11,
+ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [ax_cv_cxx_compile_cxx11=yes],
+ [ax_cv_cxx_compile_cxx11=no])])
+ if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+ ac_success=yes
+ fi
+
+ m4_if([$1], [noext], [], [dnl
+ if test x$ac_success = xno; then
+ for switch in -std=gnu++11; do
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+ $cachevar,
+ [ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXXFLAGS="$ac_save_CXXFLAGS"])
+ if eval test x\$$cachevar = xyes; then
+ CXXFLAGS="$CXXFLAGS $switch"
+ ac_success=yes
+ break
+ fi
+ done
+ fi])
+
+ m4_if([$1], [ext], [], [dnl
+ if test x$ac_success = xno; then
+ for switch in -std=c++11; do
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+ $cachevar,
+ [ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXXFLAGS="$ac_save_CXXFLAGS"])
+ if eval test x\$$cachevar = xyes; then
+ CXXFLAGS="$CXXFLAGS $switch"
+ ac_success=yes
+ break
+ fi
+ done
+ fi])
+ AC_LANG_POP([C++])
+ if test x$ax_cxx_compile_cxx11_required = xtrue; then
+ if test x$ac_success = xno; then
+ AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
+ fi
+ else
+ if test x$ac_success = xno; then
+ HAVE_CXX11=0
+ AC_MSG_NOTICE([No compiler with C++11 support was found])
+ else
+ HAVE_CXX11=1
+ AC_DEFINE(HAVE_CXX11,1,
+ [define if the compiler supports basic C++11 syntax])
+ fi
+
+ AC_SUBST(HAVE_CXX11)
+ fi
+])
+
diff --git a/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_javac_and_java.m4 b/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_javac_and_java.m4
new file mode 100644
index 000000000..581b45066
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_javac_and_java.m4
@@ -0,0 +1,121 @@
+dnl @synopsis AX_JAVAC_AND_JAVA
+dnl @synopsis AX_CHECK_JAVA_CLASS(CLASSNAME)
+dnl
+dnl Test for the presence of a JDK, and (optionally) specific classes.
+dnl
+dnl If "JAVA" is defined in the environment, that will be the only
+dnl java command tested. Otherwise, a hard-coded list will be used.
+dnl Similarly for "JAVAC".
+dnl
+dnl AX_JAVAC_AND_JAVA does not currently support testing for a particular
+dnl Java version, testing for only one of "java" and "javac", or
+dnl compiling or running user-provided Java code.
+dnl
+dnl After AX_JAVAC_AND_JAVA runs, the shell variables "success" and
+dnl "ax_javac_and_java" are set to "yes" or "no", and "JAVAC" and
+dnl "JAVA" are set to the appropriate commands.
+dnl
+dnl AX_CHECK_JAVA_CLASS must be run after AX_JAVAC_AND_JAVA.
+dnl It tests for the presence of a class based on a fully-qualified name.
+dnl It sets the shell variable "success" to "yes" or "no".
+dnl
+dnl @category Java
+dnl @version 2009-02-09
+dnl @license AllPermissive
+dnl
+dnl Copyright (C) 2009 David Reiss
+dnl Copying and distribution of this file, with or without modification,
+dnl are permitted in any medium without royalty provided the copyright
+dnl notice and this notice are preserved.
+
+
+AC_DEFUN([AX_JAVAC_AND_JAVA],
+ [
+
+ dnl Hard-coded default commands to test.
+ JAVAC_PROGS="javac,jikes,gcj -C"
+ JAVA_PROGS="java,kaffe"
+
+ dnl Allow the user to specify an alternative.
+ if test -n "$JAVAC" ; then
+ JAVAC_PROGS="$JAVAC"
+ fi
+ if test -n "$JAVA" ; then
+ JAVA_PROGS="$JAVA"
+ fi
+
+ AC_MSG_CHECKING(for javac and java)
+
+ echo "public class configtest_ax_javac_and_java { public static void main(String args@<:@@:>@) { } }" > configtest_ax_javac_and_java.java
+ success=no
+ oIFS="$IFS"
+
+ IFS=","
+ for JAVAC in $JAVAC_PROGS ; do
+ IFS="$oIFS"
+
+ echo "Running \"$JAVAC configtest_ax_javac_and_java.java\"" >&AS_MESSAGE_LOG_FD
+ if $JAVAC configtest_ax_javac_and_java.java >&AS_MESSAGE_LOG_FD 2>&1 ; then
+
+ IFS=","
+ for JAVA in $JAVA_PROGS ; do
+ IFS="$oIFS"
+
+ echo "Running \"$JAVA configtest_ax_javac_and_java\"" >&AS_MESSAGE_LOG_FD
+ if $JAVA configtest_ax_javac_and_java >&AS_MESSAGE_LOG_FD 2>&1 ; then
+ success=yes
+ break 2
+ fi
+
+ done
+
+ fi
+
+ done
+
+ rm -f configtest_ax_javac_and_java.java configtest_ax_javac_and_java.class
+
+ if test "$success" != "yes" ; then
+ AC_MSG_RESULT(no)
+ JAVAC=""
+ JAVA=""
+ else
+ AC_MSG_RESULT(yes)
+ fi
+
+ ax_javac_and_java="$success"
+
+ ])
+
+
+AC_DEFUN([AX_CHECK_JAVA_CLASS],
+ [
+ AC_MSG_CHECKING(for Java class [$1])
+
+ echo "import $1; public class configtest_ax_javac_and_java { public static void main(String args@<:@@:>@) { } }" > configtest_ax_javac_and_java.java
+
+ echo "Running \"$JAVAC configtest_ax_javac_and_java.java\"" >&AS_MESSAGE_LOG_FD
+ if $JAVAC configtest_ax_javac_and_java.java >&AS_MESSAGE_LOG_FD 2>&1 ; then
+ AC_MSG_RESULT(yes)
+ success=yes
+ else
+ AC_MSG_RESULT(no)
+ success=no
+ fi
+
+ rm -f configtest_ax_javac_and_java.java configtest_ax_javac_and_java.class
+ ])
+
+
+AC_DEFUN([AX_CHECK_ANT_VERSION],
+ [
+ AC_MSG_CHECKING(for ant version > $2)
+ ANT_VALID=`expr $($1 -version 2>/dev/null | sed -n 's/.*version \(@<:@0-9\.@:>@*\).*/\1/p') \>= $2`
+ if test "x$ANT_VALID" = "x1" ; then
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ ANT=""
+ fi
+ ])
+
diff --git a/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_thrift_internal.m4 b/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_thrift_internal.m4
new file mode 100644
index 000000000..8c0e3cbc1
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/aclocal/ax_thrift_internal.m4
@@ -0,0 +1,28 @@
+dnl @synopsis AX_THRIFT_GEN(SHORT_LANGUAGE, LONG_LANGUAGE, DEFAULT)
+dnl @synopsis AX_THRIFT_LIB(SHORT_LANGUAGE, LONG_LANGUAGE, DEFAULT)
+dnl
+dnl Allow a particular language generator to be disabled.
+dnl Allow a particular language library to be disabled.
+dnl
+dnl These macros have poor error handling and are poorly documented.
+dnl They are intended only for internal use by the Thrift compiler.
+dnl
+dnl @version 2008-02-20
+dnl @license AllPermissive
+dnl
+dnl Copyright (C) 2009 David Reiss
+dnl Copying and distribution of this file, with or without modification,
+dnl are permitted in any medium without royalty provided the copyright
+dnl notice and this notice are preserved.
+
+AC_DEFUN([AX_THRIFT_LIB],
+ [
+ AC_ARG_WITH($1,
+ AC_HELP_STRING([--with-$1], [build the $2 library @<:@default=$3@:>@]),
+ [with_$1="$withval"],
+ [with_$1=$3]
+ )
+ have_$1=no
+ dnl What we do here is going to vary from library to library,
+ dnl so we can't really generalize (yet!).
+ ])
diff --git a/src/jaegertracing/thrift/contrib/fb303/bootstrap.sh b/src/jaegertracing/thrift/contrib/fb303/bootstrap.sh
new file mode 100755
index 000000000..3cbeddb34
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/bootstrap.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+#
+# 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.
+#
+
+# To be safe include -I flag
+aclocal -I ./aclocal
+automake -a
+autoconf
+./configure --config-cache $*
diff --git a/src/jaegertracing/thrift/contrib/fb303/configure.ac b/src/jaegertracing/thrift/contrib/fb303/configure.ac
new file mode 100644
index 000000000..73b35ba07
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/configure.ac
@@ -0,0 +1,164 @@
+# Autoconf input file
+# $Id$
+
+# AC - autoconf
+# FB - facebook
+
+#
+# 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.
+#
+
+#########################################################################
+# DO NOT TOUCH EXCEPT TO CHANGE REV# IN AC_INIT
+
+AC_PREREQ(2.52)
+AC_INIT([libfb303],[20080209])
+#AC_CONFIG_AUX_DIR([/usr/share/automake-1.9])
+# To install locally
+FB_INITIALIZE([localinstall])
+AC_PREFIX_DEFAULT([/usr/local])
+
+############################################################################
+# User Configurable. Change With CAUTION!
+# User can include custom makefile rules. Uncomment and update only <name> in PRODUCT_MK.
+# Include where appropriate in any Makefile.am as @PRODUCT_MK@
+
+#PRODUCT_MK="include ${EXTERNAL_PATH}/shared/build/<name>.mk"
+
+# Default path to external Facebook components and shared build toools I.e fb303 etc.
+# To point to other locations set environment variable EXTERNAL_PATH.
+# To change the current default you must change bootstrap.sh.
+FB_WITH_EXTERNAL_PATH([`pwd`])
+
+AC_ARG_VAR([PY_PREFIX], [Prefix for installing Python modules.
+ (Normal --prefix is ignored for Python because
+ Python has different conventions.)
+ Default = "/usr"])
+AS_IF([test "x$PY_PREFIX" = x], [PY_PREFIX="/usr"])
+
+##########################################################################
+# User Configurable
+
+# Pre-defined macro to set opt build mode. Run with --disable-shared option to turn off optimization.
+FB_ENABLE_DEFAULT_OPT_BUILD
+
+# Predefined macro to set static library mode. Run with --disable-static option to turn off static lib mode.
+FB_ENABLE_DEFAULT_STATIC
+
+# Personalized feature generator. Creates defines/conditionals and --enable --disable command line options.
+# FB_ENABLE_FEATURE([FEATURE], [feature]) OR FB_ENABLE_FEATURE([FEATURE], [feature], [\"<value>\"])
+
+# Example: Macro supplies -DFACEBOOK at compile time and "if FACEBOOK endif" capabilities.
+
+# Personalized path generator Sets default paths. Provides --with-xx=DIR options.
+# FB_WITH_PATH([<var>_home], [<var>path], [<default location>]
+
+# Example: sets $(thrift_home) variable with default path set to /usr/local.
+FB_WITH_PATH([thrift_home], [thriftpath], [/usr/local])
+
+AX_CXX_COMPILE_STDCXX_11([noext])
+AX_THRIFT_LIB(cpp, [C++], yes)
+have_cpp=no
+if test "$with_cpp" = "yes"; then
+ # Require boost 1.40.0 or later
+ AX_BOOST_BASE([1.40.0])
+ if test "x$succeeded" = "xyes"; then
+ have_cpp="yes"
+ fi
+fi
+AM_CONDITIONAL([WITH_CPP], [test "$have_cpp" = "yes"])
+
+AX_THRIFT_LIB(java, [Java], yes)
+if test "$with_java" = "yes"; then
+ AX_JAVAC_AND_JAVA
+ AC_PATH_PROG([ANT], [ant])
+ AX_CHECK_ANT_VERSION($ANT, 1.7)
+ AC_SUBST(CLASSPATH)
+ AC_SUBST(ANT_FLAGS)
+ if test "x$JAVAC" != "x" && test "x$JAVAC" != "x" && test "x$ANT" != "x" ; then
+ have_java="yes"
+ fi
+fi
+AM_CONDITIONAL(WITH_JAVA, [test "$have_java" = "yes"])
+
+AX_THRIFT_LIB(php, [PHP], yes)
+if test "$with_php" = "yes"; then
+ AC_PATH_PROG([PHP], [php])
+ if test "x$PHP" != "x" && test "x$PHP" != "x:" ; then
+ have_php="yes"
+ fi
+fi
+AM_CONDITIONAL(WITH_PHP, [test "$have_php" = "yes"])
+
+AX_THRIFT_LIB(python, [Python], yes)
+if test "$with_python" = "yes"; then
+ AM_PATH_PYTHON(2.4,, :)
+ if test "x$PYTHON" != "x" && test "x$PYTHON" != "x:" ; then
+ have_python="yes"
+ fi
+fi
+AM_CONDITIONAL(WITH_PYTHON, [test "$have_python" = "yes"])
+
+# Generates Makefile from Makefile.am. Modify when new subdirs are added.
+# Change Makefile.am also to add subdirectly.
+AC_CONFIG_FILES(Makefile cpp/Makefile py/Makefile)
+
+# Check for headers
+AC_CHECK_HEADERS([inttypes.h])
+AC_CHECK_HEADERS([netinet/in.h])
+
+############################################################################
+# DO NOT TOUCH.
+
+AC_SUBST(PRODUCT_MK)
+AC_OUTPUT
+
+#############################################################################
+######### FINISH ############################################################
+
+echo "EXTERNAL_PATH $EXTERNAL_PATH"
+echo
+echo "Building C++ Library ......... : $have_cpp"
+echo "Building Java Library ........ : $have_java"
+echo "Building Python Library ...... : $have_python"
+echo "Building PHP Library ......... : $have_php"
+
+
+#
+# NOTES FOR USER
+# Short cut to create conditional flags.
+#enable_facebook="yes"
+#AM_CONDITIONAL([FACEBOOK], [test "$enable_facebook" = yes])
+#enable_hdfs="yes"
+#AM_CONDITIONAL([HDFS], [test "$enable_hdfs" = yes])
+
+# Enable options with --enable and --disable configurable.
+#AC_MSG_CHECKING([whether to enable FACEBOOK])
+#FACEBOOK=""
+#AC_ARG_ENABLE([facebook],
+# [ --enable-facebook Enable facebook.],
+# [
+# ENABLE_FACEBOOK=$enableval
+# ],
+# [
+# ENABLE_FACEBOOK="no"
+# ]
+#)
+#AM_CONDITIONAL([FACEBOOK], [test "$ENABLE_FACEBOOK" = yes])
+#AC_MSG_RESULT($ENABLE_FACEBOOK)
+
diff --git a/src/jaegertracing/thrift/contrib/fb303/cpp/FacebookBase.cpp b/src/jaegertracing/thrift/contrib/fb303/cpp/FacebookBase.cpp
new file mode 100644
index 000000000..3c569759c
--- /dev/null
+++ b/src/jaegertracing/thrift/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/src/jaegertracing/thrift/contrib/fb303/cpp/FacebookBase.h b/src/jaegertracing/thrift/contrib/fb303/cpp/FacebookBase.h
new file mode 100644
index 000000000..daa524644
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/cpp/FacebookBase.h
@@ -0,0 +1,104 @@
+/*
+ * 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 <boost/shared_ptr.hpp>
+#include <thrift/server/TServer.h>
+#include <thrift/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/src/jaegertracing/thrift/contrib/fb303/cpp/Makefile.am b/src/jaegertracing/thrift/contrib/fb303/cpp/Makefile.am
new file mode 100644
index 000000000..748d3298d
--- /dev/null
+++ b/src/jaegertracing/thrift/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 = $(prefix)/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:pure_enums ))
+
+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/src/jaegertracing/thrift/contrib/fb303/cpp/ServiceTracker.cpp b/src/jaegertracing/thrift/contrib/fb303/cpp/ServiceTracker.cpp
new file mode 100644
index 000000000..7a61b21a9
--- /dev/null
+++ b/src/jaegertracing/thrift/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 <thrift/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/src/jaegertracing/thrift/contrib/fb303/cpp/ServiceTracker.h b/src/jaegertracing/thrift/contrib/fb303/cpp/ServiceTracker.h
new file mode 100644
index 000000000..9a3edd8f1
--- /dev/null
+++ b/src/jaegertracing/thrift/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 <thrift/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
diff --git a/src/jaegertracing/thrift/contrib/fb303/global_footer.mk b/src/jaegertracing/thrift/contrib/fb303/global_footer.mk
new file mode 100644
index 000000000..96f82ebd2
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/global_footer.mk
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+
+thriftstyle : $(XBUILT_SOURCES)
+
diff --git a/src/jaegertracing/thrift/contrib/fb303/global_header.mk b/src/jaegertracing/thrift/contrib/fb303/global_header.mk
new file mode 100644
index 000000000..77c9455ee
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/global_header.mk
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+#define thrift_template
+# $(1) : $(2)
+# $$(THRIFT) $(3) $(4) $(5) $(6) $(7) $(8) $$<
+#endef
+
+define thrift_template
+XTARGET := $(shell perl -e '@val = split("\/","$(2)"); $$last = pop(@val);split("\\.",$$last);print "$(1)/"."gen-cpp/"."@_[0]"."_types.cpp\n"' )
+
+ifneq ($$(XBUILT_SOURCES),)
+ XBUILT_SOURCES := $$(XBUILT_SOURCES) $$(XTARGET)
+else
+ XBUILT_SOURCES := $$(XTARGET)
+endif
+$$(XTARGET) : $(2)
+ $$(THRIFT) -o $1 $3 $$<
+endef
+
+clean-common:
+ rm -rf gen-*
diff --git a/src/jaegertracing/thrift/contrib/fb303/if/fb303.thrift b/src/jaegertracing/thrift/contrib/fb303/if/fb303.thrift
new file mode 100644
index 000000000..89bd6eb7b
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/if/fb303.thrift
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+/**
+ * fb303.thrift
+ */
+
+namespace java com.facebook.fb303
+namespace cpp facebook.fb303
+namespace perl Facebook.FB303
+namespace netcore Facebook.FB303.Test
+
+/**
+ * Common status reporting mechanism across all services
+ */
+enum fb_status {
+ DEAD = 0,
+ STARTING = 1,
+ ALIVE = 2,
+ STOPPING = 3,
+ STOPPED = 4,
+ WARNING = 5,
+}
+
+/**
+ * Standard base service
+ */
+service FacebookService {
+
+ /**
+ * Returns a descriptive name of the service
+ */
+ string getName(),
+
+ /**
+ * Returns the version of the service
+ */
+ string getVersion(),
+
+ /**
+ * Gets the status of this service
+ */
+ fb_status getStatus(),
+
+ /**
+ * User friendly description of status, such as why the service is in
+ * the dead or warning state, or what is being started or stopped.
+ */
+ string getStatusDetails(),
+
+ /**
+ * Gets the counters for this service
+ */
+ map<string, i64> getCounters(),
+
+ /**
+ * Gets the value of a single counter
+ */
+ i64 getCounter(1: string key),
+
+ /**
+ * Sets an option
+ */
+ void setOption(1: string key, 2: string value),
+
+ /**
+ * Gets an option
+ */
+ string getOption(1: string key),
+
+ /**
+ * Gets all options
+ */
+ map<string, string> getOptions(),
+
+ /**
+ * Returns a CPU profile over the given time interval (client and server
+ * must agree on the profile format).
+ */
+ string getCpuProfile(1: i32 profileDurationInSec),
+
+ /**
+ * Returns the unix time that the server has been running since
+ */
+ i64 aliveSince(),
+
+ /**
+ * Tell the server to reload its configuration, reopen log files, etc
+ */
+ oneway void reinitialize(),
+
+ /**
+ * Suggest a shutdown to the server
+ */
+ oneway void shutdown(),
+
+}
diff --git a/src/jaegertracing/thrift/contrib/fb303/java/build.properties b/src/jaegertracing/thrift/contrib/fb303/java/build.properties
new file mode 100644
index 000000000..84636683c
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/java/build.properties
@@ -0,0 +1,5 @@
+# Maven Ant tasks Jar details
+mvn.ant.task.version=2.1.3
+mvn.repo=http://repo1.maven.org/maven2
+mvn.ant.task.url=${mvn.repo}/org/apache/maven/maven-ant-tasks/${mvn.ant.task.version}
+mvn.ant.task.jar=maven-ant-tasks-${mvn.ant.task.version}.jar
diff --git a/src/jaegertracing/thrift/contrib/fb303/java/build.xml b/src/jaegertracing/thrift/contrib/fb303/java/build.xml
new file mode 100755
index 000000000..7a1b8f105
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/java/build.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+ -->
+<project name="libfb303" default="dist" basedir="."
+ xmlns:artifact="antlib:org.apache.maven.artifact.ant">
+
+ <!-- project wide settings. All directories relative to basedir -->
+ <property name="thrift.root" location="${basedir}/../../../"/>
+ <property name="fb303.artifactid" value="libfb303"/>
+ <property name="interface.dir" value="${basedir}/../if"/>
+ <property name="thrift.java.dir" location="${thrift.root}/lib/java"/>
+ <property name="build.tools.dir" location="${thrift.java.dir}/build/tools/"/>
+ <property name="thrift_compiler" value="${thrift.root}/compiler/cpp/thrift"/>
+ <property file="${basedir}/build.properties"/>
+
+ <!-- inherit from the java build file for version and other properties -->
+ <property file="${thrift.java.dir}/gradle.properties" />
+
+ <property environment="env"/>
+
+ <condition property="version" value="${thrift.version}">
+ <isset property="release"/>
+ </condition>
+ <property name="version" value="${thrift.version}-SNAPSHOT"/>
+
+ <property name="fb303.final.name" value="${fb303.artifactid}-${version}"/>
+
+ <property name="src" value="${basedir}/src"/>
+ <property name="gen" value="${basedir}/gen-java"/>
+ <property name="build.dir" value="${basedir}/build"/>
+ <property name="build.lib.dir" value="${build.dir}/lib"/>
+ <property name="build.classes.dir" value="${build.dir}/classes"/>
+
+ <property name="fb303.jar.file" location="${build.dir}/${fb303.final.name}.jar"/>
+ <property name="fb303.pom.xml" location="${build.dir}/${fb303.final.name}.pom"/>
+
+ <target name="init" depends="setup.init,mvn.init" unless="init.finished">
+ <property name="init.finished" value="true"/>
+ </target>
+
+ <target name="setup.init">
+ <tstamp/>
+ <mkdir dir="${build.dir}"/>
+ <mkdir dir="${build.classes.dir}"/>
+ <mkdir dir="${build.lib.dir}"/>
+ </target>
+
+ <!-- generate fb303 thrift code -->
+ <target name="generate">
+ <echo message="generating thrift fb303 files"/>
+ <exec executable="${thrift_compiler}" failonerror="true">
+ <arg line="--gen java -o ${basedir} ${interface.dir}/fb303.thrift"/>
+ </exec>
+ </target>
+
+ <!-- compile the base and thrift generated code and jar them -->
+ <target name="dist" depends="init,generate">
+ <echo message="Building ${fb303.final.name}.jar"/>
+ <javac destdir="${build.classes.dir}" debug="on">
+ <classpath>
+ <fileset dir="${thrift.java.dir}/build/libs">
+ <include name="libthrift*.jar" />
+ <exclude name="libthrift*javadoc.jar" />
+ <exclude name="libthrift*sources.jar" />
+ </fileset>
+ <fileset dir="${thrift.java.dir}/build/deps">
+ <include name="*.jar"/>
+ </fileset>
+ </classpath>
+ <src path="${src}"/>
+ <src path="${gen}"/>
+ <include name="**/*.java"/>
+ </javac>
+ <jar jarfile="${build.dir}/${fb303.final.name}.jar" basedir="${build.classes.dir}">
+ </jar>
+ </target>
+
+ <!-- copy the build jar to the distribution library directory -->
+ <target name="install" depends="dist">
+ <copy todir="${install.path}">
+ <fileset dir="${build.lib.dir}" includes="*.jar"/>
+ <fileset dir="${build.lib.dir}" includes="${fb303.final.name}.jar"/>
+ </copy>
+ </target>
+
+ <target name="clean">
+ <delete dir="${build.dir}"/>
+ <delete dir="${gen}"/>
+ </target>
+
+ <target name="mvn.ant.tasks.download" depends="setup.init,mvn.ant.tasks.check" unless="mvn.ant.tasks.found">
+ <get src="${mvn.ant.task.url}/${mvn.ant.task.jar}" dest="${build.tools.dir}/${mvn.ant.task.jar}" usetimestamp="true"/>
+ </target>
+
+ <target name="mvn.ant.tasks.check">
+ <condition property="mvn.ant.tasks.found">
+ <typefound uri="antlib:org.apache.maven.artifact.ant" name="artifact"/>
+ </condition>
+ </target>
+
+ <target name="mvn.init" depends="mvn.ant.tasks.download" unless="mvn.finished">
+ <echo message="${mvn.ant.task.jar}"/>
+ <!-- Download mvn ant tasks, download dependencies, and setup pom file -->
+ <typedef uri="antlib:org.apache.maven.artifact.ant" classpath="${build.tools.dir}/${mvn.ant.task.jar}"/>
+
+ <!-- remote repositories used to download dependencies from -->
+ <artifact:remoteRepository id="central" url="${mvn.repo}"/>
+ <artifact:remoteRepository id="apache" url="${apache.repo}"/>
+
+ <!-- Pom file information -->
+ <artifact:pom id="pom"
+ groupId="${thrift.groupid}"
+ artifactId="${fb303.artifactid}"
+ version="${version}"
+ url="http://thrift.apache.org"
+ name="Apache Thrift"
+ description="Thrift is a software framework for scalable cross-language services development."
+ packaging="jar"
+ >
+ <remoteRepository refid="central"/>
+ <remoteRepository refid="apache"/>
+ <license name="The Apache Software License, Version 2.0" url="${license}"/>
+ <scm connection="scm:git:https://github.com/apache/thrift.git"
+ developerConnection="scm:git:https://github.com/apache/thrift.git"
+ url="https://github.com/apache/thrift"
+ />
+ <!-- Thrift Developers -->
+ <developer id="mcslee" name="Mark Slee"/>
+ <developer id="dreiss" name="David Reiss"/>
+ <developer id="aditya" name="Aditya Agarwal"/>
+ <developer id="marck" name="Marc Kwiatkowski"/>
+ <developer id="jwang" name="James Wang"/>
+ <developer id="cpiro" name="Chris Piro"/>
+ <developer id="bmaurer" name="Ben Maurer"/>
+ <developer id="kclark" name="Kevin Clark"/>
+ <developer id="jake" name="Jake Luciani"/>
+ <developer id="bryanduxbury" name="Bryan Duxbury"/>
+ <developer id="esteve" name="Esteve Fernandez"/>
+ <developer id="todd" name="Todd Lipcon"/>
+ <developer id="geechorama" name="Andrew McGeachie"/>
+ <developer id="molinaro" name="Anthony Molinaro"/>
+ <developer id="roger" name="Roger Meier"/>
+ <developer id="jfarrell" name="Jake Farrell"/>
+ <developer id="jensg" name="Jens Geyer"/>
+ <developer id="carl" name="Carl Yeksigian"/>
+
+ <!-- Thrift dependencies list -->
+ <dependency groupId="org.apache.thrift" artifactId="libthrift" version="${version}"/>
+ </artifact:pom>
+
+ <!-- Generate the pom file -->
+ <artifact:writepom pomRefId="pom" file="${fb303.pom.xml}"/>
+
+ <property name="mvn.finished" value="true"/>
+ </target>
+
+ <macrodef name="signAndDeploy">
+ <!-- Sign and deploy jars to apache repo -->
+ <attribute name="file"/>
+ <attribute name="classifier" default=""/>
+ <attribute name="packaging" default="jar"/>
+ <attribute name="pom" default=""/>
+ <sequential>
+ <artifact:mvn fork="true">
+ <arg value="org.apache.maven.plugins:maven-gpg-plugin:1.1:sign-and-deploy-file"/>
+ <arg value="-DrepositoryId=${maven-repository-id}"/>
+ <arg value="-Durl=${maven-repository-url}"/>
+ <arg value="-DpomFile=@{pom}"/>
+ <arg value="-Dfile=@{file}"/>
+ <arg value="-Dclassifier=@{classifier}"/>
+ <arg value="-Dpackaging=@{packaging}"/>
+ <arg value="-Pgpg"/>
+ </artifact:mvn>
+ </sequential>
+ </macrodef>
+
+ <target name="publish" depends="clean,dist">
+ <!-- Compile, packages and then send release to apache maven repo -->
+ <!-- run with: ant -Drelease=true publish-->
+ <signAndDeploy file="${fb303.pom.xml}" packaging="pom" classifier="" pom="${fb303.pom.xml}"/>
+ <signAndDeploy file="${fb303.jar.file}" packaging="jar" classifier="" pom="${fb303.pom.xml}"/>
+ </target>
+</project>
diff --git a/src/jaegertracing/thrift/contrib/fb303/java/src/FacebookBase.java b/src/jaegertracing/thrift/contrib/fb303/java/src/FacebookBase.java
new file mode 100644
index 000000000..f8f26a318
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/java/src/FacebookBase.java
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+package com.facebook.fb303;
+
+import java.util.AbstractMap;
+import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+public abstract class FacebookBase implements FacebookService.Iface {
+
+ private String name_;
+
+ private long alive_;
+
+ private final ConcurrentHashMap<String,Long> counters_ =
+ new ConcurrentHashMap<String, Long>();
+
+ private final ConcurrentHashMap<String,String> options_ =
+ new ConcurrentHashMap<String, String>();
+
+ protected FacebookBase(String name) {
+ name_ = name;
+ alive_ = System.currentTimeMillis() / 1000;
+ }
+
+ public String getName() {
+ return name_;
+ }
+
+ public abstract fb_status getStatus();
+
+ public String getStatusDetails() {
+ return "";
+ }
+
+ public void deleteCounter(String key) {
+ counters_.remove(key);
+ }
+
+ public void resetCounter(String key) {
+ counters_.put(key, 0L);
+ }
+
+ public long incrementCounter(String key) {
+ long val = getCounter(key) + 1;
+ counters_.put(key, val);
+ return val;
+ }
+
+ public long incrementCounter(String key, long increment) {
+ long val = getCounter(key) + increment;
+ counters_.put(key, val);
+ return val;
+ }
+
+ public long setCounter(String key, long value) {
+ counters_.put(key, value);
+ return value;
+ }
+
+ public AbstractMap<String,Long> getCounters() {
+ return counters_;
+ }
+
+ public long getCounter(String key) {
+ Long val = counters_.get(key);
+ if (val == null) {
+ return 0;
+ }
+ return val.longValue();
+ }
+
+ public void setOption(String key, String value) {
+ options_.put(key, value);
+ }
+
+ public String getOption(String key) {
+ return options_.get(key);
+ }
+
+ public AbstractMap<String,String> getOptions() {
+ return options_;
+ }
+
+ public long aliveSince() {
+ return alive_;
+ }
+
+ public String getCpuProfile() {
+ return "";
+ }
+
+ public void reinitialize() {}
+
+ public void shutdown() {}
+
+}
diff --git a/src/jaegertracing/thrift/contrib/fb303/php/FacebookBase.php b/src/jaegertracing/thrift/contrib/fb303/php/FacebookBase.php
new file mode 100644
index 000000000..2ac318fb3
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/php/FacebookBase.php
@@ -0,0 +1,89 @@
+<?php
+/*
+ * 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.
+ */
+
+/**
+ * Abstract Class providing null implementation for FacebookService
+ * methods.
+ */
+class FacebookBase implements FacebookServiceIf {
+ protected $name_ = '';
+
+ public function __construct($name) {
+ $this->name_ = $name;
+ }
+
+ public function getName() {
+ return $this->name_;
+ }
+
+ public function getVersion() {
+ return '';
+ }
+
+ public function getStatus() {
+ return null;
+ }
+
+ public function getStatusDetails() {
+ return '';
+ }
+
+ public function getCounters() {
+ return array();
+ }
+
+ public function getCounter($key) {
+ return null;
+ }
+
+ public function setOption($key, $value) {
+ return;
+ }
+
+ public function getOption($key) {
+ return '';
+ }
+
+ public function getOptions() {
+ return array();
+ }
+
+ public function aliveSince() {
+ return 0;
+ }
+
+ public function getCpuProfile($duration) {
+ return '';
+ }
+
+ public function getLimitedReflection() {
+ return array();
+ }
+
+ public function reinitialize() {
+ return;
+ }
+
+ public function shutdown() {
+ return;
+ }
+
+}
+
diff --git a/src/jaegertracing/thrift/contrib/fb303/py/Makefile.am b/src/jaegertracing/thrift/contrib/fb303/py/Makefile.am
new file mode 100644
index 000000000..060495e58
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/py/Makefile.am
@@ -0,0 +1,44 @@
+#
+# 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.
+#
+
+DESTDIR ?= /
+EXTRA_DIST = setup.py src
+
+all:
+
+all-local:
+ $(thrift_home)/bin/thrift --gen py $(top_srcdir)/if/fb303.thrift
+ mv gen-py/fb303/* fb303
+ $(PYTHON) setup.py build
+
+# We're ignoring prefix here because site-packages seems to be
+# the equivalent of /usr/local/lib in Python land.
+# Old version (can't put inline because it's not portable).
+#$(PYTHON) setup.py install --prefix=$(prefix) --root=$(DESTDIR) $(PYTHON_SETUPUTIL_ARGS)
+install-exec-hook:
+ $(PYTHON) setup.py install --root=$(DESTDIR) --prefix=$(PY_PREFIX) $(PYTHON_SETUPUTIL_ARGS)
+
+
+
+clean: clean-local
+
+clean-local:
+ $(RM) -r build
+
+check-local: all
diff --git a/src/jaegertracing/thrift/contrib/fb303/py/fb303/FacebookBase.py b/src/jaegertracing/thrift/contrib/fb303/py/fb303/FacebookBase.py
new file mode 100644
index 000000000..07db10cd3
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/py/fb303/FacebookBase.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+import time
+import FacebookService
+import thrift.reflection.limited
+from ttypes import fb_status
+
+
+class FacebookBase(FacebookService.Iface):
+
+ def __init__(self, name):
+ self.name = name
+ self.alive = int(time.time())
+ self.counters = {}
+
+ def getName(self, ):
+ return self.name
+
+ def getVersion(self, ):
+ return ''
+
+ def getStatus(self, ):
+ return fb_status.ALIVE
+
+ def getCounters(self):
+ return self.counters
+
+ def resetCounter(self, key):
+ self.counters[key] = 0
+
+ def getCounter(self, key):
+ if self.counters.has_key(key):
+ return self.counters[key]
+ return 0
+
+ def incrementCounter(self, key):
+ self.counters[key] = self.getCounter(key) + 1
+
+ def setOption(self, key, value):
+ pass
+
+ def getOption(self, key):
+ return ""
+
+ def getOptions(self):
+ return {}
+
+ def getOptions(self):
+ return {}
+
+ def aliveSince(self):
+ return self.alive
+
+ def getCpuProfile(self, duration):
+ return ""
+
+ def getLimitedReflection(self):
+ return thrift.reflection.limited.Service()
+
+ def reinitialize(self):
+ pass
+
+ def shutdown(self):
+ pass
diff --git a/src/jaegertracing/thrift/contrib/fb303/py/fb303_scripts/__init__.py b/src/jaegertracing/thrift/contrib/fb303/py/fb303_scripts/__init__.py
new file mode 100644
index 000000000..f8e3a94b9
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/py/fb303_scripts/__init__.py
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+
+__all__ = ['fb303_simple_mgmt']
diff --git a/src/jaegertracing/thrift/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py b/src/jaegertracing/thrift/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py
new file mode 100644
index 000000000..5c8f409c1
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+from __future__ import print_function
+import sys
+import os
+from optparse import OptionParser
+
+from thrift.Thrift import *
+
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+
+from fb303 import *
+from fb303.ttypes import *
+
+
+def service_ctrl(
+ command,
+ port,
+ trans_factory=None,
+ prot_factory=None):
+ """
+ service_ctrl is a generic function to execute standard fb303 functions
+
+ @param command: one of stop, start, reload, status, counters, name, alive
+ @param port: service's port
+ @param trans_factory: TTransportFactory to use for obtaining a TTransport. Default is
+ TBufferedTransportFactory
+ @param prot_factory: TProtocolFactory to use for obtaining a TProtocol. Default is
+ TBinaryProtocolFactory
+ """
+
+ if command in ["status"]:
+ try:
+ status = fb303_wrapper('status', port, trans_factory, prot_factory)
+ status_details = fb303_wrapper('get_status_details', port, trans_factory, prot_factory)
+
+ msg = fb_status_string(status)
+ if (len(status_details)):
+ msg += " - %s" % status_details
+ print(msg)
+ return 2 if status == fb_status.ALIVE else 3
+ except:
+ print("Failed to get status")
+ return 3
+
+ # scalar commands
+ if command in ["version", "alive", "name"]:
+ try:
+ result = fb303_wrapper(command, port, trans_factory, prot_factory)
+ print(result)
+ return 0
+ except:
+ print("failed to get ", command)
+ return 3
+
+ # counters
+ if command in ["counters"]:
+ try:
+ counters = fb303_wrapper('counters', port, trans_factory, prot_factory)
+ for counter in counters:
+ print("%s: %d" % (counter.encode('utf-8'), counters[counter]))
+ return 0
+ except:
+ print("failed to get counters")
+ return 3
+
+ # Only root should be able to run the following commands
+ if os.getuid() == 0:
+ # async commands
+ if command in ["stop", "reload"]:
+ try:
+ fb303_wrapper(command, port, trans_factory, prot_factory)
+ return 0
+ except:
+ print("failed to tell the service to ", command)
+ return 3
+ else:
+ if command in ["stop", "reload"]:
+ print("root privileges are required to stop or reload the service.")
+ return 4
+
+ print("The following commands are available:")
+ for command in ["counters", "name", "version", "alive", "status"]:
+ print("\t%s" % command)
+ print("The following commands are available for users with root privileges:")
+ for command in ["stop", "reload"]:
+ print("\t%s" % command)
+
+ return 0
+
+
+def fb303_wrapper(command, port, trans_factory=None, prot_factory=None):
+ sock = TSocket.TSocket('localhost', port)
+
+ # use input transport factory if provided
+ if (trans_factory is None):
+ trans = TTransport.TBufferedTransport(sock)
+ else:
+ trans = trans_factory.getTransport(sock)
+
+ # use input protocol factory if provided
+ if (prot_factory is None):
+ prot = TBinaryProtocol.TBinaryProtocol(trans)
+ else:
+ prot = prot_factory.getProtocol(trans)
+
+ # initialize client and open transport
+ fb303_client = FacebookService.Client(prot, prot)
+ trans.open()
+
+ if (command == 'reload'):
+ fb303_client.reinitialize()
+
+ elif (command == 'stop'):
+ fb303_client.shutdown()
+
+ elif (command == 'status'):
+ return fb303_client.getStatus()
+
+ elif (command == 'version'):
+ return fb303_client.getVersion()
+
+ elif (command == 'get_status_details'):
+ return fb303_client.getStatusDetails()
+
+ elif (command == 'counters'):
+ return fb303_client.getCounters()
+
+ elif (command == 'name'):
+ return fb303_client.getName()
+
+ elif (command == 'alive'):
+ return fb303_client.aliveSince()
+
+ trans.close()
+
+
+def fb_status_string(status_enum):
+ if (status_enum == fb_status.DEAD):
+ return "DEAD"
+ if (status_enum == fb_status.STARTING):
+ return "STARTING"
+ if (status_enum == fb_status.ALIVE):
+ return "ALIVE"
+ if (status_enum == fb_status.STOPPING):
+ return "STOPPING"
+ if (status_enum == fb_status.STOPPED):
+ return "STOPPED"
+ if (status_enum == fb_status.WARNING):
+ return "WARNING"
+
+
+def main():
+
+ # parse command line options
+ parser = OptionParser()
+ commands = ["stop", "counters", "status", "reload", "version", "name", "alive"]
+
+ parser.add_option("-c", "--command", dest="command", help="execute this API",
+ choices=commands, default="status")
+ parser.add_option("-p", "--port", dest="port", help="the service's port",
+ default=9082)
+
+ (options, args) = parser.parse_args()
+ status = service_ctrl(options.command, options.port)
+ sys.exit(status)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/jaegertracing/thrift/contrib/fb303/py/setup.py b/src/jaegertracing/thrift/contrib/fb303/py/setup.py
new file mode 100644
index 000000000..d27c2962f
--- /dev/null
+++ b/src/jaegertracing/thrift/contrib/fb303/py/setup.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+import sys
+try:
+ from setuptools import setup, Extension
+except:
+ from distutils.core import setup, Extension, Command
+
+setup(name='thrift_fb303',
+ version='1.0.0',
+ description='Python bindings for the Apache Thrift FB303',
+ author=['Apache Thrift Developers'],
+ author_email=['dev@thrift.apache.org'],
+ url='http://thrift.apache.org',
+ license='Apache License 2.0',
+ packages=[
+ 'fb303',
+ 'fb303_scripts',
+ ],
+ classifiers=[
+ 'Development Status :: 7 - Inactive',
+ 'Environment :: Console',
+ 'Intended Audience :: Developers',
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2',
+ 'Topic :: Software Development :: Libraries',
+ 'Topic :: System :: Networking'
+ ],
+ )