Subversion Repositories SmartDukaan

Rev

Rev 30 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
30 ashish 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 "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