Taking trace () to the next level ...

"H.Merijn Brand" <[email protected]>
Newsgroups gmane.comp.lang.perl.modules.dbi.sybase.devel
Message-ID <[email protected]>
I've had a series of discussions with several DBD authors and others
because I wanted to get better support for Driver-side trace message
handling in a portable way.

My DBD::Unify supports $dbh->{dbd_verbose} since a *long* time, and Tim
never saw the generic value of that, but now that John Scoles has used
it for himself in DBD::Oracle and others showed interest too, it might
be well worth to take the discussion to a wider board.

Here's a summary, '»' marked lines are proposed additions/changes. I
hope I interpreted all opinions correctly.

DBI

	$h->trace ($trace_setting [, $output ]);

   $h may be 'DBI'

   $trace_setting is a (combined) flag, which supports

	1..15	Simple debug level
	"SQL"	All SQL statements executed (not yet implemented)
	"ALL"	All DBI *and* Driver flags
»	"DBD"	All Driver flags

»	   $h->trace ("DBD=7") could be an alternative to set the level

	"1|pglib"	Combinations of a DBI debug level and driver
			flags, which have to be parsed by
			parse_trace_flags ()
»	"1|4"		Combination of a DBI debug level and a
			driver debug level
»	"|4"		Driver-side only debug level, will NOT
			alter the current DBI debug level

	$trace_setting can be stored in $ENV{DBI_TRACE}
»	Driver side $trace_settings can be stored in $ENV{DBD_TRACE}
	(note that this /was/ DBD_VERBOSE in previous discussions, but
	DBD_TRACE is more in line with the above)

	#define DBIc_TRACE_LEVEL_MASK   0x0000000F
	#define DBIc_TRACE_FLAGS_MASK   0xFFFFFF00

	Is 0x00000000F0 supposed to be the Driver *level* mask?

   $output can be a filename or an output handle. The latter is very
   nice in combination with perlIO

	my $trace = "";
	open my $th, ">", \$trace;
	$dbh->trace (4, $th);
	...
	$dbh->trace (0);
	# Trace log now in $trace;

   Handles can get there own (inherited) $trace_setting using the

	$h->{TraceLevel}  = "2|14";
»	$h->{dbd_verbose} = 4;

»  the dbd_verbose attribute is internally implemented as uni_verbose,
»  pg_verbose, ora_verbose, ... but offers a generic alias to
»  dbd_verbose, so that writing cross-database portable scripts will be
»  much easier.

There is no policy regarding DBD tracing. DBD::Unify uses a trace
*level*, which is by default inherited from dbis->debug (XS), but
DBD::Pg uses flags

DBI - Uses trace *level* (flags SQL or ALL set all)
  0 - Trace disabled.
  1 - Trace top-level DBI method calls returning with results or errors.
  2 - As above, adding tracing of top-level method entry with parameters.
  3 - As above, adding some high-level information from the driver
      and some internal information from the DBI.
  4 - As above, adding more detailed information from the driver.
      This is the first level to trace all the rows being fetched.
  5 to 15 - As above but with more and more internal information.

DBD::Unify - Uses trace *level*
  0 - Trace disabled
  1 - No messages defined (yet)
  2 - Level 1 plus main method entry and exit points:
  3 - Level 2 plus errors and additional return codes and field types
      and values:
  4 - Level 3 plus some content info:
  5 - Level 4 plus internal coding for exchanges and low(er) level
      return codes:
  6 - Level 5 plus destroy/cleanup states:
  7 - No messages (yet) set to level 7 and up.

DBD::Oracle - Uses trace *level*
  Uses level 1..6, but does not document what the output is

DBD::Pg - uses trace *flags* AND *level* from DBI. Level 4 or higher
	  sets all flags
  pglibpq	- Outputs the name of each libpq function (without
		  arguments) immediately before running it.
  pgstart	- Outputs the name of each internal DBD::Pg function,
		  and other information such as the function arguments
		  or important global variables, as each function starts
  pgend		- Outputs a simple message at the very end of
		  each internal DBD::Pg function.
  pgprefix	- Forces each line of trace output to begin with the
		  string "dbdpg: "
  pglogin	- Outputs a message showing the connection string
		  right before a new database connection is attempted
		  (on with level 5 or up)

DBD::MySQL - Cannot find anything in the docs about tracing

DBD::ODBC - Only supports one trace flag
  odbcdev	- flag is used to output development tracing so it
		  should not be relevant in normal use.
  DBD::ODBC outputs tracing at levels 3 and above (as levels 1 and 2
  are reserved for DBI).

Where is it stated that levels 1 and 2 are DBI only?

All of the people I talked to agree that is is often useful to see
Driver-only tracing/debugging, as by now we do trust that DBI is Doing
The Right Thing (TM)

The problem with the current definition of the trace_flags, is that,
even though most drivers still work with a trace *level*, it only
supports trace *flags*. My implementation and suggestion of
$h->{dbd_verbose} is a nice workaround to start with, but it would be
easier to lift it to the trace method, so that Driver-only tracing is
more standardized

http://search.cpan.org/~timb/DBI-1.607/lib/DBI/DBD.pm#Other_database_handle_methods

-- 
H.Merijn Brand          Amsterdam Perl Mongers  http://amsterdam.pm.org/
using & porting perl 5.6.2, 5.8.x, 5.10.x, 5.11.x on HP-UX 10.20, 11.00,
11.11, 11.23, and 11.31, SuSE 10.1, 10.2, and 10.3, AIX 5.2, and Cygwin.
http://mirrors.develooper.com/hpux/           http://www.test-smoke.org/
http://qa.perl.org      http://www.goldmark.org/jeff/stupid-disclaimers/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.