Dne 24.10.2013 11:46, Harriv napsal(a):
>
>
> I don't need main thread to be responsive, I want to read the data as
> soon as possible. It's possible to control the tracing from command line
> or another application, or I can use multiprocessing module to help.
>
> How to do that? How to get data before trace has stopped?
>
> It's probably possible to pipe the output of fbtracemgr to Python
> program, but I'm still interested how to do it with plain Python program.

You were on right track with svc.readline(), as it returns with data if 
there are any trace data at server. If it do not returns, then there are 
no data which means that no events happen in database that match your 
trace config. If you're sure it should report something, then check your 
trace config as problem is most likely there.

If you want to read everything that trace session returns immediately as 
it's available, use simple loop over service (service object acts 
similarly like file object here), for example:

svc = fdb.sevices.connect(...)
for line in svc:
   print line

However, it never stops looping until trace session is canceled by other 
means.

Here is sample script that traces all SELECT statements in given 
database and shows information when select finishes:

import fdb
import argparse
import os

def main():

     parser = argparse.ArgumentParser(description="Tool to analyze index 
usage.")

     parser.add_argument('database',
                         help="Full path to database.")
     parser.add_argument('-o','--host',
                         help="Server host.")
     parser.add_argument('-u','--user',
                         default=os.environ.get('ISC_USER', 'sysdba'),
                         help="User name")
     parser.add_argument('-p','--password',
                         default=os.environ.get('ISC_PASSWORD', None),
                         help="User password")

     args = parser.parse_args()

     # We need password
     if not args.password:
         print "A password is required to use the Services Manager."
         print
         parser.print_help()
         return

     trace_config = """<database %s>
   enabled true
   log_statement_finish true
   print_plan true
   include_filter %%SELECT%%
   exclude_filter %%RDB$%%
   time_threshold 0
   max_sql_length 2048
</database>
"""
     try:
         if args.host:
             svc_host = args.host + ':service_mgr'
         else:
             svc_host = 'service_mgr'
         svc = 
fdb.services.connect(host=svc_host,user=args.user,password=args.password)

         trace_id = svc.trace_start(config=trace_config % args.database)
         trace_start = datetime.datetime.now()
         print "Trace session %i started." % trace_id
     except Exception as e:
         print e
         exit

     print "Use tracex.py to stop this trace session."

     try:
         for line in svc:
             print line
     except Exception as e:
         print 'Trace ended with exception:\n%s\n' % str(e)
     else:
         print "Trace session stopped"

     svc.close()


if __name__ == '__main__':
     main()

To control trace services you can use next script (tracex.py mentioned 
in previous one):

import fdb
import argparse
import os

def main():

     parser = argparse.ArgumentParser(description="Tool to manage trace 
sessions")

     parser.add_argument('-o','--host',
                         help="Server host.")
     parser.add_argument('-u','--user',
                         default=os.environ.get('ISC_USER', 'sysdba'),
                         help="User name")
     parser.add_argument('-p','--password',
                         default=os.environ.get('ISC_PASSWORD', None),
                         help="User password")
     parser.add_argument('-l','--list', action='store_true',
                         help="List trace sessions.")
     parser.add_argument('-s','--suspend', type=int, metavar='SESSION_ID',
                         help="Pause trace # session.")
     parser.add_argument('-r','--resume', type=int, metavar='SESSION_ID',
                         help="resume trace # session.")
     parser.add_argument('-c','--cancel', type=int, metavar='SESSION_ID',
                         help="cancel trace # session.")

     args = parser.parse_args()

     if not args.password:
         print "A password is required to use the Services Manager."
         print
         parser.print_help()
         return

     if args.host:
         svc_host = args.host + ':service_mgr'
     else:
         svc_host = 'service_mgr'
     svc = 
fdb.services.connect(host=svc_host,user=args.user,password=args.password)

     if args.list:
         sessions = svc.trace_list()
         if len(sessions.keys()) == 0:
             print "No trace sessions."
         else:
             for sid, data in sessions.items():
                 print "Trace session %i" % sid
                 if data.has_key('name'):
                     print "  name:", data['name']
                 print "  date:", data['date'].strftime('%Y-%m-%d %H:%M:%S')
                 print "  user:", data['user']
                 print " flags:", ', '.join(data['flags'])
     elif args.suspend:
         try:
             print svc.trace_suspend(args.suspend)
         except Exception as e:
             print "ERROR:"
             print e.args
     elif args.resume:
         try:
             print svc.trace_resume(args.resume)
         except Exception as e:
             print "ERROR:"
             print e.args
     elif args.cancel:
         try:
             print svc.trace_stop(args.cancel)
         except Exception as e:
             print "ERROR:"
             print e.args


if __name__ == '__main__':
     main()

best regards
Pavel Cisar
IBPhoenix


Reply via email to