[Suggestion for a generic way of...] Debugging the filter chain

pipitas at gmail.com pipitas at gmail.com
Tue Oct 26 12:32:31 PDT 2010


Johannes Meixner wrote on 02:34 Oct 19:
> On Oct 18 12:13 William Pietri wrote (shortened):
> > I see in the logs that it starts a bunch of things (filters bannertops,
> > pstopdf, pdftopdf, cpdftocps, and brlpdwrappermfc6490cw, and the lpd
> > backend). Is there some easy way to me to peek into what's going on
> > there in terms of inputs, arguments called, and outputs?
>
> Do you already use in /etc/cups/cupsd.conf
>    LogLevel debug
> perhaps together with
>    MaxLogSize 0
> (restart the cupsd after changes in its cupsd.conf)?
>
> Regarding input and output data it is a bit more tricky.
> You may exchange step by step each filter binary by a
> selfmade script which writes its input into a file.

...and this selfmade script can be the same for each and every filter, if you implement it the right way. I call it a "proxyfilter".

Years ago, I have done something like this. First time I used it in some tricky customer projects which involved CUPS, and it had to serve as proof of CUPS' innocence for problems which appeared intermittently on a certain printer.

But I don't have the code sticking around any more (I don't even have a Linux system at the moment...)

Basically, what I did consisted of the following steps:

  * Rename the original "filters" directory to "filters.orig"
  * Create an additional "filters.debug" directory
  * Copy all filters from the "filters.orig" to the "filters.debug"
    directory, renaming them to "${origname}.bin"
  * Create a symlink called "filters" pointing to either "filters.orig"
    or "filters.debug" (change symlink as needed)
  * Create a "proxyfilter.sh" wrapper script (written in Bash) inside
    the "filters.debug" directory
  * Inside the "filters.debug" directory, for each filter create
    symlinks named "${origname}" pointing to "proxyfilter.sh"

Remember,...
  ...cupsd calls each filter inside the "filters" directory as needed;
  ...if the currently active "filters" symlink points to "filters.debug",
     it will find all filters ("texttops", "pstops", "pstoraster", etc.)
     pointing to "proxyfilter.sh";
  ...so in reality, "proxyfilter.sh" is called for each filter.

Now the trick is what to put inside the "proxyfilter.sh"? First, "proxyfilter.sh" will have to behave like any filter in the CUPS filtering system. See also "man filter":

  ...correctly process all arguments it sees ($1, $2, $3, $4, $5, $6);
  ...correctly handle the call with zero arguments;
  ...read input file from stdin when called without a $6
     (that is: 'export input="-"' or 'export input="${6}"' as needed) ;
  ...write the proxyfilter's output to stdout;

"proxyfilter.sh" has to evaluate its argument "${0}". From "${0}" it will see under which name it was called. This may be "pstops", "texttops" or whatever.

Next, proxyfilter will not just forward its stdin (or input file) to stdout, but...

 ...it will invoke the real filter, f.e. "${pstops}.bin", on the job,
 ...and it will also use "tee" to direct a copy of stdin to a debug jobfile.

The magic lines to achieve this would be something like

  cat ${input} \
  | ${0}.bin $1 "$2" "$3" $4 "$5" - \
  | tee /tmp/${0}.$$.debugfile

So for every filter invoked by cupsd, you'll find in "/tmp" a file under a name that carries the filtername plus the PID and the ".debugfile" extension.

Of course you can add lots of glitter and beauty and robustness and features to such a proxyfilter (like using a more uniq name for the .debugfile, composed of current date+time, as well as all of what you can read from the commandline (like ${3} == jobtitle, etc... just remember to sanitize some of the characters that may appear in the jobtitle (printing from browsers may use the URL containing forward slashes which wouldn't work in a filename, etc.)

If anyone is enterprising enough, s/he could re-implement such a proxyfilter (with lots of comments how to use it) and publish it somewhere... :-)

Cheers,
pipitas





More information about the cups mailing list