From patchwork Wed Oct 13 14:13:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Zupka X-Patchwork-Id: 250721 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o9DECrwH002623 for ; Wed, 13 Oct 2010 14:12:53 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752653Ab0JMOMp (ORCPT ); Wed, 13 Oct 2010 10:12:45 -0400 Received: from mx1.redhat.com ([209.132.183.28]:62423 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752470Ab0JMOMo (ORCPT ); Wed, 13 Oct 2010 10:12:44 -0400 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o9DECiL5007180 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 13 Oct 2010 10:12:44 -0400 Received: from jzupka.local.com (dhcp-27-161.brq.redhat.com [10.34.27.161]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o9DECb2I009027; Wed, 13 Oct 2010 10:12:42 -0400 From: =?UTF-8?q?Ji=C5=99=C3=AD=20=C5=BDupka?= To: kvm-autotest@redhat.com, kvm@vger.kernel.org Cc: jzupka@redhat.com, akong@redhat.com, ldoktor@redhat.com Subject: [Autotest][PATCH 3/4] Monitoring numerical information from file and return value of this information. Date: Wed, 13 Oct 2010 16:13:18 +0200 Message-Id: <1286979199-13109-4-git-send-email-jzupka@redhat.com> In-Reply-To: <1286979199-13109-1-git-send-email-jzupka@redhat.com> References: <1286979199-13109-1-git-send-email-jzupka@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 13 Oct 2010 14:12:53 +0000 (UTC) diff --git a/client/common_lib/utils.py b/client/common_lib/utils.py index c126e58..e7e0d02 100644 --- a/client/common_lib/utils.py +++ b/client/common_lib/utils.py @@ -4,6 +4,7 @@ import os, pickle, random, re, resource, select, shutil, signal, StringIO import socket, struct, subprocess, sys, time, textwrap, urlparse import warnings, smtplib, logging, urllib2 +from threading import Thread, Event try: import hashlib except ImportError: @@ -323,6 +324,156 @@ def write_keyval(path, dictionary, type_tag=None): keyval.close() +class FileFieldMonitor(): + """ + Monitors the information from the file and reports it's values. + + It gather the information at start and stop of the measurement or + continuously during the measurement. + """ + class Monitor(Thread): + """ + Internal monitor class to ensure continuous monitor of monitored file. + """ + def __init__(self, master): + """ + @param master: Master class which control Monitor + """ + Thread.__init__(self) + self.master = master + + def run(self): + """ + Start monitor in thread mode + """ + while not self.master.end_event.isSet(): + self.master._get_value(self.master.logging) + time.sleep(self.master.time_step) + + + def __init__(self, status_file, data_to_read, mode_diff, continuously=False, + contlogging=False, separator=" +", time_step=0.1): + """ + Initialize variables. + @param status_file: File contain status. + @param mode_diff: If True make a difference of value, else average. + @param data_to_read: List of tuples with data position. + format: [(start_of_line,position in params)] + example: + data: + cpu 324 345 34 5 345 + cpu0 34 11 34 34 33 + ^^^^ + start of line + params 0 1 2 3 4 + @param mode_diff: True to subtract old value from new value, + False make average of the values. + @parma continuously: Start the monitoring thread using the time_step + as the measurement period. + @param contlogging: Log data in continuous run. + @param separator: Regular expression of separator. + @param time_step: Time period of the monitoring value. + """ + self.end_event = Event() + self.start_time = 0 + self.end_time = 0 + self.test_time = 0 + + self.status_file = status_file + self.separator = separator + self.data_to_read = data_to_read + self.num_of_params = len(self.data_to_read) + self.mode_diff = mode_diff + self.continoutsly = continuously + self.time_step = time_step + + self.value = [0 for i in range(self.num_of_params)] + self.old_value = [0 for i in range(self.num_of_params)] + self.log = [] + self.logging = contlogging + + self.started = False + self.num_of_get_value = 0 + self.monitor = None + + + def _get_value(self, logging=True): + """ + Return current values. + @param logging: If true log value in memory. There can be problem + with long run. + """ + data = read_file(self.status_file) + value = [] + for i in range(self.num_of_params): + value.append(int(get_field(data, + self.data_to_read[i][1], + self.data_to_read[i][0], + self.separator))) + + if logging: + self.log.append(value) + if not self.mode_diff: + value = map(lambda x, y: x + y, value, self.old_value) + + self.old_value = value + self.num_of_get_value += 1 + return value + + + def start(self): + """ + Start value monitor. + """ + if self.started: + self.stop() + self.old_value = [0 for i in range(self.num_of_params)] + self.num_of_get_value = 0 + self.log = [] + self.end_event.clear() + self.start_time = time.time() + self._get_value() + self.started = True + if (self.continoutsly): + self.monitor = FileFieldMonitor.Monitor(self) + self.monitor.start() + + + def stop(self): + """ + Stop value monitor. + """ + if self.started: + self.started = False + self.end_time = time.time() + self.test_time = self.end_time - self.start_time + self.value = self._get_value() + if (self.continoutsly): + self.end_event.set() + self.monitor.join() + if (self.mode_diff): + self.value = map(lambda x, y: x - y, self.log[-1], self.log[0]) + else: + self.value = map(lambda x: x / self.num_of_get_value, + self.value) + + + def get_status(self): + """ + @return: Status of monitored process average value, + time of test and array of monitored values and time step of + continuous run. + """ + if self.started: + self.stop() + if self.mode_diff: + for i in range(len(self.log) - 1): + self.log[i] = (map(lambda x, y: x - y, + self.log[i + 1], self.log[i])) + self.log.pop() + return (self.value, self.test_time, self.log, self.time_step) + + def is_url(path): """Return true if path looks like a URL""" # for now, just handle http and ftp