resourceloader: Audit debug log channels and messages
[lhc/web/wiklou.git] / includes / resourceloader / ResourceLoader.php
index b4b5a2e..d5b17d8 100644 (file)
  * @author Trevor Parscal
  */
 
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
+
 /**
  * Dynamic JavaScript and CSS resource loading system.
  *
  * Most of the documentation is on the MediaWiki documentation wiki starting at:
  *    https://www.mediawiki.org/wiki/ResourceLoader
  */
-class ResourceLoader {
+class ResourceLoader implements LoggerAwareInterface {
        /** @var int */
        protected static $filterCacheVersion = 7;
 
@@ -77,6 +81,11 @@ class ResourceLoader {
         */
        protected $blobStore;
 
+       /**
+        * @var LoggerInterface
+        */
+       private $logger;
+
        /**
         * Load information stored in the database about modules.
         *
@@ -188,24 +197,25 @@ class ResourceLoader {
                }
 
                if ( !in_array( $filter, array( 'minify-js', 'minify-css' ) ) ) {
-                       wfDebugLog( 'resourceloader', __METHOD__ . ": Invalid filter: $filter" );
+                       $this->logger->warning( 'Invalid filter {filter}', array(
+                               'filter' => $filter
+                       ) );
                        return $data;
                }
 
                if ( !$options['cache'] ) {
                        $result = $this->applyFilter( $filter, $data );
                } else {
-                       // Use CACHE_ANYTHING since filtering is very slow compared to DB queries
                        $key = wfMemcKey( 'resourceloader', 'filter', $filter, self::$filterCacheVersion, md5( $data ) );
-                       $cache = wfGetCache( CACHE_ANYTHING );
+                       $cache = wfGetCache( wfIsHHVM() ? CACHE_ACCEL : CACHE_ANYTHING );
                        $cacheEntry = $cache->get( $key );
                        if ( is_string( $cacheEntry ) ) {
-                               wfIncrStats( "rl-$filter-cache-hits" );
+                               wfIncrStats( "resourceloader_cache.$filter.hit" );
                                return $cacheEntry;
                        }
                        $result = '';
                        try {
-                               wfIncrStats( "rl-$filter-cache-misses" );
+                               wfIncrStats( "resourceloader_cache.$filter.miss" );
                                $result = $this->applyFilter( $filter, $data );
                                if ( $options['cacheReport'] ) {
                                        $result .= "\n/* cache key: $key */";
@@ -213,7 +223,9 @@ class ResourceLoader {
                                $cache->set( $key, $result );
                        } catch ( Exception $e ) {
                                MWExceptionHandler::logException( $e );
-                               wfDebugLog( 'resourceloader', __METHOD__ . ": minification failed: $e" );
+                               $this->logger->warning( 'Minification failed: {exception}', array(
+                                       'exception' => $e
+                               ) );
                                $this->errors[] = self::formatExceptionNoComment( $e );
                        }
                }
@@ -240,14 +252,18 @@ class ResourceLoader {
         * Register core modules and runs registration hooks.
         * @param Config|null $config
         */
-       public function __construct( Config $config = null ) {
+       public function __construct( Config $config = null, LoggerInterface $logger = null ) {
                global $IP;
 
-               if ( $config === null ) {
-                       wfDebug( __METHOD__ . ' was called without providing a Config instance' );
-                       $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
+               if ( !$logger ) {
+                       $logger = new NullLogger();
                }
+               $this->setLogger( $logger );
 
+               if ( !$config ) {
+                       $this->logger->debug( __METHOD__ . ' was called without providing a Config instance' );
+                       $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
+               }
                $this->config = $config;
 
                // Add 'local' source first
@@ -277,6 +293,10 @@ class ResourceLoader {
                return $this->config;
        }
 
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
+       }
+
        /**
         * @param MessageBlobStore $blobStore
         * @since 1.25
@@ -634,7 +654,7 @@ class ResourceLoader {
                                // Do not allow private modules to be loaded from the web.
                                // This is a security issue, see bug 34907.
                                if ( $module->getGroup() === 'private' ) {
-                                       wfDebugLog( 'resourceloader', __METHOD__ . ": request for private module '$name' denied" );
+                                       $this->logger->debug( "Request for private module '$name' denied" );
                                        $this->errors[] = "Cannot show private module \"$name\"";
                                        continue;
                                }
@@ -649,7 +669,9 @@ class ResourceLoader {
                        $this->preloadModuleInfo( array_keys( $modules ), $context );
                } catch ( Exception $e ) {
                        MWExceptionHandler::logException( $e );
-                       wfDebugLog( 'resourceloader', __METHOD__ . ": preloading module info failed: $e" );
+                       $this->logger->warning( 'Preloading module info failed: {exception}', array(
+                               'exception' => $e
+                       ) );
                        $this->errors[] = self::formatExceptionNoComment( $e );
                }
 
@@ -659,7 +681,9 @@ class ResourceLoader {
                        $versionHash = $this->getCombinedVersion( $context, array_keys( $modules ) );
                } catch ( Exception $e ) {
                        MWExceptionHandler::logException( $e );
-                       wfDebugLog( 'resourceloader', __METHOD__ . ": calculating version hash failed: $e" );
+                       $this->logger->warning( 'Calculating version hash failed: {exception}', array(
+                               'exception' => $e
+                       ) );
                        $this->errors[] = self::formatExceptionNoComment( $e );
                }
 
@@ -805,8 +829,7 @@ class ResourceLoader {
                        // sending the 304.
                        wfResetOutputBuffers( /* $resetGzipEncoding = */ true );
 
-                       header( 'HTTP/1.0 304 Not Modified' );
-                       header( 'Status: 304 Not Modified' );
+                       HttpStatus::header( 304 );
 
                        $this->sendResponseHeaders( $context, $etag, false );
                        return true;
@@ -942,10 +965,9 @@ MESSAGE;
                                $blobs = $this->blobStore->get( $this, $modules, $context->getLanguage() );
                        } catch ( Exception $e ) {
                                MWExceptionHandler::logException( $e );
-                               wfDebugLog(
-                                       'resourceloader',
-                                       __METHOD__ . ": pre-fetching blobs from MessageBlobStore failed: $e"
-                               );
+                               $this->logger->warning( 'Prefetching MessageBlobStore failed: {exception}', array(
+                                       'exception' => $e
+                               ) );
                                $this->errors[] = self::formatExceptionNoComment( $e );
                        }
                } else {
@@ -1058,7 +1080,9 @@ MESSAGE;
                                }
                        } catch ( Exception $e ) {
                                MWExceptionHandler::logException( $e );
-                               wfDebugLog( 'resourceloader', __METHOD__ . ": generating module package failed: $e" );
+                               $this->logger->warning( 'Generating module package failed: {exception}', array(
+                                       'exception' => $e
+                               ) );
                                $this->errors[] = self::formatExceptionNoComment( $e );
 
                                // Respond to client with error-state instead of module implementation