CWebLogRoute with showInFireBug vs AJAX

I’m not sure if this is a bug, but I suspect it may be a bug (or missing feature, depending on your point of view).

I’m logging in FireBug with CWebLogRoute and showInFireBug enabled - it’s working nicely, except for AJAX requests where the script is expecting text or HTML as the reply…

For example, the tags autocompleter in the blog-demo displays JavaScript code (console.log statements) in the dropdown.

This kind of JS-based logger output will probably have other unintended side-effects on various other AJAX functions, too.

Is there a way to turn off the logging for AJAX requests, as a temporary workaround?

Of course not a good long-term solution, since log output is just as important (if not more) for AJAX as for regular page requests…

I use this helper function:


<?php

class JavaScript {

	/**

	* Makes request ajax safe.  Usefull when returning json data, and yii wants to spit out debug info

	*/

	public static function makeAjaxSafe() {

		Yii::app()->log->routes['web']->enabled = false;

	}

}

Maybe it would go better in a some sort of request layer like CHttpRequest

I would override beforeAction() and test if this is an ajax request. Can be implemented as a parent controller so you have to write the code only once.

I seem to recall having seen in another framework that it’s possible to look at the headers and determine if the request is coming from the browser itself or via AJAX…

I think whatever the best solution, it should be applied to the framework - this problem is too common to ignore.

With isAjaxRequest you can check if it’s an ajax request.




class ParentController extends CController

{


   public function beforeAction(CAction $action)

   {


      if (true === Yii::app()->request->isAjaxRequest)

      {

         if (true === isset(Yii::app()->log->routes['profile']))

         {

            Yii::app()->log->routes['profile']->enabled = false;

         }

         if (true === isset(Yii::app()->log->routes['web']))

         {

            Yii::app()->log->routes['web']->enabled = false;

         }

      }


      return parent::beforeAction($action);


   }


}



I’ll create a ticket for this and implant it if Qiang approves

But in some cases one may want to have profile and web logging? For example when creating an ajax only page were html gets dynamically loaded.

// Ah I see your ticket now.

I think it will be better to extend your Log class to don’t display them when an ajax request is called…

That’s the beauty of OOP :D

We can add a parameter if qiang approve it but I don’t think this is the best to do. You could need the logs in ajax requests…

I agreee, this is not ideal.

Log messages really should be returned some other way that doesn’t interfere with either AJAX or regular HTML, and doesn’t inhibit logging under any conditions.

The best way would be to return the log entries as headers, which would not interfere with any type of content, even images and other binaries.

The question is whether it’s possible to pick up these headers client-side and display them.

I know it’s possible with FirePHP, for example. But really, another add-on, on top of FireBug, just for that - and only works in FF, it would be better to have a simpler and cross-browser solution somehow…

So hey, there is a W3C way to get response headers:

http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders-method

No idea how widely supported this is.

Maybe it would possible for Yii to add something into jQuery, to pick up and parse log-entries from headers and display them, for example in FireBug?

Deleted the issue. I guess we don’t need to bloat yii with a built-in option to turn off logging on ajax requests… Seems like the pro is about the same as the con to me

Uhm, okay. Really?

I’ve needed to handle this problem on several different occasions already - having to address this problem again and again is getting tedious.

Dynamically generated images and PDFs, for example. Tomorrow I have to do some protected downloads as well, and will need the same fix again. This seems like a very common problem.

Most of the time I end up with something along the lines of this:




    foreach (Yii::app()->log->routes as $route)

    if ($route instanceof CWebLogRoute)

      $route->enabled = false;



Well, maybe I’ll write up my own logging class at some point, using headers, so I can debug my AJAX and other actions properly…

You could put this logic in beforeAction() as Y!! described if you want it to be automatic. It’s pretty easy to implant on the application side, but adding it to the core would just be a complication to a lot of people I think.

You could write your logger with support for:

http://www.firephp.org/

FirePHP enables you to log to your Firebug Console using a simple PHP method call.

All data is sent via response headers and will not interfere with the content on your page.

FirePHP is ideally suited for AJAX development where clean JSON and XML responses are required.

Maybe the issue should be reopen because the code is:





///CWebLogRoute

	protected function render($view,$data)

	{

		if($this->showInFireBug)

			$view.='-firebug';

		else

		{

			$app=Yii::app();

			if(!($app instanceof CWebApplication) || $app->getRequest()->getIsAjaxRequest())

				return;

		}

		$viewFile=YII_PATH.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.$view.'.php';

		include(Yii::app()->findLocalizedFile($viewFile,'en'));

	}



And should take in account ajax request even with firebug log active:





///CWebLogRoute

	protected function render($view,$data)

	{

		$app=Yii::app();

		if(!($app instanceof CWebApplication) || $app->getRequest()->getIsAjaxRequest())

		    return;


		if($this->showInFireBug)

		    $view.='-firebug';


		$viewFile=YII_PATH.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.$view.'.php';

		include(Yii::app()->findLocalizedFile($viewFile,'en'));

	}



What do you think?

Well the point it that the html log does not help anything for ajax requests. firebug logs DO however work with ajax requests, at least some of the time. If you load something with ajax, and you have firebug logging on, you will notice that the logs come up on firebug

I think web services also has to be addressed by a possible solution that might come out from this discussion.

/Tommy

in my opinion, complications will inevitably arise - the question is whether you have to find the solution in some obscure forum post or unsupported extension, or whether the framework provides a well-documented official solution.

You will run into these issues, unless you’re programming something completely trivial and ultra simple… but then why would you be using a complete MVC framework?

Anyways, FirePHP, that idea had crossed my mind… but I would prefer a simpler (cross-browser) solution - I’ll be thinking about possible ideas for a different approach :slight_smile:

Several months later… :D

I think the current behavior is annoying so I proposed to add a simple parameter to manage it http://code.google.com/p/yii/issues/detail?id=1594 (proposed patch attached).




@@ -25,6 +25,10 @@

		 * @var boolean whether the log should be displayed in FireBug instead of browser window. Defaults to false.

		 */

		public $showInFireBug=false;

+		/**

+		 * @var boolean if the log should be ignored in FireBug for Ajax requests. Defaults to false.

+		 */

+		public $ignoreAjaxInFireBug=false;


		/**

		 * Displays the log messages.

@@ -44,7 +48,7 @@

		{

				if($this->showInFireBug)

						$view.='-firebug';

-				else

+				if(!$this->showInFireBug || ($this->showInFireBug && $this->ignoreAjaxInFireBug))

				{

						$app=Yii::app();

						if(!($app instanceof CWebApplication) || $app->getRequest()->getIsAjaxRequest())



Opinions?


if(!$this->showInFireBug || ($this->showInFireBug && $this->ignoreAjaxInFireBug))



could be probably compressed to


if(!$this->showInFireBug || $this->ignoreAjaxInFireBug)