How to add traces to IIS log from PHP

One of the new features added to FastCGI module in IIS 7.5 is ability to use IIS tracing infrastructure from FastCGI applications. This feature request was made by a customer who wanted to consolidate logging of the request processing in one log. All IIS events were present in IIS trace logs but traces generated by PHP applications were separate. So IIS trace log didn’t give a holistic view for PHP applications. ASP.Net already has a way to use IIS traces. So this limitation was specific to PHP. We closed this gap in PHP by providing a way for PHP developers to send traces to IIS using FastCGI’s STDERR stream which are then extracted by FastCGI module and sent to IIS tracing subsystem. This feature has been included in KB 980363 so that this can be made to work on IIS 7.0 as well. On IIS6 and below, these trace messages will be ignored as there is no tracing subsystem available.
FastCGI module parses STDERR stream looking for markers which identify the content as trace messages. Messages starting with “IIS_TRACE_ERROR:” are parsed as errors, “IIS_TRACE_WARNING:” as warnings and “IIS_TRACE_INFO” as info messages. Message end is recognized by marker “:IIS_TRACE_END”. Any function in PHP which can write to STDERR stream can be used to send these traces to FastCGI. So calling error_log(“IIS_TRACE_ERROR:This is an error.:IIS_TRACE_END”) will appear in IIS trace log as an error. Traces appear for CGI trace provider on IIS 7.0 and FastCGI trace provider on IIS 7.5. Trace messages are removed from STDERR stream before STDERR stream content goes through StderrMode logic so that traces don’t disturb existing STDERR behavior. Below is a simple helper class which you can use to generate trace messages.
class IIS_TRACE {
 const NONE    = 0;
 const ERROR   = 1;
 const WARNING = 2;
 const INFO    = 3;
 private static $verbosity = self::NONE;
 private static $traceErrorStart   = "IIS_TRACE_ERROR:";
 private static $traceWarningStart = "IIS_TRACE_WARNING:";
 private static $traceInfoStart    = "IIS_TRACE_INFO:";
 private static $traceEnd          = ":IIS_TRACE_END";
 public static function SetVerbosity ( $verbose )
    if( $verbose != self::NONE    && $verbose != self::ERROR   &&
        $verbose != self::WARNING && $verbose != self::INFO )
        throw new Exception( 'Function SetVerbosity called with invalid value' );
    self::$verbosity = $verbose;
 public static function WriteError ( $msg )
    if (self::$verbosity >= self::ERROR )
        error_log( self::$traceErrorStart . $msg . self::$traceEnd );
 public static function WriteWarning ( $msg )
    if (self::$verbosity >= self::WARNING )
        error_log( self::$traceWarningStart . $msg . self::$traceEnd );
 public static function WriteInfo ( $msg )
    if (self::$verbosity >= self::INFO )
    error_log( self::$traceInfoStart . $msg .self::$traceEnd );
With this class present in your code, you can use WriteInfo, WriteWarning, WriteError functions available in IIS_TRACE class in your code to add traces to IIS trace log as below. When you have tracing enabled, these traces will appear with all other information about request processing.
If($percent > 100)
    IIS_TRACE::WriteError(‘Invalid data provided. Percent = ’ . $percent);
Hope this helps.

Steps to enable tracing using appcmd

Here are the steps you need to enable tracing for a site using appcmd.



1.       Enable tracing for site.
2.       Enable tracing for all request paths and for all response codes.
3.       Appcmd leaves verbosity to default value “warning”. Get the providers count to change verbosity in step 4.
       Change verbosity to verbose for all providers.


@REM Step1
@REM Change site name in the commands if you need to



%windir%\System32\inetsrv\appcmd configure trace "Default Web Site" /enablesite



@REM Step2
@REM Change /statusCodes if you don’t want to enable tracing for all response codes.
@REM Status code range doesn’t work in vista client. Change accordingly.
@REM Use /path to enable tracing for requests to particular file. Eg. /path:*.aspx
@REM Use /timeTaken to enable tracing based on time taken to process request



%windir%\System32\inetsrv\appcmd configure trace "Default Web Site" /enable /statusCodes:100-999 -commit:apphost



@REM Step 3
@REM Change %%V to %V if you are not running in batch mode


%windir%\System32\inetsrv\appcmd list config "Default Web Site" -section:traceFailedRequests -text:* | findstr provider:> traceproviders.txt
for /F %%V in (traceproviders.txt) do set /a PROCOUNT = PROCOUNT + 1


@REM Step 4
@REM Change %%V to %V if you are not running in batch mode

for /L %%V in (0,1,%PROCOUNT%) do %windir%\System32\inetsrv\appcmd set config "Default Web Site" /section:traceFailedRequests /[path='*'].traceAreas.[@%%V].verbosity:Verbose -commit:apphost




You can remove step3 and change step 4 to run blindly from 0 to 3. You might get invalid index errors from appcmd if you have less than 4 providers installed on your machine which you can ignore.