diff --git a/erp5/util/benchmark/process.py b/erp5/util/benchmark/process.py
index 658f969f2ff646b60e9cf7b4a5ec635546a47cea..e9175daf522c3a07bbb732101f494c56cac286ab 100644
--- a/erp5/util/benchmark/process.py
+++ b/erp5/util/benchmark/process.py
@@ -69,6 +69,7 @@ class BenchmarkProcess(multiprocessing.Process):
                         "another process, flushing remaining results...")
 
   def getBrowser(self, log_file):
+    self._logger.info("[BenchmarkProcess] Browser username and password: %s - %s" % (self._username, self._password))
     return Browser(self._argument_namespace.erp5_base_url,
                    self._username,
                    self._password,
@@ -87,8 +88,8 @@ class BenchmarkProcess(multiprocessing.Process):
       except StopIteration:
         raise
       except Exception, e:
+        self._logger.info("Exception while running target suite for user %s: %s" % (self._browser._username, str(e)))
         msg = "%s: %s" % (target, traceback.format_exc())
-
         try:
           msg += "Last response headers:\n%s\nLast response contents:\n%s" % \
               (self._browser.headers, self._browser.contents)
@@ -115,7 +116,7 @@ class BenchmarkProcess(multiprocessing.Process):
         # Clear the Browser history (which keeps (request, response))
         # otherwise it will consume a lot of memory after some time. Also it
         # does make sense to keep it as suites are independent of each other
-        self._browser.mech_browser.clear_history()
+        self._browser._history.clear()
 
       result.exitSuite(with_error)
 
diff --git a/erp5/util/benchmark/result.py b/erp5/util/benchmark/result.py
index 5b23a1462ee9214787f47546de4739b9d58d42f6..f7724863c5e4efbebfd461fb059a3161b5bb41f9 100644
--- a/erp5/util/benchmark/result.py
+++ b/erp5/util/benchmark/result.py
@@ -80,10 +80,14 @@ class BenchmarkResultStatistic(object):
 
   @property
   def mean(self):
+    if self.n == 0:
+      self.n = 1
     return self._value_sum / self.n
 
   @property
   def standard_deviation(self):
+    if self.n == 0:
+      self.n = 1
     return math.sqrt(self._variance_sum / self.n)
 
 class NothingFlushedException(Exception):
diff --git a/erp5/util/benchmark/thread.py b/erp5/util/benchmark/thread.py
new file mode 100644
index 0000000000000000000000000000000000000000..947660ce7464aa024bb54ab5a90d9048a7caadc4
--- /dev/null
+++ b/erp5/util/benchmark/thread.py
@@ -0,0 +1,76 @@
+##############################################################################
+#
+# Copyright (c) 2011 Nexedi SA and Contributors. All Rights Reserved.
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+
+import threading
+import time
+import requests
+
+class TestThread(threading.Thread):
+
+  def __init__(self, process_manager, command, log, env={}):
+    threading.Thread.__init__(self)
+    self.process_manager = process_manager
+    self.command = command
+    self.log = log
+    self.env = env
+  
+  def run(self):
+    self.process_manager.spawn(*self.command, **self.env)
+
+class TestMetricThread(threading.Thread):
+
+  def __init__(self, metric_url, log, stop_event, interval=60):
+    threading.Thread.__init__(self)
+    self.metric_url = metric_url
+    self.log = log
+    self.interval = interval
+    self.stop_event = stop_event
+    self.metric_list = []
+    self.error_message = None
+
+  def run(self):
+    while(not self.stop_event.is_set()):
+      self.stop_event.wait(-time.time() % self.interval)
+      try:
+        response = requests.get(self.metric_url)
+        if response.status_code == 200:
+          self.metric_list.append(response.text)
+        else:
+          self.log("Error getting mettrics: response.status: %s - response.text: %s" % (str(response.status_code), str(response.text)))
+          self.error_message = "response.status: %s - response.text: %s" % (str(response.status_code), str(response.text))
+      except Exception as e:
+        self.log("Exception while getting metrics: %s" % (str(e)))
+        self.error_message = "Exception while getting metrics: %s" % (str(e))
+
+  def getMetricList(self):
+    return self.metric_list
+
+  def getErrorMessage(self):
+    return self.error_message
+
+
+