2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
21 * ServiceTracker is a utility class for logging and timing service
22 * calls to a fb303 Thrift server. Currently, ServiceTracker offers
23 * the following features:
25 * . Logging of service method start, end (and duration), and
26 * optional steps in between.
28 * . Automatic check of server status via fb303::getStatus()
29 * with a ServiceException thrown if server not alive
32 * . A periodic logged checkpoint reporting lifetime time, lifetime
33 * service count, and per-method statistics since the last checkpoint
34 * time (at method finish).
36 * . Export of fb303 counters for lifetime and checkpoint statistics
39 * . For TThreadPoolServers, a logged warning when all server threads
40 * are busy (at method start). (Must call setThreadManager() after
41 * ServiceTracker instantiation for this feature to be enabled.)
43 * Individual features may be enabled or disabled by arguments to the
44 * constructor. The constructor also accepts a pointer to a logging
45 * method -- if no pointer is passed, the tracker will log to stdout.
47 * ServiceTracker defines private methods for service start, finish,
48 * and step, which are designed to be accessed by instantiating a
49 * friend ServiceMethod object, as in the following example:
51 * #include <ServiceTracker.h>
52 * class MyServiceHandler : virtual public MyServiceIf,
53 * public facebook::fb303::FacebookBase
56 * MyServiceHandler::MyServiceHandler() : mServiceTracker(this) {}
57 * void MyServiceHandler::myServiceMethod(int userId) {
58 * // note: Instantiating a ServiceMethod object starts a timer
59 * // and tells the ServiceTracker to log the start. Might throw
60 * // a ServiceException.
61 * ServiceMethod serviceMethod(&mServiceTracker,
65 * // note: Calling the step method tells the ServiceTracker to
66 * // log the step, with a time elapsed since start.
67 * serviceMethod.step("post parsing, begin processing");
69 * // note: When the ServiceMethod object goes out of scope, the
70 * // ServiceTracker will log the total elapsed time of the method.
74 * ServiceTracker mServiceTracker;
77 * The step() method call is optional; the startService() and
78 * finishService() methods are handled by the object's constructor and
81 * The ServiceTracker is (intended to be) thread-safe.
85 * . Come up with something better for logging than passing a
86 * function pointer to the constructor.
88 * . Add methods for tracking errors from service methods, e.g.
89 * ServiceTracker::reportService().
92 #ifndef SERVICETRACKER_H
93 #define SERVICETRACKER_H
101 #include <boost/shared_ptr.hpp>
103 #include <thrift/concurrency/Mutex.h>
106 namespace apache
{ namespace thrift
{ namespace concurrency
{
111 namespace facebook
{ namespace fb303
{
121 enum Unit
{ UNIT_SECONDS
, UNIT_MILLISECONDS
, UNIT_MICROSECONDS
};
123 uint64_t elapsedUnits(Unit unit
, std::string
*label
= NULL
) const;
132 friend class ServiceMethod
;
136 static uint64_t CHECKPOINT_MINIMUM_INTERVAL_SECONDS
;
137 static int LOG_LEVEL
;
139 ServiceTracker(facebook::fb303::FacebookBase
*handler
,
140 void (*logMethod
)(int, const std::string
&)
141 = &ServiceTracker::defaultLogMethod
,
142 bool featureCheckpoint
= true,
143 bool featureStatusCheck
= true,
144 bool featureThreadCheck
= true,
145 Stopwatch::Unit stopwatchUnit
146 = Stopwatch::UNIT_MILLISECONDS
);
148 void setThreadManager(boost::shared_ptr
<apache::thrift::concurrency::ThreadManager
> threadManager
);
152 facebook::fb303::FacebookBase
*handler_
;
153 void (*logMethod_
)(int, const std::string
&);
154 boost::shared_ptr
<apache::thrift::concurrency::ThreadManager
> threadManager_
;
156 bool featureCheckpoint_
;
157 bool featureStatusCheck_
;
158 bool featureThreadCheck_
;
159 Stopwatch::Unit stopwatchUnit_
;
161 apache::thrift::concurrency::Mutex statisticsMutex_
;
162 time_t checkpointTime_
;
163 uint64_t checkpointServices_
;
164 uint64_t checkpointDuration_
;
165 std::map
<std::string
, std::pair
<uint64_t, uint64_t> > checkpointServiceDuration_
;
167 void startService(const ServiceMethod
&serviceMethod
);
168 int64_t stepService(const ServiceMethod
&serviceMethod
,
169 const std::string
&stepName
);
170 void finishService(const ServiceMethod
&serviceMethod
);
171 void reportCheckpoint();
172 static void defaultLogMethod(int level
, const std::string
&message
);
178 friend class ServiceTracker
;
180 ServiceMethod(ServiceTracker
*tracker
,
181 const std::string
&name
,
182 const std::string
&signature
,
183 bool featureLogOnly
= false);
184 ServiceMethod(ServiceTracker
*tracker
,
185 const std::string
&name
,
187 bool featureLogOnly
= false);
189 uint64_t step(const std::string
&stepName
);
191 ServiceTracker
*tracker_
;
193 std::string signature_
;
194 bool featureLogOnly_
;
199 class ServiceException
: public std::exception
202 explicit ServiceException(const std::string
&message
, int code
= 0)
203 : message_(message
), code_(code
) {}
204 ~ServiceException() throw() {}
205 virtual const char *what() const throw() { return message_
.c_str(); }
206 int code() const throw() { return code_
; }
208 std::string message_
;
213 }} // facebook::fb303