summaryrefslogtreecommitdiff
path: root/src/collectl2pcp/header.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/collectl2pcp/header.c')
-rw-r--r--src/collectl2pcp/header.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/collectl2pcp/header.c b/src/collectl2pcp/header.c
new file mode 100644
index 0000000..2bd0129
--- /dev/null
+++ b/src/collectl2pcp/header.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2013 Red Hat Inc.
+ *
+ * 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.
+ *
+ * Parse collectl header up to (and including) the first timestamp.
+ */
+
+#include "metrics.h"
+
+static char *hostname = NULL;
+int header_time = 0;
+
+int
+header_handler(FILE *fp, char *fname, char *buf, int maxbuf)
+{
+ int i;
+ char *s;
+ fields_t *f;
+ int sts = 0;
+
+
+ while(fgets(buf, maxbuf, fp)) {
+ if ((s = strrchr(buf, '\n')) != NULL)
+ *s = '\0';
+ if (!buf[0])
+ continue;
+
+ f = fields_new(buf, strlen(buf)+1);
+ if (f->nfields == 0) {
+ fields_free(f);
+ continue;
+ }
+
+ if (strncmp(f->fields[0], ">>>", 3) == 0) {
+ /* first timestamp: we're finished parsing the header */
+ sts = timestamp_handler(find_handler(">>>"), f);
+ fields_free(f);
+ break;
+ }
+
+ if (f->nfields > 3 && strncmp(f->fields[1], "Host:", 5) == 0) {
+ /* # Host: somehostname ... */
+ if (hostname && strcmp(hostname, f->fields[2]) != 0) {
+ fprintf(stderr, "FATAL Error: host mismatch: \"%s\" contains data for host \"%s\", not \"%s\"\n",
+ fname, f->fields[2], hostname);
+ exit(1);
+ }
+
+ if (!hostname) {
+ hostname = strdup(f->fields[2]);
+ pmiSetHostname(hostname);
+ put_str_value("kernel.uname.nodename", PM_INDOM_NULL, NULL, hostname);
+ put_str_value("kernel.uname.sysname", PM_INDOM_NULL, NULL, "Linux");
+ }
+ }
+
+ if (f->nfields > 2 && strncmp(f->fields[1], "Distro:", 7) == 0) {
+ strcpy(buf, f->fields[2]);
+ for (i=3; i < f->nfields; i++) {
+ if (strcmp(f->fields[i], "Platform:") == 0)
+ break;
+ strcat(buf, " ");
+ strcat(buf, f->fields[i]);
+ }
+ put_str_value("kernel.uname.distro", PM_INDOM_NULL, NULL, buf);
+
+#if 0 /* TODO -- add hinv.platform */
+ if (i < f->nfields) { /* found embedded platform */
+ strcpy(buf, f->fields[++i]);
+ for (; i < f->nfields; i++) {
+ strcat(buf, " ");
+ strcat(buf, f->fields[i]);
+ }
+ put_str_value("hinv.platform", PM_INDOM_NULL, NULL, buf);
+ }
+#endif
+ }
+
+ if (f->nfields == 7 && strncmp(f->fields[1], "Date:", 5) == 0) {
+ /* # Date: 20130505-170328 Secs: 1367791408 TZ: -0500 */
+ int d = strtol(f->fields[4], NULL, 0);
+
+ if (d < header_time) {
+ fprintf(stderr, "FATAL Error: input file order mismatch: \"%s\" contains data at %d, prior to %d\n",
+ fname, d, header_time);
+ exit(1);
+ }
+ header_time = d;
+ sts = pmiSetTimezone(f->fields[6]);
+ utc_offset = strtol(f->fields[6], NULL, 0);
+ sscanf(f->fields[6], "%d", &utc_offset); /* e.g. -0500 */
+ utc_offset /= 100;
+ if (vflag)
+ printf("Timezone set to \"%s\" utc_offset=%d hours, sts=%d\n", f->fields[6], utc_offset, sts);
+ }
+
+ if (f->nfields > 8 && strncmp(f->fields[1], "SubSys:", 7) == 0) {
+ /* # SubSys: bcdfijmnstYZ Options: Interval: 10:60 NumCPUs: 24 NumBud: 3 Flags: i */
+ put_str_value("hinv.ncpu", PM_INDOM_NULL, NULL, f->fields[7]);
+ }
+
+ if (f->nfields == 7 && strncmp(f->fields[1], "HZ:", 3) == 0) {
+ /* # HZ: 100 Arch: x86_64-linux-thread-multi PageSize: 4096 */
+ kernel_all_hz = strtol(f->fields[2], NULL, 0);
+ put_str_value("kernel.all.hz", PM_INDOM_NULL, NULL, f->fields[2]);
+ put_str_value("kernel.uname.machine", PM_INDOM_NULL, NULL, f->fields[4]);
+ put_str_value("hinv.pagesize", PM_INDOM_NULL, NULL, f->fields[6]);
+ }
+
+ if (f->nfields == 9 && strncmp(f->fields[1], "Kernel:", 7) == 0) {
+ /* # Kernel: 2.6.18-274.17.1.el5 Memory: 131965176 kB Swap: 134215000 kB */
+ put_str_value("kernel.uname.release", PM_INDOM_NULL, NULL, f->fields[2]);
+ put_int_value("hinv.physmem", PM_INDOM_NULL, NULL, atoi(f->fields[4])/1024);
+ put_str_value("hinv.machine", PM_INDOM_NULL, NULL, "linux");
+ }
+
+ if (f->nfields > 4 && strncmp(f->fields[1], "NumDisks:", 9) == 0) {
+ /* # NumDisks: 846 DiskNames: sda sdb .... */
+ put_str_value("hinv.ndisk", PM_INDOM_NULL, NULL, f->fields[2]);
+ }
+
+ if (f->nfields > 4 && strncmp(f->fields[1], "NumNets:", 8) == 0) {
+ /* # NumNets: 5 NetNames: em1: lo: ... */
+ put_str_value("hinv.ninterface", PM_INDOM_NULL, NULL, f->fields[2]);
+ }
+
+ fields_free(f);
+ }
+
+ if (vflag)
+ printf("Parsed header in file:\"%s\" host:\"%s\" sts=%d\n", fname, hostname, sts);
+
+ return sts;
+}