]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/thrift/contrib/fb303/cpp/ServiceTracker.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / jaegertracing / thrift / contrib / fb303 / cpp / ServiceTracker.h
1 /*
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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
17 * under the License.
18 */
19
20 /**
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:
24 *
25 * . Logging of service method start, end (and duration), and
26 * optional steps in between.
27 *
28 * . Automatic check of server status via fb303::getStatus()
29 * with a ServiceException thrown if server not alive
30 * (at method start).
31 *
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).
35 *
36 * . Export of fb303 counters for lifetime and checkpoint statistics
37 * (at method finish).
38 *
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.)
42 *
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.
46 *
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:
50 *
51 * #include <ServiceTracker.h>
52 * class MyServiceHandler : virtual public MyServiceIf,
53 * public facebook::fb303::FacebookBase
54 * {
55 * public:
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,
62 * "myServiceMethod",
63 * userId);
64 * ...
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");
68 * ...
69 * // note: When the ServiceMethod object goes out of scope, the
70 * // ServiceTracker will log the total elapsed time of the method.
71 * }
72 * ...
73 * private:
74 * ServiceTracker mServiceTracker;
75 * }
76 *
77 * The step() method call is optional; the startService() and
78 * finishService() methods are handled by the object's constructor and
79 * destructor.
80 *
81 * The ServiceTracker is (intended to be) thread-safe.
82 *
83 * Future:
84 *
85 * . Come up with something better for logging than passing a
86 * function pointer to the constructor.
87 *
88 * . Add methods for tracking errors from service methods, e.g.
89 * ServiceTracker::reportService().
90 */
91
92 #ifndef SERVICETRACKER_H
93 #define SERVICETRACKER_H
94
95
96 #include <iostream>
97 #include <string>
98 #include <sstream>
99 #include <exception>
100 #include <map>
101 #include <boost/shared_ptr.hpp>
102
103 #include <thrift/concurrency/Mutex.h>
104
105
106 namespace apache { namespace thrift { namespace concurrency {
107 class ThreadManager;
108 }}}
109
110
111 namespace facebook { namespace fb303 {
112
113
114 class FacebookBase;
115 class ServiceMethod;
116
117
118 class Stopwatch
119 {
120 public:
121 enum Unit { UNIT_SECONDS, UNIT_MILLISECONDS, UNIT_MICROSECONDS };
122 Stopwatch();
123 uint64_t elapsedUnits(Unit unit, std::string *label = NULL) const;
124 void reset();
125 private:
126 timeval startTime_;
127 };
128
129
130 class ServiceTracker
131 {
132 friend class ServiceMethod;
133
134 public:
135
136 static uint64_t CHECKPOINT_MINIMUM_INTERVAL_SECONDS;
137 static int LOG_LEVEL;
138
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);
147
148 void setThreadManager(boost::shared_ptr<apache::thrift::concurrency::ThreadManager> threadManager);
149
150 private:
151
152 facebook::fb303::FacebookBase *handler_;
153 void (*logMethod_)(int, const std::string &);
154 boost::shared_ptr<apache::thrift::concurrency::ThreadManager> threadManager_;
155
156 bool featureCheckpoint_;
157 bool featureStatusCheck_;
158 bool featureThreadCheck_;
159 Stopwatch::Unit stopwatchUnit_;
160
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_;
166
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);
173 };
174
175
176 class ServiceMethod
177 {
178 friend class ServiceTracker;
179 public:
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,
186 uint64_t id,
187 bool featureLogOnly = false);
188 ~ServiceMethod();
189 uint64_t step(const std::string &stepName);
190 private:
191 ServiceTracker *tracker_;
192 std::string name_;
193 std::string signature_;
194 bool featureLogOnly_;
195 Stopwatch timer_;
196 };
197
198
199 class ServiceException : public std::exception
200 {
201 public:
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_; }
207 private:
208 std::string message_;
209 int code_;
210 };
211
212
213 }} // facebook::fb303
214
215 #endif