simperf_proc_interface.py
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:7k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. #!/usr/bin/python
  2. """
  3. @file simperf_proc_interface.py
  4. @brief Utility to extract log messages from *.<pid>.llsd files containing performance statistics.
  5. $LicenseInfo:firstyear=2008&license=mit$
  6. Copyright (c) 2008-2010, Linden Research, Inc.
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. $/LicenseInfo$
  23. """
  24. # ----------------------------------------------------
  25. # Utility to extract log messages from *.<pid>.llsd
  26. # files that contain performance statistics.
  27. # ----------------------------------------------------
  28. import sys, os
  29. if os.path.exists("setup-path.py"):
  30.     execfile("setup-path.py")
  31. from indra.base import llsd
  32. DEFAULT_PATH="/dev/shm/simperf/"
  33. # ----------------------------------------------------
  34. # Pull out the stats and return a single document
  35. def parse_logfile(filename, target_column=None, verbose=False):
  36.     full_doc = []
  37.     # Open source temp log file.  Let exceptions percolate up.
  38.     sourcefile = open( filename,'r')
  39.         
  40.     if verbose:
  41.         print "Reading " + filename  
  42.     
  43.     # Parse and output all lines from the temp file
  44.     for line in sourcefile.xreadlines():
  45.         partial_doc = llsd.parse(line)
  46.         if partial_doc is not None:
  47.             if target_column is None:
  48.                 full_doc.append(partial_doc)
  49.             else:
  50.                 trim_doc = { target_column: partial_doc[target_column] }
  51.                 if target_column != "fps":
  52.                     trim_doc[ 'fps' ] = partial_doc[ 'fps' ]
  53.                 trim_doc[ '/total_time' ] = partial_doc[ '/total_time' ]
  54.                 trim_doc[ 'utc_time' ] = partial_doc[ 'utc_time' ]
  55.                 full_doc.append(trim_doc)
  56.     sourcefile.close()
  57.     return full_doc
  58. # Extract just the meta info line, and the timestamp of the first/last frame entry.
  59. def parse_logfile_info(filename, verbose=False):
  60.     # Open source temp log file.  Let exceptions percolate up.
  61.     sourcefile = open(filename, 'rU') # U is to open with Universal newline support
  62.         
  63.     if verbose:
  64.         print "Reading " + filename  
  65.     # The first line is the meta info line.
  66.     info_line = sourcefile.readline()
  67.     if not info_line:
  68.         sourcefile.close()
  69.         return None
  70.     # The rest of the lines are frames.  Read the first and last to get the time range.
  71.     info = llsd.parse( info_line )
  72.     info['start_time'] = None
  73.     info['end_time'] = None
  74.     first_frame = sourcefile.readline()
  75.     if first_frame:
  76.         try:
  77.             info['start_time'] = int(llsd.parse(first_frame)['timestamp'])
  78.         except:
  79.             pass
  80.     # Read the file backwards to find the last two lines.
  81.     sourcefile.seek(0, 2)
  82.     file_size = sourcefile.tell()
  83.     offset = 1024
  84.     num_attempts = 0
  85.     end_time = None
  86.     if file_size < offset:
  87.         offset = file_size
  88.     while 1:
  89.         sourcefile.seek(-1*offset, 2)
  90.         read_str = sourcefile.read(offset)
  91.         # Remove newline at the end
  92.         if read_str[offset - 1] == 'n':
  93.             read_str = read_str[0:-1]
  94.         lines = read_str.split('n')
  95.         full_line = None
  96.         if len(lines) > 2:  # Got two line
  97.             try:
  98.                 end_time = llsd.parse(lines[-1])['timestamp']
  99.             except:
  100.                 # We couldn't parse this line.  Try once more.
  101.                 try:
  102.                     end_time = llsd.parse(lines[-2])['timestamp']
  103.                 except:
  104.                     # Nope.  Just move on.
  105.                     pass
  106.             break
  107.         if len(read_str) == file_size:   # Reached the beginning
  108.             break
  109.         offset += 1024
  110.     info['end_time'] = int(end_time)
  111.     sourcefile.close()
  112.     return info
  113.     
  114. def parse_proc_filename(filename):
  115.     try:
  116.         name_as_list = filename.split(".")
  117.         cur_stat_type = name_as_list[0].split("_")[0]
  118.         cur_pid = name_as_list[1]
  119.     except IndexError, ValueError:
  120.         return (None, None)
  121.     return (cur_pid, cur_stat_type)
  122. # ----------------------------------------------------
  123. def get_simstats_list(path=None):
  124.     """ Return stats (pid, type) listed in <type>_proc.<pid>.llsd """
  125.     if path is None:
  126.         path = DEFAULT_PATH
  127.     simstats_list = []
  128.     for file_name in os.listdir(path):
  129.         if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd":
  130.             simstats_info = parse_logfile_info(path + file_name)
  131.             if simstats_info is not None:
  132.                 simstats_list.append(simstats_info)
  133.     return simstats_list
  134. def get_log_info_list(pid=None, stat_type=None, path=None, target_column=None, verbose=False):
  135.     """ Return data from all llsd files matching the pid and stat type """
  136.     if path is None:
  137.         path = DEFAULT_PATH
  138.     log_info_list = {}
  139.     for file_name in os.listdir ( path ):
  140.         if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd":
  141.             (cur_pid, cur_stat_type) = parse_proc_filename(file_name)
  142.             if cur_pid is None:
  143.                 continue
  144.             if pid is not None and pid != cur_pid:
  145.                 continue
  146.             if stat_type is not None and stat_type != cur_stat_type:
  147.                 continue
  148.             log_info_list[cur_pid] = parse_logfile(path + file_name, target_column, verbose)
  149.     return log_info_list
  150. def delete_simstats_files(pid=None, stat_type=None, path=None):
  151.     """ Delete *.<pid>.llsd files """
  152.     if path is None:
  153.         path = DEFAULT_PATH
  154.     del_list = []
  155.     for file_name in os.listdir(path):
  156.         if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd":
  157.             (cur_pid, cur_stat_type) = parse_proc_filename(file_name)
  158.             if cur_pid is None:
  159.                 continue
  160.             if pid is not None and pid != cur_pid:
  161.                 continue
  162.             if stat_type is not None and stat_type != cur_stat_type:
  163.                 continue
  164.             del_list.append(cur_pid)
  165.             # Allow delete related exceptions to percolate up if this fails.
  166.             os.unlink(os.path.join(DEFAULT_PATH, file_name))
  167.     return del_list