HCE Project Python language Distributed Tasks Manager Application, Distributed Crawler Application and client API bindings.  2.0.0-chaika
Hierarchical Cluster Engine Python language binding
Profiler.py
Go to the documentation of this file.
1 '''
2 Implementation class HCEProfiler for python bindings to HCE cluster node.
3 
4 @package: hce
5 @file Profiler.py
6 @author Alexander Vybornyh <alexander.hce.cluster@gmail.com>
7 @link: http://hierarchical-cluster-engine.com/
8 @copyright: Copyright &copy; 2013-2015 IOIX Ukraine
9 @license: http://hierarchical-cluster-engine.com/license/
10 @since: 0.1
11 '''
12 
13 
14 import sys
15 import cProfile
16 import pstats
17 import StringIO
18 import ConfigParser
19 import logging.config
20 import argparse
21 
22 import app.Consts as APP_CONSTS
23 import app.Utils as Utils
24 # For traceback
25 from app.Utils import tracefunc
26 
27 # List of strings to be appended in to the final message for profiler records
28 messagesList = []
29 
30 
31 
32 class Profiler(object):
33 
34 
35  MSG_ERROR_PARSE_CMD_PARAMS = "Error parse command line parameters."
36  MSG_ERROR_EMPTY_CONFIG_FILE_NAME = "Config file name is empty."
37  MSG_ERROR_WRONG_CONFIG_FILE_NAME = "Config file name is wrong"
38  MSG_ERROR_LOAD_APP_CONFIG = "Error loading application config file."
39  MSG_ERROR_READ_LOG_CONFIG = "Error read log config file."
40  MSG_ERROR_WRONG_CONFIG_OPTION = "Wrong format option"
41  MSG_ERROR_WRONG__OPTION_SORTBY = "Read wrong value of 'sortby' from config"
42 
43 
44  PROFILER_OPTION_LOG = "log"
45  PROFILER_OPTION_STATUS = "profile"
46  PROFILER_OPTION_SORTBY = "sortby"
47  PROFILER_OPTION_LIMIT = "limit"
48  PROFILER_OPTION_TRACEBACK = "traceback"
49  PROFILER_OPTION_TRACEBACK_LOGGER_MODE = "tracebackLoggerMode"
50 
51 
52  PROFILER_OPTION_STATUS_DEFAULT = 0
53  PROFILER_OPTION_SORTBY_DEFAULT = "cumulative"
54  PROFILER_OPTION_LIMIT_DEFAULT = 1.0
55  PROFILER_OPTION_TRACEBACK_DEFAULT = 0
56  PROFILER_OPTION_TRACEBACK_LOGGER_MODE_DEFAULT = 1
57 
58 
59  PROFILER_OPTION_SORTBY_ALLOWED_LIST = ['stdname', 'calls', 'time', 'cumulative']
60 
61 
62  MESSAGES_ITEMS_DELIMITER = ","
63 
64 
65  tracebackOptions = {'tracebackIdent':Utils.tracebackIdent,
66  'tracebackIdentFiller':Utils.tracebackIdentFiller,
67  'tracebackMessageCall':Utils.tracebackMessageCall,
68  'tracebackMessageExit':Utils.tracebackMessageExit,
69  'tracebackmessageDelimiter':Utils.tracebackmessageDelimiter,
70  'tracebackTimeMark':Utils.tracebackTimeMark,
71  'tracebackTimeMarkFormat':Utils.tracebackTimeMarkFormat,
72  'tracebackTimeMarkDelimiter':Utils.tracebackTimeMarkDelimiter,
73  'tracebackIncludeInternalCalls':Utils.tracebackIncludeInternalCalls,
74  'tracebackIncludeLineNumber':Utils.tracebackIncludeLineNumber,
75  'tracebackIncludeLineNumberDelimiter':Utils.tracebackIncludeLineNumberDelimiter,
76  'tracebackIncludeFileNumber':Utils.tracebackIncludeFileNumber,
77  'tracebackIncludeFileNumberDelimiter':Utils.tracebackIncludeFileNumberDelimiter,
78  'tracebackFunctionNameDelimiter':Utils.tracebackFunctionNameDelimiter,
79  'tracebackExcludeModulePath':Utils.tracebackExcludeModulePath,
80  'tracebackExcludeFunctionName':Utils.tracebackExcludeFunctionName,
81  'tracebackExcludeFunctionNameStarts':Utils.tracebackExcludeFunctionNameStarts,
82  'tracebackIncludeExitCalls':Utils.tracebackIncludeExitCalls,
83  'tracebackRecursionlimit':Utils.tracebackRecursionlimit,
84  'tracebackRecursionlimitErrorMsg':Utils.tracebackRecursionlimitErrorMsg,
85  'tracebackIncludeLocals':Utils.tracebackIncludeLocals,
86  'tracebackIncludeArg':Utils.tracebackIncludeArg,
87  'tracebackIncludeLocalsPrefix':Utils.tracebackIncludeLocalsPrefix,
88  'tracebackIncludeArgPrefix':Utils.tracebackIncludeArgPrefix,
89  'tracebackElapsedTimeDelimiter':Utils.tracebackElapsedTimeDelimiter,
90  'tracebackElapsedTimeFormat':Utils.tracebackElapsedTimeFormat,
91  'tracebackUnknownExceptionMsg':Utils.tracebackUnknownExceptionMsg}
92 
93 
94  def __init__(self):
95  '''
96  Constructor
97  '''
98  self.parser = None
99  self.logger = None
100  self.isStarted = False
106  self.errorMsg = ""
107  #create instance of profiler
108  self.pr = cProfile.Profile()
109  try:
110  #load configuration files and initialization
111  self.__loadAppConfig(self.__parseParams())
112  except Exception, err:
113  self.errorMsg = str(err)
115 
116  if self.traceback > 0:
117  #used self.tracebackLoggerMode already reinit from config
118  if self.tracebackLoggerMode > 0 and Utils.tracebackLogger is None:
119  Utils.tracebackLogger = Utils.MPLogger().getLogger(APP_CONSTS.LOGGER_NAME_TRACEBACK)
120 
121  sys.settrace(tracefunc)
122 
123 
124 
129  def __initTrackbackOptions(self, config, section):
130 
131  for key, value in self.tracebackOptions.items():
132  opt = Utils.getConfigParameter(config, section, key, value)
133 
134  if opt and opt != value:
135  try:
136  exec('Utils.' + str(key) + '=' + str(opt)) # pylint: disable=W0122
137  except Exception:
138  raise Exception(self.MSG_ERROR_WRONG_CONFIG_OPTION + ': ' + str(key))
139 
140 
141 
145  def __loadAppConfig(self, configName):
146  #variable for result
147  confLogFileName = ""
148 
149  try:
150  config = ConfigParser.ConfigParser()
151  config.optionxform = str
152 
153  readOk = config.read(configName)
154 
155  if len(readOk) == 0:
156  raise Exception(self.MSG_ERROR_WRONG_CONFIG_FILE_NAME + ": " + configName)
157 
158  if config.has_section(APP_CONSTS.CONFIG_APPLICATION_SECTION_NAME):
159  confLogFileName = str(config.get(APP_CONSTS.CONFIG_APPLICATION_SECTION_NAME, self.PROFILER_OPTION_LOG))
160 
161  if config.has_section(APP_CONSTS.CONFIG_PROFILER_SECTION_NAME):
162  self.status = int(config.get(APP_CONSTS.CONFIG_PROFILER_SECTION_NAME, self.PROFILER_OPTION_STATUS))
163  self.sortby = str(config.get(APP_CONSTS.CONFIG_PROFILER_SECTION_NAME, self.PROFILER_OPTION_SORTBY))
164  self.limit = float(config.get(APP_CONSTS.CONFIG_PROFILER_SECTION_NAME, self.PROFILER_OPTION_LIMIT))
165  self.traceback = int(config.get(APP_CONSTS.CONFIG_PROFILER_SECTION_NAME, self.PROFILER_OPTION_TRACEBACK))
166  if self.traceback > 0:
167  self.__initTrackbackOptions(config, APP_CONSTS.CONFIG_PROFILER_SECTION_NAME)
168  if config.has_option(APP_CONSTS.CONFIG_PROFILER_SECTION_NAME, self.PROFILER_OPTION_TRACEBACK_LOGGER_MODE):
169  self.tracebackLoggerMode = int(Utils.getConfigParameter(config, APP_CONSTS.CONFIG_PROFILER_SECTION_NAME,
172  else:
173  pass
174  else:
175  pass
176 
177  except Exception, err:
178  raise Exception(self.MSG_ERROR_LOAD_APP_CONFIG + ' ' + str(err))
179 
180  if self.sortby not in self.PROFILER_OPTION_SORTBY_ALLOWED_LIST:
181  raise Exception(self.MSG_ERROR_WRONG__OPTION_SORTBY)
182 
183  return confLogFileName
184 
185 
186 
190  def readConfig(self, configName):
191  try:
192  if isinstance(configName, str) and len(configName) == 0:
193  raise Exception(self.MSG_ERROR_EMPTY_CONFIG_FILE_NAME)
194 
195  logging.config.fileConfig(configName)
196  #call rotation log files and initialization logger
197  self.logger = Utils.MPLogger().getLogger()
198 
199  except Exception, err:
200  raise Exception(self.MSG_ERROR_READ_LOG_CONFIG + ' ' + str(err))
201 
202 
203 
206  def __parseParams(self):
207  configName = ""
208  try:
209  self.parser = argparse.ArgumentParser(description='Process command line arguments.', add_help=False)
210  self.parser.add_argument('-c', '--config', action='store', metavar='config_file', help='config ini-file')
211 
212  args = self.parser.parse_known_args()
213 
214  if args is None or args[0] is None or args[0].config is None:
215  raise Exception(self.MSG_ERROR_EMPTY_CONFIG_FILE_NAME)
216 
217  configName = str(args[0].config)
218 
219  except Exception, err:
220  raise Exception(self.MSG_ERROR_PARSE_CMD_PARAMS + ' ' + str(err))
221 
222  return configName
223 
224 
225 
228  def start(self):
229  if self.isStarted is False:
230  self.pr.enable()
231  self.isStarted = True
232 
233 
234 
237  def stop(self):
238  msgStr = self.MESSAGES_ITEMS_DELIMITER.join(messagesList)
239 
240  if self.isStarted is True and self.status > 0:
241  self.isStarted = False
242  self.pr.disable()
243  s = StringIO.StringIO()
244  ps = pstats.Stats(self.pr, stream=s).sort_stats(self.sortby)
245  ps.print_stats(self.limit)
246 
247  #call rotation log files
248  self.logger = Utils.MPLogger().getLogger(APP_CONSTS.LOGGER_NAME_PROFILER)
249  #dump profile information to log
250  if self.logger:
251  self.logger.debug("%s\n%s", msgStr, str(s.getvalue()))
252  self.logger.debug("%s", APP_CONSTS.LOGGER_DELIMITER_LINE)
253 
254  if self.traceback > 0:
255  if Utils.tracebackLogger is None:
256  #call rotation log files
257  self.logger = Utils.MPLogger().getLogger(APP_CONSTS.LOGGER_NAME_TRACEBACK)
258  #dump traceback information to log
259  if self.logger:
260  self.logger.debug("%s\n%s", msgStr, "\n".join(Utils.tracebackList))
261  self.logger.debug("%s", APP_CONSTS.LOGGER_DELIMITER_LINE)
262 
string PROFILER_OPTION_TRACEBACK_LOGGER_MODE
Definition: Profiler.py:49
def __init__(self)
constructor
Definition: Profiler.py:94
def __loadAppConfig(self, configName)
load application config file
Definition: Profiler.py:145
string PROFILER_OPTION_LIMIT
Definition: Profiler.py:47
def readConfig(self, configName)
load log config file of prifiler
Definition: Profiler.py:190
def __initTrackbackOptions(self, config, section)
initialize traceback options from config file
Definition: Profiler.py:129
string MSG_ERROR_READ_LOG_CONFIG
Definition: Profiler.py:39
string PROFILER_OPTION_SORTBY
Definition: Profiler.py:46
dictionary tracebackOptions
Constans traceback config options (key - options name, value - default.
Definition: Profiler.py:65
def __parseParams(self)
parsing paramers
Definition: Profiler.py:206
string PROFILER_OPTION_TRACEBACK
Definition: Profiler.py:48
string PROFILER_OPTION_LOG
Constans profiler options read from config.
Definition: Profiler.py:44
string MSG_ERROR_WRONG_CONFIG_FILE_NAME
Definition: Profiler.py:37
string MSG_ERROR_PARSE_CMD_PARAMS
Constants error messages used in class.
Definition: Profiler.py:35
int PROFILER_OPTION_STATUS_DEFAULT
Constans default values of profiler options.
Definition: Profiler.py:52
string PROFILER_OPTION_STATUS
Definition: Profiler.py:45
string MSG_ERROR_WRONG__OPTION_SORTBY
Definition: Profiler.py:41
def start(self)
start profiling
Definition: Profiler.py:228
Class which provides functionality for use profiling.
Definition: Profiler.py:32
int PROFILER_OPTION_TRACEBACK_DEFAULT
Definition: Profiler.py:55
int PROFILER_OPTION_TRACEBACK_LOGGER_MODE_DEFAULT
Definition: Profiler.py:56
string MESSAGES_ITEMS_DELIMITER
Constans for global message list of strings in the final message for profiler records.
Definition: Profiler.py:62
float PROFILER_OPTION_LIMIT_DEFAULT
Definition: Profiler.py:54
string MSG_ERROR_LOAD_APP_CONFIG
Definition: Profiler.py:38
list PROFILER_OPTION_SORTBY_ALLOWED_LIST
Constans allowed values of &#39;sortby&#39;.
Definition: Profiler.py:59
Definition: join.py:1
string PROFILER_OPTION_SORTBY_DEFAULT
Definition: Profiler.py:53
string MSG_ERROR_WRONG_CONFIG_OPTION
Definition: Profiler.py:40
string MSG_ERROR_EMPTY_CONFIG_FILE_NAME
Definition: Profiler.py:36
def stop(self)
stop profiling
Definition: Profiler.py:237