From patchwork Fri Feb 1 14:53:08 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Seiji Aguchi X-Patchwork-Id: 217554 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 711782C0087 for ; Sat, 2 Feb 2013 04:49:54 +1100 (EST) Received: from localhost ([::1]:60878 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U1KkK-0004Yy-IA for incoming@patchwork.ozlabs.org; Fri, 01 Feb 2013 12:49:52 -0500 Received: from eggs.gnu.org ([208.118.235.92]:36933) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U1HzY-0005Yq-Hi for qemu-devel@nongnu.org; Fri, 01 Feb 2013 09:53:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U1HzU-0007hI-HC for qemu-devel@nongnu.org; Fri, 01 Feb 2013 09:53:24 -0500 Received: from usindpps03.hds.com ([207.126.252.16]:37417) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U1HzU-0007h6-Ag for qemu-devel@nongnu.org; Fri, 01 Feb 2013 09:53:20 -0500 Received: from usindmail02.hds.com (usindmail02 [207.126.252.21]) by usindpps03.hds.com (8.14.4/8.14.4) with ESMTP id r11ErAb8007662; Fri, 1 Feb 2013 09:53:10 -0500 Received: from USINDEHT102.corp.hds.com (usindnetf5d-vlan47float.corp.hds.com [10.74.73.11]) by usindmail02.hds.com (8.14.1/8.14.1) with ESMTP id r11Er98N025474; Fri, 1 Feb 2013 09:53:09 -0500 (EST) Received: from USINDEM103.corp.hds.com ([169.254.3.148]) by USINDEHT102.corp.hds.com ([::1]) with mapi id 14.02.0309.002; Fri, 1 Feb 2013 09:53:08 -0500 From: Seiji Aguchi To: "qemu-devel@nongnu.org" , "pbonzini@redhat.com" Thread-Topic: [RFC][PATCH]Add timestamp to error message Thread-Index: Ac4Aizd9DsVjHOfqS/CFciewBcor8Q== Date: Fri, 1 Feb 2013 14:53:08 +0000 Message-ID: Accept-Language: ja-JP, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.74.73.11] MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.9.8327, 1.0.431, 0.0.0000 definitions=2013-02-01_04:2013-02-01, 2013-02-01, 1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_policy_notspam policy=outbound_policy score=0 spamscore=0 ipscore=0 suspectscore=1 phishscore=0 bulkscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=6.0.2-1211240000 definitions=main-1302010081 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 207.126.252.16 X-Mailman-Approved-At: Fri, 01 Feb 2013 12:49:35 -0500 Cc: "dle-develop@lists.sourceforge.net" , Satoru Moriya Subject: [Qemu-devel] [RFC][PATCH]Add timestamp to error message X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org [Issue] When we offer a customer support service and a problem happens in a customer's system, we try to understand the problem by comparing what the customer reports with message logs of the customer's system. In this case, we often need to know when the problem happens. But, currently, there is no timestamp in qemu's error messages. Therefore, we may not be able to understand the problem based on error messages. [Solution] This patch adds a timestamp to qemu's error message logged by error_report(). A logic calculating a time is copied from libvirt, src/util/virtime.c. [TODO] Other functions below are used to output error messages in qemu. - qerror_report() is called in many source codes. - fprintf() is called in vl.c. A timestamp should be added to these messages as well. Signed-off-by: Seiji Aguchi --- util/qemu-error.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 90 insertions(+), 0 deletions(-) -- 1.7.1 diff --git a/util/qemu-error.c b/util/qemu-error.c index 08a36f4..44d0fc1 100644 --- a/util/qemu-error.c +++ b/util/qemu-error.c @@ -196,6 +196,95 @@ void error_print_loc(void) } } + +#define SECS_PER_HOUR (60 * 60) +#define SECS_PER_DAY (SECS_PER_HOUR * 24) +#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) +#define LEAPS_THRU_END_OF(y) (DIV(y, 4) - DIV(y, 100) + DIV(y, 400)) + +const unsigned short int __mon_yday[2][13] = { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; + +#define is_leap_year(y) \ + ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) + +static void error_print_timestamp(void) +{ + struct timespec ts; + unsigned long long now; + + struct tm fields; + long int days, rem, y; + const unsigned short int *ip; + unsigned long long whenSecs; + unsigned int offset = 0; /* We hardcoded GMT */ + + if (clock_gettime(CLOCK_REALTIME, &ts) < 0) { + return; + } + + now = (ts.tv_sec * 1000ull) + (ts.tv_nsec / (1000ull * 1000ull)); + /* This code is taken from GLibC under terms of LGPLv2+ */ + + whenSecs = now / 1000ull; + + days = whenSecs / SECS_PER_DAY; + rem = whenSecs % SECS_PER_DAY; + rem += offset; + while (rem < 0) { + rem += SECS_PER_DAY; + --days; + } + while (rem >= SECS_PER_DAY) { + rem -= SECS_PER_DAY; + ++days; + } + fields.tm_hour = rem / SECS_PER_HOUR; + rem %= SECS_PER_HOUR; + fields.tm_min = rem / 60; + fields.tm_sec = rem % 60; + /* January 1, 1970 was a Thursday. */ + fields.tm_wday = (4 + days) % 7; + if (fields.tm_wday < 0) { + fields.tm_wday += 7; + } + y = 1970; + + while (days < 0 || days >= (is_leap_year(y) ? 366 : 365)) { + /* Guess a corrected year, assuming 365 days per year. */ + long int yg = y + days / 365 - (days % 365 < 0); + + /* Adjust DAYS and Y to match the guessed year. */ + days -= ((yg - y) * 365 + + LEAPS_THRU_END_OF(yg - 1) + - LEAPS_THRU_END_OF(y - 1)); + y = yg; + } + fields.tm_year = y - 1900; + + fields.tm_yday = days; + ip = __mon_yday[is_leap_year(y)]; + for (y = 11; days < (long int) ip[y]; --y) { + continue; + } + + days -= ip[y]; + fields.tm_mon = y; + fields.tm_mday = days + 1; + + error_printf( + "%4d-%02d-%02d %02d:%02d:%02d.%03lld+0000 ", + fields.tm_year + 1900, fields.tm_mon + 1, fields.tm_mday, + fields.tm_hour, fields.tm_min, fields.tm_sec, + now % 1000); + + return; +} + /* * Print an error message to current monitor if we have one, else to stderr. * Format arguments like sprintf(). The result should not contain @@ -207,6 +296,7 @@ void error_report(const char *fmt, ...) { va_list ap; + error_print_timestamp(); error_print_loc(); va_start(ap, fmt); error_vprintf(fmt, ap);