diff --git a/library/Class/WebService/SIGB/AbstractRESTService.php b/library/Class/WebService/SIGB/AbstractRESTService.php
index 69bc2ed0b168aea4ed7ae00b107ba5e8314165d6..5f211e4d5e3b57fa769b208aca8434fdf8ff0747 100644
--- a/library/Class/WebService/SIGB/AbstractRESTService.php
+++ b/library/Class/WebService/SIGB/AbstractRESTService.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with AFI-OPAC 2.0; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
 abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebService_SIGB_AbstractService {
@@ -82,13 +82,16 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic
 	public function httpGet($options) {
 		$url = $this->buildQueryURL($options);
 		try {
-			return $this->getWebClient()->open_url($url);
+			$response = $this->getWebClient()->open_url($url);
+			$this->log();
+			return $response;
 		} catch (Exception $e) {
+			$this->logError($url, $e->getMessage());
 			return '';
 		}
 	}
 
-	
+
 	/**
 	 * @param string $xml
 	 * @param string $tag
@@ -124,7 +127,7 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic
 																$reader);
 	}
 
- 
+
 	/**
 	 * @param array $params
 	 * @param Class_WebService_SIGB_AbstractILSDIPatronInfoReader $reader
@@ -168,7 +171,7 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic
 
 		return false;
 	}
-		
+
 
 	/**
 	 * @param array $params
@@ -202,7 +205,7 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic
 	public function ilsdiRenewLoan($params, $error_tag='error') {
 		return $this->ilsdiAction('RenewLoan', $params, $error_tag, 'Prolongation impossible');
 	}
-	
+
 
 	/**
 	 * @param string $xml
@@ -211,12 +214,12 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic
 		return $this->ilsdiCheckXml($xml, $error_tag, 'Mise à jour impossible');
 	}
 
-		
+
 	public function ilsdiAction($name, $params, $error_tag, $error_message) {
 		$params = array_merge(array('service' => $name), $params);
 		return $this->ilsdiCheckXml($this->httpGet($params), $error_tag, $error_message);
 	}
-	
+
 
 	public function ilsdiCheckXml($xml, $error_tag, $error_message) {
 		if (!$xml)
diff --git a/library/Class/WebService/SIGB/AbstractService.php b/library/Class/WebService/SIGB/AbstractService.php
index aebe8404272cdb1666a93eec789fc7662470dc35..fd4802e0e2e1f67e6d6d25f98829a6092e2b8167 100644
--- a/library/Class/WebService/SIGB/AbstractService.php
+++ b/library/Class/WebService/SIGB/AbstractService.php
@@ -20,6 +20,7 @@
  */
 
 abstract class Class_WebService_SIGB_AbstractService {
+	protected static $_logger;
 	protected $_notice_cache;
 
 	/**
@@ -30,6 +31,25 @@ abstract class Class_WebService_SIGB_AbstractService {
 	}
 
 
+	public static function setLogger($logger) {
+		static::$_logger = $logger;
+	}
+
+
+	public static function log() {
+		if (!static::$_logger)
+			return;
+		static::$_logger->log();
+	}
+
+
+	public static function logError($url, $message) {
+		if (!static::$_logger)
+			return;
+		static::$_logger->logError($url, $message);
+	}
+
+
 	public function getReservationsOf($emprunteur) {
 		return array();
 	}
diff --git a/library/ZendAfi/Controller/Plugin/InspectorGadget.php b/library/ZendAfi/Controller/Plugin/InspectorGadget.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad9f6ea4a7cc720c0524516f7c5d45630d71bd07
--- /dev/null
+++ b/library/ZendAfi/Controller/Plugin/InspectorGadget.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * AFI-OPAC 2.0 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * AFI-OPAC 2.0 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with AFI-OPAC 2.0; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+class ZendAfi_Controller_Plugin_InspectorGadget extends Zend_Controller_Plugin_Abstract {
+	const PARAM_NAME = 'inspector_gadget';
+	protected $_enabled = false;
+	protected $_calls = [];
+
+	public function preDispatch(Zend_Controller_Request_Abstract  $request) {
+		if (!$request->getParam(self::PARAM_NAME, false))
+			return;
+
+		$this->beEnabled();
+		Class_WebService_SIGB_AbstractService::setLogger($this);
+	}
+
+
+	public function isEnabled() {
+		return $this->_enabled;
+	}
+
+
+	public function addToParams($params=[]) {
+		if (!$this->isEnabled())
+			return $params;
+
+		$params[self::PARAM_NAME] = 1;
+		return $params;
+	}
+
+
+	protected function beEnabled() {
+		$this->_enabled = true;
+	}
+
+
+	public function postDispatch(Zend_Controller_Request_Abstract $request) {
+		if (!$this->_enabled || empty($this->_calls))
+			return;
+
+		if (false === strpos('</body>', $this->_response->getBody())) {
+			$this->_response->setBody($this->render() . $this->_response->getBody());
+			return;
+		}
+
+		$this->_response->setBody(str_ireplace('</body>',  $this->render() . '</body>',
+																					 $this->_response->getBody()));
+	}
+
+
+	protected function render() {
+		$html = $this->renderButton()
+			. '<div data-type="' . self::PARAM_NAME . '" style="display:none;"><ol>';
+
+		foreach($this->_calls as $call)
+			$html .= '<li>' . $this->renderCall($call) . '</li>';
+
+		return $html . '</ol></div>';
+	}
+
+
+	protected function renderButton() {
+		return '<button style="width:20px;height:20px;text-align:center;"
+onclick="$(\'[data-type=' . self::PARAM_NAME . ']\').dialog({title:\'Inspector\', width:625});">i</button>';
+	}
+
+
+	protected function renderCall($call) {
+		return
+			'<h3>Requête</h3>' . $call->request . ' (' . $call->response_code . ')'
+			. '<h3>Réponse</h3><textarea style="width:600px">' . $call->response_body . '</textarea>';
+	}
+
+
+	public function log() {
+		$httpClient = Zend_Registry::get('httpClient');
+		$call = new StdClass();
+		$call->request = $httpClient->getLastRequest();
+
+		if ($response = $httpClient->getLastResponse()) {
+			$call->response_code = $response->getStatus();
+			$call->response_body = $response->getBody();
+		}
+
+		$this->_calls[] = $call;
+	}
+
+
+	public function logError($url, $message) {
+		$call = new StdClass();
+		$call->request = $url;
+		$call->response_code = 'n/a';
+		$call->response_body = $message;
+
+		$this->_calls[] = $call;
+	}
+}
+
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/AbsoluteUrl.php b/library/ZendAfi/View/Helper/AbsoluteUrl.php
index 57d88de467b4ca46bab1564bf911113cf9a2cba3..90771a016dac8468c3381a331ac89500add07cd5 100644
--- a/library/ZendAfi/View/Helper/AbsoluteUrl.php
+++ b/library/ZendAfi/View/Helper/AbsoluteUrl.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with AFI-OPAC 2.0; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 class ZendAfi_View_Helper_AbsoluteUrl extends Zend_View_Helper_HtmlElement {
 	protected static $_do_not_add_base_url;
@@ -25,18 +25,29 @@ class ZendAfi_View_Helper_AbsoluteUrl extends Zend_View_Helper_HtmlElement {
 		static::$_do_not_add_base_url = true;
 	}
 
-	public function absoluteUrl($url_array_or_string = [], $name = null, $reset = false, $encode = true) {
-		$url = is_string($url_array_or_string) 
-			? $url_array_or_string
-			: $this->view->url($url_array_or_string, $name, $reset, $encode);
 
+	public function absoluteUrl($url_array_or_string = [], $name = null, $reset = false, $encode = true) {
+		$url = $this->prepare($url_array_or_string, $name, $reset, $encode);
 		if (preg_match('/http[s]?:\/\//', $url))
 			return $url;
 
 		if ((!static::$_do_not_add_base_url) &&  (0 !== strpos($url, BASE_URL)))
 			$url = BASE_URL . ($url[0] == '/' ? $url : '/'.$url);
 
-
 		return 'http://' . $_SERVER['SERVER_NAME'] . $url;
 	}
+
+
+	protected function prepare($url_array_or_string, $name, $reset, $encode) {
+		if (is_string($url_array_or_string))
+			return $url_array_or_string;
+
+		$inspector_gadget = Zend_Controller_Front::getInstance()
+			->getPlugin('ZendAfi_Controller_Plugin_InspectorGadget');
+
+		if ($inspector_gadget)
+			$url_array_or_string = $inspector_gadget->addToParams($url_array_or_string);
+
+		return $this->view->url($url_array_or_string, $name, $reset, $encode);
+	}
 }
\ No newline at end of file
diff --git a/library/startup.php b/library/startup.php
index ff5ee156fd18db70fade25d7a9376b56145d8ae6..a539a15a79ef8d65b56e1a977429450230274692 100644
--- a/library/startup.php
+++ b/library/startup.php
@@ -278,6 +278,7 @@ function setupFrontController($cfg) {
 		->registerPlugin(new ZendAfi_Controller_Plugin_TogetherJS())
 		->registerPlugin(new ZendAfi_Controller_Plugin_CustomFields())
 		->registerPlugin(new ZendAfi_Controller_Plugin_Lectura())
+		->registerPlugin(new ZendAfi_Controller_Plugin_InspectorGadget())
 		->setParam('useDefaultControllerAlways', true);
 
 
diff --git a/tests/application/modules/admin/controllers/AjaxControllerTest.php b/tests/application/modules/admin/controllers/AjaxControllerTest.php
index d92506d2a8cb8c5c50cb1f22e3a45230bd376629..eb5f8c50d69db5540d3e362aab5de78a01051be2 100644
--- a/tests/application/modules/admin/controllers/AjaxControllerTest.php
+++ b/tests/application/modules/admin/controllers/AjaxControllerTest.php
@@ -16,10 +16,46 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with AFI-OPAC 2.0; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
 class AjaxControllerSuggestTest extends AbstractControllerTestCase {
+	protected $_sql_mock;
+
+	public function setUp() {
+		parent::setUp();
+		$this->_sql_mock = $this
+			->mock()
+			->whenCalled('fetchAll')
+			->with("select id_auteur,libelle from codif_auteur where formes like'1%' order by FORMES limit 100", false)
+			->answers([['id_auteur' => 12999, 'libelle' => 'André Gosciny']])
+
+			->whenCalled('fetchAll')
+			->with("select id_auteur,libelle from codif_auteur where formes like'L%' order by FORMES limit 100", false)
+			->answers([['id_auteur' => 12999, 'libelle' => 'André Gosciny']])
+
+			->whenCalled('fetchAll')
+			->with("select id_matiere,libelle from codif_matiere where code_alpha like 'L%' order by code_alpha limit 100", true)
+			->answers([[999, 'Testing test']])
+
+			->whenCalled('fetchAll')
+			->with("select id_interet,libelle from codif_interet where code_alpha like 'L%' order by code_alpha limit 100", true)
+			->answers([[777, 'Cinéma']])
+
+			->whenCalled('fetchAll')
+			->with("select id_dewey,libelle from codif_dewey where id_dewey like'%' order by id_dewey limit 100", false)
+			->answers([['id_dewey' => '888', 'libelle' => 'Actualités']])
+
+			->whenCalled('fetchAll')
+			->with("select id_pcdm4,libelle from codif_pcdm4 where id_pcdm4 like'%' order by id_pcdm4 limit 100", false)
+			->answers([['id_pcdm4' => '566', 'libelle' => 'Bande dessiné']])
+
+			->beStrict();
+
+		Zend_Registry::set('sql', $this->_sql_mock);
+	}
+
+
 	/** @test */
 	public function forAuthorsAsAdminPortailBodyShouldContainsTagListe() {
 		$this->dispatch('/admin/ajax/listesuggestion/type_autorite/auteur/mode/1/valeur/1/id_champ/suggest', true);
@@ -36,26 +72,24 @@ class AjaxControllerSuggestTest extends AbstractControllerTestCase {
 
 
 	public function getTypeAutorites() {
-		return [
-			['auteur'],
-			['matiere'],
-			['interet'],
-			['dewey'],
-			['pcdm4'],
+		return [['auteur'],
+						['matiere'],
+						['interet'],
+						['dewey'],
+						['pcdm4'],
 //			['thesaurus'],
 //			['tag'],
-			];
+		];
 	}
 
-	/** 
-	 * @test 
+	/**
+	 * @test
 	 * @dataProvider getTypeAutorites
 	 */
 	public function forAutoritysAsAdminPortailBodyShouldContainsTagListe($type_autorite) {
-		$this->dispatch('/admin/ajax/listesuggestion/type_autorite/'.$type_autorite.'/mode/1/valeur/l/id_champ/suggest', 
+		$this->dispatch('/admin/ajax/listesuggestion/type_autorite/'.$type_autorite.'/mode/1/valeur/l/id_champ/suggest',
 										true);
-		$this->assertXPath('//div[@class="tag_liste"]',
-											 $this->_response->getBody());
+		$this->assertXPath('//div[@class="tag_liste"]', $this->_response->getBody());
 	}
 
 }
@@ -63,7 +97,7 @@ class AjaxControllerSuggestTest extends AbstractControllerTestCase {
 
 
 
-class AjaxControllerSuggestThesaurusPirateTest extends AbstractControllerTestCase {	
+class AjaxControllerSuggestThesaurusPirateTest extends AbstractControllerTestCase {
 	public function setUp() {
 		parent::setUp();
 		$this->mock_sql = $this->mock();
@@ -78,7 +112,7 @@ class AjaxControllerSuggestThesaurusPirateTest extends AbstractControllerTestCas
 
 	public function datas() {
 		return [
-			[Class_CodifThesaurus::MODE_HIERARCHY_CONTAINS, 
+			[Class_CodifThesaurus::MODE_HIERARCHY_CONTAINS,
 			 "select distinct(id),id_thesaurus,id_origine from codif_thesaurus where id_thesaurus regexp (select group_concat(concat(id_thesaurus,'.*') separator '|') from codif_thesaurus where id_thesaurus like 'PUBL%' and id_origine is not null and libelle like '%pirate%') order by id_thesaurus"],
 			[Class_CodifThesaurus::MODE_LABEL_STARTS_WITH,
 			 "select id,id_thesaurus,libelle,id_origine from codif_thesaurus where id_thesaurus like 'PUBL%'  and libelle like'pirate%' order by id_thesaurus limit 100"],
@@ -90,8 +124,8 @@ class AjaxControllerSuggestThesaurusPirateTest extends AbstractControllerTestCas
 	}
 
 
-	/** 
-	 * @test 
+	/**
+	 * @test
 	 * @dataProvider datas
 	 */
 	public function withModeShouldRunExpectedQueryAndSuggestPirate($mode, $query) {
@@ -107,8 +141,8 @@ class AjaxControllerSuggestThesaurusPirateTest extends AbstractControllerTestCas
 
 
 	protected function assertPirateIsSuggested() {
-		$this->assertXPathContentContains('//div[@class="tag_liste"][@clef="1"]', 
-																			'1 : pirate', 
+		$this->assertXPathContentContains('//div[@class="tag_liste"][@clef="1"]',
+																			'1 : pirate',
 																			$this->_response->getBody());
 	}