[PATCH 1/2] lib: add xml logging
Keng-Yu Lin
kengyu at canonical.com
Fri Jun 1 08:21:38 UTC 2012
On Fri, Jun 1, 2012 at 10:43 AM, IvanHu <ivan.hu at canonical.com> wrote:
> On 05/28/2012 11:01 PM, Colin King wrote:
>>
>> From: Colin Ian King<colin.king at canonical.com>
>>
>> Signed-off-by: Colin Ian King<colin.king at canonical.com>
>> ---
>> doc/fwts.1 | 2 +-
>> src/lib/include/fwts_log.h | 1 +
>> src/lib/src/Makefile.am | 1 +
>> src/lib/src/fwts_framework.c | 4 +-
>> src/lib/src/fwts_log.c | 3 +
>> src/lib/src/fwts_log_xml.c | 186
>> ++++++++++++++++++++++++++++++++++++++++++
>> 6 files changed, 195 insertions(+), 2 deletions(-)
>> create mode 100644 src/lib/src/fwts_log_xml.c
>>
>> diff --git a/doc/fwts.1 b/doc/fwts.1
>> index 0d773cd..09eee56 100644
>> --- a/doc/fwts.1
>> +++ b/doc/fwts.1
>> @@ -150,7 +150,7 @@ specify the information in each log line. The
>> following specifiers are available
>> e.g. \-\-log\-format="%date %time [%field] (%owner): "
>> .TP
>> .B \-\-log\-type
>> -specify the log type. Currently plaintext and json log types are
>> available and the
>> +specify the log type. Currently plaintext, json and xml log types are
>> available and the
>> default is plaintext.
>> .TP
>> .B \-\-lp\-tags
>> diff --git a/src/lib/include/fwts_log.h b/src/lib/include/fwts_log.h
>> index 8903bab..8027d41 100644
>> --- a/src/lib/include/fwts_log.h
>> +++ b/src/lib/include/fwts_log.h
>> @@ -81,6 +81,7 @@ typedef struct fwts_log_ops_t {
>>
>> fwts_log_ops fwts_log_plaintext_ops;
>> fwts_log_ops fwts_log_json_ops;
>> +fwts_log_ops fwts_log_xml_ops;
>>
>> extern fwts_log_field fwts_log_filter;
>> extern const char *fwts_log_format;
>> diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am
>> index cae1f91..acea9cb 100644
>> --- a/src/lib/src/Makefile.am
>> +++ b/src/lib/src/Makefile.am
>> @@ -39,6 +39,7 @@ libfwts_la_SOURCES = \
>> fwts_log.c \
>> fwts_log_plaintext.c \
>> fwts_log_json.c \
>> + fwts_log_xml.c \
>> fwts_memorymap.c \
>> fwts_microcode.c \
>> fwts_mmap.c \
>> diff --git a/src/lib/src/fwts_framework.c b/src/lib/src/fwts_framework.c
>> index 1fcd88e..2b42982 100644
>> --- a/src/lib/src/fwts_framework.c
>> +++ b/src/lib/src/fwts_framework.c
>> @@ -76,7 +76,7 @@ static fwts_option fwts_framework_options[] = {
>> { "json-data-path", "j:", 1, "Specify path to fwts json data
>> files - default is /usr/share/fwts." },
>> { "lp-tags-log", "", 0, "Output LaunchPad bug tags in
>> results log." },
>> { "disassemble-aml", "", 0, "Disassemble AML from DSDT and
>> SSDT tables." },
>> - { "log-type", "", 1, "Specify log type (plaintext or
>> json)." },
>> + { "log-type", "", 1, "Specify log type (plaintext,
>> json or xml)." },
>> { NULL, NULL, 0, NULL }
>> };
>>
>> @@ -1040,6 +1040,8 @@ int fwts_framework_options_handler(fwts_framework
>> *fw, int argc, char * const ar
>> fw->log_type = LOG_TYPE_PLAINTEXT;
>> else if (!strcmp(optarg, "json"))
>> fw->log_type = LOG_TYPE_JSON;
>> + else if (!strcmp(optarg, "xml"))
>> + fw->log_type = LOG_TYPE_XML;
>> else {
>> fprintf(stderr, "--log-type can be either
>> plaintext or json.\n");
>> return FWTS_ERROR;
>> diff --git a/src/lib/src/fwts_log.c b/src/lib/src/fwts_log.c
>> index 5331fff..2b11441 100644
>> --- a/src/lib/src/fwts_log.c
>> +++ b/src/lib/src/fwts_log.c
>> @@ -390,6 +390,9 @@ fwts_log *fwts_log_open(const char *owner, const char
>> *name, const char *mode, f
>> case LOG_TYPE_PLAINTEXT:
>> newlog->ops =&fwts_log_plaintext_ops;
>> break;
>> + case LOG_TYPE_XML:
>> + newlog->ops =&fwts_log_xml_ops;
>> + break;
>> case LOG_TYPE_NONE:
>> default:
>> newlog->ops =&fwts_log_plaintext_ops;
>> diff --git a/src/lib/src/fwts_log_xml.c b/src/lib/src/fwts_log_xml.c
>> new file mode 100644
>> index 0000000..57b530b
>> --- /dev/null
>> +++ b/src/lib/src/fwts_log_xml.c
>> @@ -0,0 +1,186 @@
>> +/*
>> + * Copyright (C) 2010-2012 Canonical
>> + *
>> + * 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., 51 Franklin Street, Fifth Floor, Boston, MA
>> 02110-1301, USA.
>> + *
>> + */
>> +
>> +#include<stdlib.h>
>> +#include<stdio.h>
>> +#include<stdarg.h>
>> +#include<string.h>
>> +#include<unistd.h>
>> +#include<sys/ioctl.h>
>> +#include<time.h>
>> +
>> +#include "fwts.h"
>> +
>> +#define MAX_XML_STACK (64)
>> +#define XML_INDENT (4)
>> +
>> +typedef struct {
>> + const char *name;
>> +} fwts_log_xml_stack_t;
>> +
>> +static fwts_log_xml_stack_t xml_stack[MAX_XML_STACK];
>> +static int xml_stack_index = 0;
>> +
>> +/*
>> + * fwts_log_vprintf_xml()
>> + * vprintf to a log
>> + */
>> +static int fwts_log_vprintf_xml(fwts_log *log,
>> + const fwts_log_field field,
>> + const fwts_log_level level,
>> + const char *status,
>> + const char *label,
>> + const char *prefix,
>> + const char *fmt,
>> + va_list args)
>> +{
>> + char buffer[4096];
>> + struct tm tm;
>> + time_t now;
>> + char *str;
>> +
>> + if (!((field& LOG_FIELD_MASK)& fwts_log_filter))
>> + return 0;
>> +
>> + if (field& (LOG_NEWLINE | LOG_SEPARATOR | LOG_DEBUG))
>>
>> + return 0;
>> +
>> + time(&now);
>> + localtime_r(&now,&tm);
>> +
>> + fprintf(log->fp, "%*s<logentry>\n", xml_stack_index * XML_INDENT,
>> "");
>> +
>> + fprintf(log->fp, "%*s<line_num>%d</line_num>\n",
>> + (xml_stack_index + 1) * XML_INDENT,
>> + "", log->line_number);
>> +
>> + fprintf(log->fp, "%*s<date>%2.2d/%2.2d/%-2.2d</date>\n",
>> + (xml_stack_index + 1) * XML_INDENT,
>> + "", tm.tm_mday, tm.tm_mon + 1, (tm.tm_year+1900) % 100);
>> +
>> + fprintf(log->fp, "%*s<time>%2.2d:%2.2d:%2.2d</time>\n",
>> + (xml_stack_index + 1) * XML_INDENT,
>> + "", tm.tm_hour, tm.tm_min, tm.tm_sec);
>> +
>> + fprintf(log->fp, "%*s<field_type>%s</field_type>\n",
>> + (xml_stack_index + 1) * XML_INDENT,
>> + "", fwts_log_field_to_str_full(field));
>> +
>> + str = fwts_log_level_to_str(level);
>> + if (!strcmp(str, " "))
>> + str = "None";
>> +
>> + fprintf(log->fp, "%*s<level>%s</level>\n",
>> + (xml_stack_index + 1) * XML_INDENT, "", str);
>> +
>> + fprintf(log->fp, "%*s<status>%s</status>\n",
>> + (xml_stack_index + 1) * XML_INDENT,
>> + "", *status ? status : "None");
>> +
>> + fprintf(log->fp, "%*s<failure_label>%s</failure_label>\n",
>> + (xml_stack_index + 1) * XML_INDENT,
>> + "", label&& *label ? label : "None");
>>
>> +
>> + vsnprintf(buffer, sizeof(buffer), fmt, args);
>> + fprintf(log->fp, "%*s<log_text>%s</log_text>\n",
>> + (xml_stack_index + 1) * XML_INDENT,
>> + "", buffer);
>> +
>> + fprintf(log->fp, "%*s</logentry>\n", xml_stack_index * XML_INDENT,
>> "");
>> + fflush(log->fp);
>> +
>> + log->line_number++;
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * fwts_log_underline_xml()
>> + * write an underline across log, using character ch as the underline
>> + */
>> +static void fwts_log_underline_xml(fwts_log *log, const int ch)
>> +{
>> + /* No-op for xml */
>> +}
>> +
>> +/*
>> + * fwts_log_newline()
>> + * write newline to log
>> + */
>> +static void fwts_log_newline_xml(fwts_log *log)
>> +{
>> + /* No-op for xml */
>> +}
>> +
>> +static void fwts_log_section_begin_xml(fwts_log *log, const char *name)
>> +{
>> + xml_stack[xml_stack_index].name = name;
>> +
>> + fprintf(log->fp, "%*s<%s>\n", xml_stack_index * XML_INDENT, "",
>> name);
>> + fflush(log->fp);
>> +
>> + if (xml_stack_index< MAX_XML_STACK)
>> + xml_stack_index++;
>> + else {
>> + fprintf(stderr, "xml log stack overflow pushing section
>> %s.\n", name);
>> + exit(EXIT_FAILURE);
>> + }
>> +}
>> +
>> +static void fwts_log_section_end_xml(fwts_log *log)
>> +{
>> + if (xml_stack_index> 0) {
>> + xml_stack_index--;
>> + fprintf(log->fp, "%*s</%s>\n", xml_stack_index *
>> XML_INDENT,
>> + "", xml_stack[xml_stack_index].name);
>> + fflush(log->fp);
>> + } else {
>> + fprintf(stderr, "xml log stack underflow.\n");
>> + exit(EXIT_FAILURE);
>> + }
>> +
>> +}
>> +
>> +static void fwts_log_open_xml(fwts_log *log)
>> +{
>> + char *xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"
>> ?>\n";
>> +
>> + fwrite(xml_header, 1, strlen(xml_header), log->fp);
>> + fflush(log->fp);
>> +
>> + fwts_log_section_begin_xml(log, "fwts");
>> +}
>> +
>> +static void fwts_log_close_xml(fwts_log *log)
>> +{
>> + fwts_log_section_end_xml(log);
>> +
>> + fwrite("\n", 1, 1, log->fp);
>> + fflush(log->fp);
>> +}
>> +
>> +fwts_log_ops fwts_log_xml_ops = {
>> + .vprintf = fwts_log_vprintf_xml,
>> + .underline = fwts_log_underline_xml,
>> + .newline = fwts_log_newline_xml,
>> + .section_begin = fwts_log_section_begin_xml,
>> + .section_end = fwts_log_section_end_xml,
>> + .open = fwts_log_open_xml,
>> + .close = fwts_log_close_xml
>> +};
>
>
> Hi Colin,
>
> I've checked the xml file(results.log). It seems that it doesn't close
> properly (missing </tests> and </fwts>).
> Except that, all looks good to me. Thanks!
>
I formed another patch fixing this.
More information about the fwts-devel
mailing list