Merged revision 288 (addition of copyright messages to all *.[ch] files) from trunk...
authorocto <octo>
Tue, 13 Dec 2005 07:54:53 +0000 (07:54 +0000)
committerocto <octo>
Tue, 13 Dec 2005 07:54:53 +0000 (07:54 +0000)
36 files changed:
ChangeLog
contrib/museum/collection.cgi
src/collectd.c
src/cpu.c
src/cpu.h
src/cpufreq.c [new file with mode: 0644]
src/cpufreq.h [new file with mode: 0644]
src/disk.c [new file with mode: 0644]
src/disk.h [new file with mode: 0644]
src/hddtemp.c [new file with mode: 0644]
src/hddtemp.h [new file with mode: 0644]
src/load.c
src/load.h
src/memory.c [new file with mode: 0644]
src/memory.h [new file with mode: 0644]
src/nfs.c [new file with mode: 0644]
src/nfs.h [new file with mode: 0644]
src/ping.c [new file with mode: 0644]
src/ping.h [new file with mode: 0644]
src/plugin.c
src/plugin.h [new file with mode: 0644]
src/processes.c
src/processes.h [new file with mode: 0644]
src/sensors.c [new file with mode: 0644]
src/sensors.h [new file with mode: 0644]
src/serial.c [new file with mode: 0644]
src/serial.h [new file with mode: 0644]
src/swap.c [new file with mode: 0644]
src/swap.h [new file with mode: 0644]
src/tape.c [new file with mode: 0644]
src/tape.h [new file with mode: 0644]
src/traffic.c [new file with mode: 0644]
src/traffic.h [new file with mode: 0644]
src/users.c
src/users.h
src/utils_debug.c

index 5b4af8d..a5dba07 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,10 @@
        * A bug in the `load' module under Solaris has been fixed.
        * The `users' module has been contributed by Sebastian Harl. It counts
          currently logged in users.
+       * The CPU module now works under FreeBSD without the use of
+         `libstatgrab', however SMP support is missing.
+       * The default directories for the RRD files and the PID file now
+         depend on the compile time setting of `localstatedir'.
 
 2005-11-15, Version 3.4.0 (Revision 236)
        * A PID-file is written to /var/run upon startup. Thanks to `Tommie'
index b048d52..07f8dc7 100755 (executable)
@@ -521,18 +521,18 @@ our $GraphDefs;
                         'GPRINT:cpufreq_max:MAX:%5.1lf%s Max,',
                         'GPRINT:cpufreq_avg:LAST:%5.1lf%s Last\l'
                 ],
-        users => [
-            'DEF:users_avg={file}:users:AVERAGE',
-            'DEF:users_min={file}:users:MIN',
-            'DEF:users_max={file}:users:MAX',
-            "AREA:users_max#$HalfBlue",
-            "AREA:users_min#$Canvas",
-            "LINE1:users_avg#$FullBlue:Users",
-            'GPRINT:users_min:MIN:%4.1lf Min,',
-            'GPRINT:users_avg:AVERAGE:%4.1lf Average,',
-            'GPRINT:users_max:MAX:%4.1lf Max,',
-            'GPRINT:users_avg:LAST:%4.1lf Last\l'
-        ],
+               users => [
+                           'DEF:users_avg={file}:users:AVERAGE',
+                           'DEF:users_min={file}:users:MIN',
+                           'DEF:users_max={file}:users:MAX',
+                           "AREA:users_max#$HalfBlue",
+                           "AREA:users_min#$Canvas",
+                           "LINE1:users_avg#$FullBlue:Users",
+                           'GPRINT:users_min:MIN:%4.1lf Min,',
+                           'GPRINT:users_avg:AVERAGE:%4.1lf Average,',
+                           'GPRINT:users_max:MAX:%4.1lf Max,',
+                           'GPRINT:users_avg:LAST:%4.1lf Last\l'
+               ],
        };
        $GraphDefs->{'disk'} = $GraphDefs->{'partition'};
        $GraphDefs->{'meminfo'} = $GraphDefs->{'memory'};
@@ -1058,6 +1058,9 @@ sub get_all_files
                                next;
                        }
 
+                       # Only load RRD files we can actually display..
+                       next unless (defined ($GraphDefs->{$type}));
+
                        $hash->{$type} = [] unless (defined ($hash->{$type}));
                        push (@{$hash->{$type}}, $inst);
                }
index ddfb9f2..633d023 100644 (file)
@@ -1,3 +1,26 @@
+/**
+ * collectd - src/collectd.c
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ *   Alvaro Barcellos <alvaro.barcellos at gmail.com>
+ **/
+
 #include "collectd.h"
 
 #include "multicast.h"
index adafbea..830f8ac 100644 (file)
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -1,3 +1,25 @@
+/**
+ * collectd - src/cpu.c
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
 #include "cpu.h"
 
 #if COLLECT_CPU
index 340035f..fa5a710 100644 (file)
--- a/src/cpu.h
+++ b/src/cpu.h
@@ -1,3 +1,25 @@
+/**
+ * collectd - src/cpu.h
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
 #ifndef CPU_H
 #define CPU_H
 
diff --git a/src/cpufreq.c b/src/cpufreq.c
new file mode 100644 (file)
index 0000000..7a6227b
--- /dev/null
@@ -0,0 +1,140 @@
+/**
+ * collectd - src/cpufreq.c
+ * Copyright (C) 2005  Peter Holik
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Peter Holik <peter at holik.at>
+ **/
+
+#include "cpufreq.h"
+
+/*
+ * Originally written by Peter Holik
+ */
+
+#if COLLECT_CPUFREQ
+#define MODULE_NAME "cpufreq"
+
+#include "plugin.h"
+#include "common.h"
+
+static int num_cpu = 0;
+
+static char *cpufreq_file = "cpufreq-%s.rrd";
+
+static char *ds_def[] =
+{
+       "DS:value:GAUGE:25:0:U",
+       NULL
+};
+static int ds_num = 1;
+
+extern time_t curtime;
+
+#define BUFSIZE 256
+
+void cpufreq_init (void)
+{
+        int status;
+       char filename[BUFSIZE];
+
+       num_cpu = 0;
+
+       while (1)
+       {
+               status = snprintf (filename, BUFSIZE, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", num_cpu);
+               if (status < 1 || status >= BUFSIZE)
+                       break;
+
+               if (access(filename, R_OK))
+                       break;
+
+               num_cpu++;
+       }
+
+       syslog (LOG_INFO, MODULE_NAME" found %d cpu(s)", num_cpu);
+}
+
+void cpufreq_write (char *host, char *inst, char *val)
+{
+        int status;
+        char file[BUFSIZE];
+
+        status = snprintf (file, BUFSIZE, cpufreq_file, inst);
+        if (status < 1 || status >= BUFSIZE)
+                return;
+
+       rrd_update_file (host, file, val, ds_def, ds_num);
+}
+
+void cpufreq_submit (int cpu_num, unsigned long long val)
+{
+       char buf[BUFSIZE];
+       char cpu[16];
+
+       if (snprintf (buf, BUFSIZE, "%u:%llu", (unsigned int) curtime, val) >= BUFSIZE)
+               return;
+        snprintf (cpu, 16, "%i", cpu_num);
+
+       plugin_submit (MODULE_NAME, cpu, buf);
+}
+
+void cpufreq_read (void)
+{
+        int status;
+       unsigned long long val;
+       int i = 0;
+       FILE *fp;
+       char filename[BUFSIZE];
+       char buffer[16];
+
+       for (i = 0; i < num_cpu; i++)
+       {
+               status = snprintf (filename, BUFSIZE, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", i);
+               if (status < 1 || status >= BUFSIZE)
+                       return;
+
+               if ((fp = fopen (filename, "r")) == NULL)
+               {
+                       syslog (LOG_WARNING, "cpufreq: fopen: %s", strerror (errno));
+                       return;
+               }
+
+               if (fgets (buffer, 16, fp) == NULL)
+               {
+                       syslog (LOG_WARNING, "cpufreq: fgets: %s", strerror (errno));
+                       return;
+               }
+
+               if (fclose (fp))
+                       syslog (LOG_WARNING, "cpufreq: fclose: %s", strerror (errno));
+
+               /* You're seeing correctly: The file is reporting kHz values.. */
+               val = atoll (buffer) * 1000;
+
+               cpufreq_submit (i, val);
+       }
+}
+#undef BUFSIZE
+
+void module_register (void)
+{
+       plugin_register (MODULE_NAME, cpufreq_init, cpufreq_read, cpufreq_write);
+}
+
+#undef MODULE_NAME
+#endif /* COLLECT_CPUFREQ */
diff --git a/src/cpufreq.h b/src/cpufreq.h
new file mode 100644 (file)
index 0000000..9c0d41e
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * collectd - src/cpufreq.c
+ * Copyright (C) 2005  Peter Holik
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Peter Holik <peter at holik.at>
+ **/
+
+#ifndef CPUFREQ_H
+#define CPUFREQ_H
+
+#include "collectd.h"
+#include "common.h"
+
+#ifndef COLLECT_CPUFREQ
+#if defined(KERNEL_LINUX)
+#define COLLECT_CPUFREQ 1
+#else
+#define COLLECT_CPUFREQ 0
+#endif
+#endif /* !defined(COLLECT_CPUFREQ) */
+
+#endif /* CPUFREQ_H */
diff --git a/src/disk.c b/src/disk.c
new file mode 100644 (file)
index 0000000..a6a583d
--- /dev/null
@@ -0,0 +1,345 @@
+/**
+ * collectd - src/disk.c
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "disk.h"
+
+#if COLLECT_DISK
+#define MODULE_NAME "disk"
+
+#include "plugin.h"
+#include "common.h"
+
+#ifdef KERNEL_LINUX
+typedef struct diskstats
+{
+       char *name;
+
+       unsigned int read_sectors;
+       unsigned int write_sectors;
+
+       unsigned long long read_bytes;
+       unsigned long long write_bytes;
+
+       struct diskstats *next;
+} diskstats_t;
+
+static diskstats_t *disklist;
+/* KERNEL_LINUX */
+
+#elif defined(HAVE_LIBKSTAT)
+#define MAX_NUMDISK 256
+extern kstat_ctl_t *kc;
+static kstat_t *ksp[MAX_NUMDISK];
+static int numdisk = 0;
+#endif /* HAVE_LIBKSTAT */
+
+static char *disk_filename_template = "disk-%s.rrd";
+static char *part_filename_template = "partition-%s.rrd";
+
+/* 104857600 == 100 MB */
+static char *disk_ds_def[] =
+{
+       "DS:rcount:COUNTER:25:0:U",
+       "DS:rmerged:COUNTER:25:0:U",
+       "DS:rbytes:COUNTER:25:0:104857600",
+       "DS:rtime:COUNTER:25:0:U",
+       "DS:wcount:COUNTER:25:0:U",
+       "DS:wmerged:COUNTER:25:0:U",
+       "DS:wbytes:COUNTER:25:0:104857600",
+       "DS:wtime:COUNTER:25:0:U",
+       NULL
+};
+static int disk_ds_num = 8;
+
+static char *part_ds_def[] =
+{
+       "DS:rcount:COUNTER:25:0:U",
+       "DS:rbytes:COUNTER:25:0:104857600",
+       "DS:wcount:COUNTER:25:0:U",
+       "DS:wbytes:COUNTER:25:0:104857600",
+       NULL
+};
+static int part_ds_num = 4;
+
+extern time_t curtime;
+
+void disk_init (void)
+{
+#ifdef HAVE_LIBKSTAT
+       kstat_t *ksp_chain;
+
+       numdisk = 0;
+
+       if (kc == NULL)
+               return;
+
+       for (numdisk = 0, ksp_chain = kc->kc_chain;
+                       (numdisk < MAX_NUMDISK) && (ksp_chain != NULL);
+                       ksp_chain = ksp_chain->ks_next)
+       {
+               if (strncmp (ksp_chain->ks_class, "disk", 4)
+                               && strncmp (ksp_chain->ks_class, "partition", 9))
+                       continue;
+               if (ksp_chain->ks_type != KSTAT_TYPE_IO)
+                       continue;
+               ksp[numdisk++] = ksp_chain;
+       }
+#endif
+
+       return;
+}
+
+void disk_write (char *host, char *inst, char *val)
+{
+       char file[512];
+       int status;
+
+       status = snprintf (file, 512, disk_filename_template, inst);
+       if (status < 1)
+               return;
+       else if (status >= 512)
+               return;
+
+       rrd_update_file (host, file, val, disk_ds_def, disk_ds_num);
+}
+
+void partition_write (char *host, char *inst, char *val)
+{
+       char file[512];
+       int status;
+
+       status = snprintf (file, 512, part_filename_template, inst);
+       if (status < 1)
+               return;
+       else if (status >= 512)
+               return;
+
+       rrd_update_file (host, file, val, part_ds_def, part_ds_num);
+}
+
+#define BUFSIZE 512
+void disk_submit (char *disk_name,
+               unsigned long long read_count,
+               unsigned long long read_merged,
+               unsigned long long read_bytes,
+               unsigned long long read_time,
+               unsigned long long write_count,
+               unsigned long long write_merged,
+               unsigned long long write_bytes,
+               unsigned long long write_time)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%llu:%llu:%llu:%llu:%llu:%llu:%llu:%llu",
+                               (unsigned int) curtime,
+                               read_count, read_merged, read_bytes, read_time,
+                               write_count, write_merged, write_bytes,
+                               write_time) >= BUFSIZE)
+               return;
+
+       plugin_submit (MODULE_NAME, disk_name, buf);
+}
+
+void partition_submit (char *part_name,
+               unsigned long long read_count,
+               unsigned long long read_bytes,
+               unsigned long long write_count,
+               unsigned long long write_bytes)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%llu:%llu:%llu:%llu",
+                               (unsigned int) curtime,
+                               read_count, read_bytes, write_count,
+                               write_bytes) >= BUFSIZE)
+               return;
+
+       plugin_submit ("partition", part_name, buf);
+}
+#undef BUFSIZE
+
+void disk_read (void)
+{
+#ifdef KERNEL_LINUX
+       FILE *fh;
+       char buffer[1024];
+       char disk_name[128];
+       
+       char *fields[32];
+       int numfields;
+       int fieldshift = 0;
+
+       int major = 0;
+       int minor = 0;
+
+       unsigned int read_sectors;
+       unsigned int write_sectors;
+
+       unsigned long long read_count    = 0;
+       unsigned long long read_merged   = 0;
+       unsigned long long read_bytes    = 0;
+       unsigned long long read_time     = 0;
+       unsigned long long write_count   = 0;
+       unsigned long long write_merged  = 0;
+       unsigned long long write_bytes   = 0;
+       unsigned long long write_time    = 0;
+       int is_disk = 0;
+
+       diskstats_t *ds, *pre_ds;
+
+       if ((fh = fopen ("/proc/diskstats", "r")) == NULL)
+       {
+               if ((fh = fopen ("/proc/partitions", "r")) == NULL)
+                       return;
+
+               /* Kernel is 2.4.* */
+               fieldshift = 1;
+       }
+
+       while (fgets (buffer, 1024, fh) != NULL)
+       {
+               numfields = strsplit (buffer, fields, 32);
+
+               if ((numfields != (14 + fieldshift)) && (numfields != 7))
+                       continue;
+
+               major = atoll (fields[0]);
+               minor = atoll (fields[1]);
+
+               if (snprintf (disk_name, 128, "%i-%i", major, minor) < 1)
+                       continue;
+               disk_name[127] = '\0';
+
+               for (ds = disklist, pre_ds = disklist; ds != NULL; pre_ds = ds, ds = ds->next)
+                       if (strcmp (disk_name, ds->name) == 0)
+                               break;
+
+               if (ds == NULL)
+               {
+                       if ((ds = (diskstats_t *) calloc (1, sizeof (diskstats_t))) == NULL)
+                               continue;
+
+                       if ((ds->name = strdup (disk_name)) == NULL)
+                       {
+                               free (ds);
+                               continue;
+                       }
+
+                       if (pre_ds == NULL)
+                               disklist = ds;
+                       else
+                               pre_ds->next = ds;
+               }
+
+               is_disk = 0;
+               if (numfields == 7)
+               {
+                       /* Kernel 2.6, Partition */
+                       read_count    = atoll (fields[3]);
+                       read_sectors  = atoi  (fields[4]);
+                       write_count   = atoll (fields[5]);
+                       write_sectors = atoi  (fields[6]);
+               }
+               else if (numfields == (14 + fieldshift))
+               {
+                       read_count  =  atoll (fields[3 + fieldshift]);
+                       write_count =  atoll (fields[7 + fieldshift]);
+
+                       read_sectors  = atoi (fields[5 + fieldshift]);
+                       write_sectors = atoi (fields[9 + fieldshift]);
+
+                       if ((fieldshift == 0) || (minor == 0))
+                       {
+                               is_disk = 1;
+                               read_merged  = atoll (fields[4 + fieldshift]);
+                               read_time    = atoll (fields[6 + fieldshift]);
+                               write_merged = atoll (fields[8 + fieldshift]);
+                               write_time   = atoll (fields[10+ fieldshift]);
+                       }
+               }
+               else
+               {
+                       continue;
+               }
+
+
+               if (read_sectors >= ds->read_sectors)
+                       ds->read_bytes += 512 * (read_sectors - ds->read_sectors);
+               else
+                       ds->read_bytes += 512 * ((UINT_MAX - ds->read_sectors) + read_sectors);
+
+               if (write_sectors >= ds->write_sectors)
+                       ds->write_bytes += 512 * (write_sectors - ds->write_sectors);
+               else
+                       ds->write_bytes += 512 * ((UINT_MAX - ds->write_sectors) + write_sectors);
+
+               ds->read_sectors  = read_sectors;
+               ds->write_sectors = write_sectors;
+               read_bytes  = ds->read_bytes;
+               write_bytes = ds->write_bytes;
+
+
+               if ((read_count == 0) && (write_count == 0))
+                       continue;
+
+               if (is_disk)
+                       disk_submit (disk_name, read_count, read_merged, read_bytes, read_time,
+                                       write_count, write_merged, write_bytes, write_time);
+               else
+                       partition_submit (disk_name, read_count, read_bytes, write_count, write_bytes);
+       }
+
+       fclose (fh);
+/* #endif defined(KERNEL_LINUX) */
+
+#elif defined(HAVE_LIBKSTAT)
+       static kstat_io_t kio;
+       int i;
+
+       if (kc == NULL)
+               return;
+
+       for (i = 0; i < numdisk; i++)
+       {
+               if (kstat_read (kc, ksp[i], &kio) == -1)
+                       continue;
+
+               if (strncmp (ksp[i]->ks_class, "disk", 4) == 0)
+                       disk_submit (ksp[i]->ks_name,
+                                       kio.reads,  0LL, kio.nread,    kio.rtime,
+                                       kio.writes, 0LL, kio.nwritten, kio.wtime);
+               else if (strncmp (ksp[i]->ks_class, "partition", 9) == 0)
+                       partition_submit (ksp[i]->ks_name,
+                                       kio.reads, kio.nread,
+                                       kio.writes,kio.nwritten);
+       }
+#endif /* defined(HAVE_LIBKSTAT) */
+}
+
+void module_register (void)
+{
+       plugin_register ("partition", NULL, NULL, partition_write);
+       plugin_register (MODULE_NAME, disk_init, disk_read, disk_write);
+}
+
+#undef MODULE_NAME
+#endif /* COLLECT_DISK */
diff --git a/src/disk.h b/src/disk.h
new file mode 100644 (file)
index 0000000..f946963
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * collectd - src/disk.h
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#ifndef DISKSTATS_H
+#define DISKSTATS_H
+
+#include "collectd.h"
+#include "common.h"
+
+#ifndef COLLECT_DISK
+#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT)
+#define COLLECT_DISK 1
+#else
+#define COLLECT_DISK 0
+#endif
+#endif /* !defined(COLLECT_DISK) */
+
+#endif /* DISKSTATS_H */
diff --git a/src/hddtemp.c b/src/hddtemp.c
new file mode 100644 (file)
index 0000000..4b749c1
--- /dev/null
@@ -0,0 +1,374 @@
+/**
+ * collectd - src/hddtemp.c
+ * Copyright (C) 2005  Vincent Stehlé
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Vincent Stehlé <vincent.stehle at free.fr>
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "hddtemp.h"
+
+#if COLLECT_HDDTEMP
+#define MODULE_NAME "hddtemp"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h> /* for basename */
+
+#include "plugin.h"
+#include "common.h"
+
+/* LOCALHOST_ADDR
+   The ip address 127.0.0.1, as a 32 bit. */
+#define LOCALHOST_ADDR 0x7F000001
+
+/* HDDTEMP_PORT
+   The tcp port the hddtemp daemon is listening on. */
+#define HDDTEMP_PORT 7634
+
+/* BUFFER_SIZE
+   Size of the buffer we use to receive from the hddtemp daemon. */
+#define BUFFER_SIZE 1024
+
+static char *filename_format = "hddtemp-%s.rrd";
+
+static char *ds_def[] =
+{
+       "DS:value:GAUGE:25:U:U",
+       NULL
+};
+static int ds_num = 1;
+
+extern time_t curtime;
+
+typedef struct hddname
+{
+       int major;
+       int minor;
+       char *name;
+       struct hddname *next;
+} hddname_t;
+
+static hddname_t *first_hddname = NULL;
+
+/* hddtemp_query_daemon
+   Connect to the hddtemp daemon and receive data.
+
+   Parameters:
+     buffer:      the buffer where we put the received ascii string.
+     buffer_size: size of the buffer
+
+   Return value:
+     >= 0 if ok, < 0 otherwise.
+
+   Example of possible strings, as received from daemon:
+
+          |/dev/hda|ST340014A|36|C|
+          |/dev/hda|ST380011A|46|C||/dev/hdd|ST340016A|SLP|*|
+
+   FIXME: we need to create a new socket each time. Is there another way? */
+
+static int hddtemp_query_daemon (char *buffer, int buffer_size)
+{
+       int sock;
+       ssize_t size;
+       const struct sockaddr_in addr =
+       {
+               AF_INET,                        /* sin_family */
+               htons(HDDTEMP_PORT),            /* sin_port */
+               {                               /* sin_addr */
+                       htonl(LOCALHOST_ADDR),  /* s_addr */
+               }
+       };
+
+       /* create our socket descriptor */
+       if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
+       {
+               syslog (LOG_ERR, "hddtemp: could not create socket: %s", strerror (errno));
+               return (-1);
+       }
+
+       /* connect to the hddtemp daemon */
+       if (connect (sock, (const struct sockaddr *) &addr, sizeof (addr)))
+       {
+               syslog (LOG_ERR, "hddtemp: Could not connect to the hddtemp daemon: %s", strerror (errno));
+               close (sock);
+               return (-1);
+       }
+
+       /* receive data from the hddtemp daemon */
+       memset (buffer, '\0', buffer_size);
+       size = recv (sock, buffer, buffer_size, 0);
+
+       if (size >= buffer_size)
+       {
+               syslog (LOG_WARNING, "hddtemp: Message from hddtemp has been truncated.");
+               close (sock);
+               return (-1);
+       }
+       /* FIXME: Since the server closes the connection this returns zero. At
+        * least my machine does. -octo */
+       /*
+       else if (size == 0)
+       {
+               syslog (LOG_WARNING, "hddtemp: Peer has unexpectedly shut down the socket. Buffer: `%s'", buffer);
+               close (sock);
+               return (-1);
+       }
+       */
+       else if (size < 0)
+       {
+               syslog (LOG_ERR, "hddtemp: Could not receive from the hddtemp daemon: %s", strerror (errno));
+               close (sock);
+               return (-1);
+       }
+
+       close (sock);
+       return (0);
+}
+
+static void hddtemp_init (void)
+{
+       FILE *fh;
+       char buf[BUFFER_SIZE];
+       int buflen;
+
+       char *fields[16];
+       int num_fields;
+
+       int major;
+       int minor;
+       char *name;
+       hddname_t *next;
+       hddname_t *entry;
+
+       next = first_hddname;
+       while (next != NULL)
+       {
+               entry = next;
+               next = entry->next;
+
+               free (entry->name);
+               free (entry);
+       }
+       first_hddname = NULL;
+
+       if ((fh = fopen ("/proc/partitions", "r")) != NULL)
+       {
+               while (fgets (buf, BUFFER_SIZE, fh) != NULL)
+               {
+                       /* Delete trailing newlines */
+                       buflen = strlen (buf);
+                       while ((buflen > 0) && ((buf[buflen-1] == '\n') || (buf[buflen-1] == '\r')))
+                               buf[--buflen] = '\0';
+                       if (buflen == 0)
+                               continue;
+                       
+                       num_fields = strsplit (buf, fields, 16);
+
+                       if (num_fields != 4)
+                               continue;
+
+                       major = atoi (fields[0]);
+                       minor = atoi (fields[1]);
+
+                       /* I know that this makes `minor' redundant, but I want
+                        * to be able to change this beavior in the future..
+                        * And 4 or 8 bytes won't hurt anybody.. -octo */
+                       if (major == 0)
+                               continue;
+                       if (minor != 0)
+                               continue;
+
+                       if ((name = strdup (fields[3])) == NULL)
+                               continue;
+
+                       if ((entry = (hddname_t *) malloc (sizeof (hddname_t))) == NULL)
+                       {
+                               free (name);
+                               continue;
+                       }
+
+                       entry->major = major;
+                       entry->minor = minor;
+                       entry->name  = name;
+                       entry->next  = NULL;
+
+                       if (first_hddname == NULL)
+                       {
+                               first_hddname = entry;
+                       }
+                       else
+                       {
+                               entry->next = first_hddname;
+                               first_hddname = entry;
+                       }
+               }
+       }
+
+       return;
+}
+
+static void hddtemp_write (char *host, char *inst, char *val)
+{
+       char filename[BUFFER_SIZE];
+       int status;
+
+       /* construct filename */
+       status = snprintf (filename, BUFFER_SIZE, filename_format, inst);
+       if (status < 1)
+               return;
+       else if (status >= BUFFER_SIZE)
+               return;
+
+       rrd_update_file (host, filename, val, ds_def, ds_num);
+}
+
+static char *hddtemp_get_name (char *drive)
+{
+       hddname_t *list;
+       char *ret;
+
+       for (list = first_hddname; list != NULL; list = list->next)
+               if (strcmp (drive, list->name) == 0)
+                       break;
+
+       if (list == NULL)
+               return (strdup (drive));
+
+       if ((ret = (char *) malloc (128 * sizeof (char))) == NULL)
+               return (NULL);
+
+       if (snprintf (ret, 128, "%i-%i", list->major, list->minor) >= 128)
+       {
+               free (ret);
+               return (NULL);
+       }
+
+       return (ret);
+}
+
+static void hddtemp_submit (char *inst, double temperature)
+{
+       char buf[BUFFER_SIZE];
+
+       if (snprintf (buf, BUFFER_SIZE, "%u:%.3f", (unsigned int) curtime, temperature) >= BUFFER_SIZE)
+               return;
+
+       plugin_submit (MODULE_NAME, inst, buf);
+}
+
+static void hddtemp_read (void)
+{
+       char buf[BUFFER_SIZE];
+       char *fields[128];
+       char *ptr;
+       int num_fields;
+       int num_disks;
+       int i;
+
+       static int wait_time = 1;
+       static int wait_left = 0;
+
+       if (wait_left >= 10)
+       {
+               wait_left -= 10;
+               return;
+       }
+
+       /* get data from daemon */
+       if (hddtemp_query_daemon (buf, BUFFER_SIZE) < 0)
+       {
+               /* This limit is reached in log2(86400) =~ 17 steps. Since
+                * there is a 2^n seconds wait between each step it will need
+                * roughly one day to reach this limit. -octo */
+               
+               wait_time *= 2;
+               if (wait_time > 86400)
+                       wait_time = 86400;
+
+               wait_left = wait_time;
+
+               return;
+       }
+       else
+       {
+               wait_time = 1;
+               wait_left = 0;
+       }
+
+       /* NB: strtok will eat up "||" and leading "|"'s */
+       num_fields = 0;
+       ptr = buf;
+       while ((fields[num_fields] = strtok (ptr, "|")) != NULL)
+       {
+               ptr = NULL;
+               num_fields++;
+
+               if (num_fields >= 128)
+                       break;
+       }
+
+       num_disks = num_fields / 4;
+
+       for (i = 0; i < num_disks; i++)
+       {
+               char *name, *submit_name;
+               double temperature;
+               char *mode;
+
+               mode = fields[4*i + 3];
+
+               /* Skip non-temperature information */
+               if (mode[0] != 'C' && mode[0] != 'F')
+                       continue;
+
+               name = basename (fields[4*i + 0]);
+               temperature = atof (fields[4*i + 2]);
+
+               /* Convert farenheit to celsius */
+               if (mode[0] == 'F')
+                       temperature = (temperature - 32.0) * 5.0 / 9.0;
+
+               if ((submit_name = hddtemp_get_name (name)) != NULL)
+               {
+                       hddtemp_submit (submit_name, temperature);
+                       free (submit_name);
+               }
+               else
+               {
+                       hddtemp_submit (name, temperature);
+               }
+       }
+}
+
+/* module_register
+   Register collectd plugin. */
+void module_register (void)
+{
+       plugin_register (MODULE_NAME, hddtemp_init, hddtemp_read, hddtemp_write);
+}
+
+#endif /* COLLECT_HDDTEMP */
diff --git a/src/hddtemp.h b/src/hddtemp.h
new file mode 100644 (file)
index 0000000..aaf0191
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * collectd - src/hddtemp.c
+ * Copyright (C) 2005  Vincent Stehlé
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Vincent Stehlé <vincent.stehle at free.fr>
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#ifndef HDDTEMP_H
+#define HDDTEMP_H
+
+#include "collectd.h"
+#include "common.h"
+
+#ifndef COLLECT_HDDTEMP
+#define COLLECT_HDDTEMP 1
+#endif
+
+#endif /* HDDTEMP_H */
index 2a14edd..7b3462b 100644 (file)
@@ -1,3 +1,25 @@
+/**
+ * collectd - src/load.c
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
 #include "load.h"
 
 #if COLLECT_LOAD
index ce437eb..651d1d6 100644 (file)
@@ -1,3 +1,25 @@
+/**
+ * collectd - src/load.h
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
 #ifndef LOAD_H
 #define LOAD_H
 
diff --git a/src/memory.c b/src/memory.c
new file mode 100644 (file)
index 0000000..3291bc8
--- /dev/null
@@ -0,0 +1,175 @@
+/**
+ * collectd - src/memory.c
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "memory.h"
+
+#if COLLECT_MEMORY
+#define MODULE_NAME "memory"
+
+#include "plugin.h"
+#include "common.h"
+
+static char *memory_file = "memory.rrd";
+
+/* 9223372036854775807 == LLONG_MAX */
+static char *ds_def[] =
+{
+       "DS:used:GAUGE:25:0:9223372036854775807",
+       "DS:free:GAUGE:25:0:9223372036854775807",
+       "DS:buffers:GAUGE:25:0:9223372036854775807",
+       "DS:cached:GAUGE:25:0:9223372036854775807",
+       NULL
+};
+static int ds_num = 4;
+
+#ifdef HAVE_LIBKSTAT
+static int pagesize;
+static kstat_t *ksp;
+#endif /* HAVE_LIBKSTAT */
+
+extern time_t curtime;
+
+void memory_init (void)
+{
+#ifdef HAVE_LIBKSTAT
+       /* getpagesize(3C) tells me this does not fail.. */
+       pagesize = getpagesize ();
+       if (get_kstat (&ksp, "unix", 0, "system_pages"))
+               ksp = NULL;
+#endif /* HAVE_LIBKSTAT */
+
+       return;
+}
+
+void memory_write (char *host, char *inst, char *val)
+{
+       rrd_update_file (host, memory_file, val, ds_def, ds_num);
+}
+
+#define BUFSIZE 512
+void memory_submit (long long mem_used, long long mem_buffered,
+               long long mem_cached, long long mem_free)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%lli:%lli:%lli:%lli",
+                               (unsigned int) curtime, mem_used, mem_free,
+                               mem_buffered, mem_cached) >= BUFSIZE)
+               return;
+
+       plugin_submit (MODULE_NAME, "-", buf);
+}
+#undef BUFSIZE
+
+void memory_read (void)
+{
+#ifdef KERNEL_LINUX
+       FILE *fh;
+       char buffer[1024];
+       
+       char *fields[8];
+       int numfields;
+
+       long long mem_used = 0;
+       long long mem_buffered = 0;
+       long long mem_cached = 0;
+       long long mem_free = 0;
+
+       if ((fh = fopen ("/proc/meminfo", "r")) == NULL)
+       {
+               syslog (LOG_WARNING, "memory: fopen: %s", strerror (errno));
+               return;
+       }
+
+       while (fgets (buffer, 1024, fh) != NULL)
+       {
+               long long *val = NULL;
+
+               if (strncasecmp (buffer, "MemTotal:", 9) == 0)
+                       val = &mem_used;
+               else if (strncasecmp (buffer, "MemFree:", 8) == 0)
+                       val = &mem_free;
+               else if (strncasecmp (buffer, "Buffers:", 8) == 0)
+                       val = &mem_buffered;
+               else if (strncasecmp (buffer, "Cached:", 7) == 0)
+                       val = &mem_cached;
+               else
+                       continue;
+
+               numfields = strsplit (buffer, fields, 8);
+
+               if (numfields < 2)
+                       continue;
+
+               *val = atoll (fields[1]) * 1024LL;
+       }
+
+       if (fclose (fh))
+               syslog (LOG_WARNING, "memory: fclose: %s", strerror (errno));
+
+       if (mem_used >= (mem_free + mem_buffered + mem_cached))
+       {
+               mem_used -= mem_free + mem_buffered + mem_cached;
+               memory_submit (mem_used, mem_buffered, mem_cached, mem_free);
+       }
+/* #endif defined(KERNEL_LINUX) */
+
+#elif defined(HAVE_LIBKSTAT)
+       long long mem_used;
+       long long mem_free;
+       long long mem_lock;
+
+       if (ksp == NULL)
+               return;
+
+       mem_used = get_kstat_value (ksp, "pagestotal");
+       mem_free = get_kstat_value (ksp, "pagesfree");
+       mem_lock = get_kstat_value (ksp, "pageslocked");
+
+       if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL))
+               return;
+       if (mem_used < (mem_free + mem_lock))
+               return;
+
+       mem_used -= mem_free + mem_lock;
+       mem_used *= pagesize; /* If this overflows you have some serious */
+       mem_free *= pagesize; /* memory.. Why not call me up and give me */
+       mem_lock *= pagesize; /* some? ;) */
+
+       memory_submit (mem_used, mem_lock, 0LL, mem_free);
+/* #endif defined(HAVE_LIBKSTAT) */
+
+#elif defined(HAVE_LIBSTATGRAB)
+       sg_mem_stats *ios;
+
+       if ((ios = sg_get_mem_stats ()) != NULL)
+               memory_submit (ios->used, 0LL, ios->cache, ios->free);
+#endif /* HAVE_LIBSTATGRAB */
+}
+
+void module_register (void)
+{
+       plugin_register (MODULE_NAME, memory_init, memory_read, memory_write);
+}
+
+#undef MODULE_NAME
+#endif /* COLLECT_MEMORY */
diff --git a/src/memory.h b/src/memory.h
new file mode 100644 (file)
index 0000000..c457110
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * collectd - src/memory.h
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#ifndef MEMINFO_H
+#define MEMINFO_H
+
+#include "collectd.h"
+#include "common.h"
+
+#ifndef COLLECT_MEMORY
+#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_LIBSTATGRAB)
+#define COLLECT_MEMORY 1
+#else
+#define COLLECT_MEMORY 0
+#endif
+#endif /* !defined(COLLECT_MEMORY) */
+
+#endif /* MEMINFO_H */
diff --git a/src/nfs.c b/src/nfs.c
new file mode 100644 (file)
index 0000000..d21685c
--- /dev/null
+++ b/src/nfs.c
@@ -0,0 +1,391 @@
+/**
+ * collectd - src/nfs.c
+ * Copyright (C) 2005  Jason Pepas
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Jason Pepas <cell at ices.utexas.edu>
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "nfs.h"
+
+#if COLLECT_NFS
+#define MODULE_NAME "nfs"
+
+#include "plugin.h"
+#include "common.h"
+
+static char *nfs2_procedures_file  = "nfs2_procedures-%s.rrd";
+static char *nfs3_procedures_file  = "nfs3_procedures-%s.rrd";
+
+/*
+see /proc/net/rpc/nfs
+see http://www.missioncriticallinux.com/orph/NFS-Statistics
+
+net x x x x
+rpc_stat.netcnt         Not used; always zero.
+rpc_stat.netudpcnt      Not used; always zero.
+rpc_stat.nettcpcnt      Not used; always zero.
+rpc_stat.nettcpconn     Not used; always zero.
+
+rpc x x x
+rpc_stat.rpccnt             The number of RPC calls.
+rpc_stat.rpcretrans         The number of retransmitted RPC calls.
+rpc_stat.rpcauthrefresh     The number of credential refreshes.
+
+proc2 x x x...
+proc3 x x x...
+
+Procedure   NFS Version NFS Version 3
+Number      Procedures  Procedures
+
+0           null        null
+1           getattr     getattr
+2           setattr     setattr
+3           root        lookup
+4           lookup      access
+5           readlink    readlink
+6           read        read
+7           wrcache     write
+8           write       create
+9           create      mkdir
+10          remove      symlink
+11          rename      mknod
+12          link        remove
+13          symlink     rmdir
+14          mkdir       rename
+15          rmdir       link
+16          readdir     readdir
+17          fsstat      readdirplus
+18                      fsstat
+19                      fsinfo
+20                      pathconf
+21                      commit
+*/
+
+static char *nfs2_procedures_ds_def[] =
+{
+       "DS:null:COUNTER:25:0:U",
+       "DS:getattr:COUNTER:25:0:U",
+       "DS:setattr:COUNTER:25:0:U",
+       "DS:root:COUNTER:25:0:U",
+       "DS:lookup:COUNTER:25:0:U",
+       "DS:readlink:COUNTER:25:0:U",
+       "DS:read:COUNTER:25:0:U",
+       "DS:wrcache:COUNTER:25:0:U",
+       "DS:write:COUNTER:25:0:U",
+       "DS:create:COUNTER:25:0:U",
+       "DS:remove:COUNTER:25:0:U",
+       "DS:rename:COUNTER:25:0:U",
+       "DS:link:COUNTER:25:0:U",
+       "DS:symlink:COUNTER:25:0:U",
+       "DS:mkdir:COUNTER:25:0:U",
+       "DS:rmdir:COUNTER:25:0:U",
+       "DS:readdir:COUNTER:25:0:U",
+       "DS:fsstat:COUNTER:25:0:U",
+       NULL
+};
+static int nfs2_procedures_ds_num = 18;
+
+static char *nfs3_procedures_ds_def[] =
+{
+       "DS:null:COUNTER:25:0:U",
+       "DS:getattr:COUNTER:25:0:U",
+       "DS:setattr:COUNTER:25:0:U",
+       "DS:lookup:COUNTER:25:0:U",
+       "DS:access:COUNTER:25:0:U",
+       "DS:readlink:COUNTER:25:0:U",
+       "DS:read:COUNTER:25:0:U",
+       "DS:write:COUNTER:25:0:U",
+       "DS:create:COUNTER:25:0:U",
+       "DS:mkdir:COUNTER:25:0:U",
+       "DS:symlink:COUNTER:25:0:U",
+       "DS:mknod:COUNTER:25:0:U",
+       "DS:remove:COUNTER:25:0:U",
+       "DS:rmdir:COUNTER:25:0:U",
+       "DS:rename:COUNTER:25:0:U",
+       "DS:link:COUNTER:25:0:U",
+       "DS:readdir:COUNTER:25:0:U",
+       "DS:readdirplus:COUNTER:25:0:U",
+       "DS:fsstat:COUNTER:25:0:U",
+       "DS:fsinfo:COUNTER:25:0:U",
+       "DS:pathconf:COUNTER:25:0:U",
+       "DS:commit:COUNTER:25:0:U",
+       NULL
+};
+static int nfs3_procedures_ds_num = 22;
+
+#ifdef HAVE_LIBKSTAT
+extern kstat_ctl_t *kc;
+static kstat_t *nfs2_ksp_client;
+static kstat_t *nfs2_ksp_server;
+static kstat_t *nfs3_ksp_client;
+static kstat_t *nfs3_ksp_server;
+static kstat_t *nfs4_ksp_client;
+static kstat_t *nfs4_ksp_server;
+#endif
+
+/* Possibly TODO: NFSv4 statistics */
+
+extern time_t curtime;
+
+void nfs_init (void)
+{
+#ifdef HAVE_LIBKSTAT
+       kstat_t *ksp_chain;
+
+       nfs2_ksp_client = NULL;
+       nfs2_ksp_server = NULL;
+       nfs3_ksp_client = NULL;
+       nfs3_ksp_server = NULL;
+       nfs4_ksp_client = NULL;
+       nfs4_ksp_server = NULL;
+       
+       if (kc == NULL)
+               return;
+
+       for (ksp_chain = kc->kc_chain; ksp_chain != NULL;
+                       ksp_chain = ksp_chain->ks_next)
+       {
+               if (strncmp (ksp_chain->ks_module, "nfs", 3) != 0)
+                       continue;
+               else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v2", 13) == 0)
+                       nfs2_ksp_server = ksp_chain;
+               else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v3", 13) == 0)
+                       nfs3_ksp_server = ksp_chain;
+               else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v4", 13) == 0)
+                       nfs4_ksp_server = ksp_chain;
+               else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v2", 12) == 0)
+                       nfs2_ksp_client = ksp_chain;
+               else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v3", 12) == 0)
+                       nfs3_ksp_client = ksp_chain;
+               else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v4", 12) == 0)
+                       nfs4_ksp_client = ksp_chain;
+       }
+#endif
+
+       return;
+}
+
+#define BUFSIZE 1024
+void nfs2_procedures_write (char *host, char *inst, char *val)
+{
+       char filename[BUFSIZE];
+
+       if (snprintf (filename, BUFSIZE, nfs2_procedures_file, inst) > BUFSIZE)
+               return;
+
+       rrd_update_file (host, filename, val, nfs2_procedures_ds_def,
+                       nfs2_procedures_ds_num);
+}
+
+void nfs3_procedures_write (char *host, char *inst, char *val)
+{
+       char filename[BUFSIZE];
+
+       if (snprintf (filename, BUFSIZE, nfs3_procedures_file, inst) > BUFSIZE)
+               return;
+
+       rrd_update_file (host, filename, val, nfs3_procedures_ds_def,
+                       nfs3_procedures_ds_num);
+}
+
+void nfs2_procedures_submit (unsigned long long *val, char *inst)
+{
+       char buf[BUFSIZE];
+       int retval = 0;
+
+       retval = snprintf (buf, BUFSIZE, "%u:%llu:%llu:%llu:%llu:%llu:%llu:"
+                       "%llu:%llu:%llu:%llu:%llu:%llu:%llu:%llu:%llu:"
+                       "%llu:%llu:%llu", /* 18x %llu */
+                       (unsigned int) curtime,
+                       val[0], val[1], val[2], val[3], val[4], val[5], val[6],
+                       val[7], val[8], val[9], val[10], val[11], val[12],
+                       val[13], val[14], val[15], val[16], val[17]);
+
+
+       if (retval >= BUFSIZE)
+               return;
+       else if (retval < 0)
+       {
+               syslog (LOG_ERR, "nfs: snprintf's format failed: %s", strerror (errno));
+               return;
+       }
+
+       plugin_submit ("nfs2_procedures", inst, buf);
+}
+
+void nfs3_procedures_submit (unsigned long long *val, char *inst)
+{
+       char buf[BUFSIZE];
+       int retval = 0;
+
+       retval = snprintf(buf, BUFSIZE, "%u:%llu:%llu:%llu:%llu:%llu:%llu:"
+                       "%llu:%llu:%llu:%llu:%llu:%llu:%llu:%llu:%llu:"
+                       "%llu:%llu:%llu:%llu:%llu:%llu:%llu", /* 22x %llu */
+                       (unsigned int) curtime,
+                       val[0], val[1], val[2], val[3], val[4], val[5], val[6],
+                       val[7], val[8], val[9], val[10], val[11], val[12],
+                       val[13], val[14], val[15], val[16], val[17], val[18],
+                       val[19], val[20], val[21]);
+
+       if (retval >= BUFSIZE)
+               return;
+       else if (retval < 0)
+       {
+               syslog (LOG_ERR, "nfs: snprintf's format failed: %s", strerror (errno));
+               return;
+       }
+
+       plugin_submit("nfs3_procedures", inst, buf);
+}
+
+#if defined(KERNEL_LINUX)
+void nfs_read_stats_file (FILE *fh, char *inst)
+{
+       char buffer[BUFSIZE];
+
+       char *fields[48];
+       int numfields = 0;
+
+       if (fh == NULL)
+               return;
+
+       while (fgets (buffer, BUFSIZE, fh) != NULL)
+       {
+               numfields = strsplit (buffer, fields, 48);
+
+               if (numfields < 2)
+                       continue;
+
+               if (strncmp (fields[0], "proc2", 5) == 0)
+               {
+                       int i;
+                       unsigned long long *values;
+
+                       if (numfields - 2 != nfs2_procedures_ds_num)
+                       {
+                               syslog (LOG_WARNING, "nfs: Wrong number of fields (= %i) for NFS2 statistics.", numfields - 2);
+                               continue;
+                       }
+
+                       if ((values = (unsigned long long *) malloc (nfs2_procedures_ds_num * sizeof (unsigned long long))) == NULL)
+                       {
+                               syslog (LOG_ERR, "nfs: malloc: %s", strerror (errno));
+                               continue;
+                       }
+
+                       for (i = 0; i < nfs2_procedures_ds_num; i++)
+                               values[i] = atoll (fields[i + 2]);
+
+                       nfs2_procedures_submit (values, inst);
+
+                       free (values);
+               }
+               else if (strncmp (fields[0], "proc3", 5) == 0)
+               {
+                       int i;
+                       unsigned long long *values;
+
+                       if (numfields - 2 != nfs3_procedures_ds_num)
+                       {
+                               syslog (LOG_WARNING, "nfs: Wrong number of fields (= %i) for NFS3 statistics.", numfields - 2);
+                               continue;
+                       }
+
+                       if ((values = (unsigned long long *) malloc (nfs3_procedures_ds_num * sizeof (unsigned long long))) == NULL)
+                       {
+                               syslog (LOG_ERR, "nfs: malloc: %s", strerror (errno));
+                               continue;
+                       }
+
+                       for (i = 0; i < nfs3_procedures_ds_num; i++)
+                               values[i] = atoll (fields[i + 2]);
+
+                       nfs3_procedures_submit (values, inst);
+
+                       free (values);
+               }
+       }
+}
+#endif /* defined(KERNEL_LINUX) */
+#undef BUFSIZE
+
+#ifdef HAVE_LIBKSTAT
+void nfs2_read_kstat (kstat_t *ksp, char *inst)
+{
+       unsigned long long values[18];
+
+       values[0] = get_kstat_value (ksp, "null");
+       values[1] = get_kstat_value (ksp, "getattr");
+       values[2] = get_kstat_value (ksp, "setattr");
+       values[3] = get_kstat_value (ksp, "root");
+       values[4] = get_kstat_value (ksp, "lookup");
+       values[5] = get_kstat_value (ksp, "readlink");
+       values[6] = get_kstat_value (ksp, "read");
+       values[7] = get_kstat_value (ksp, "wrcache");
+       values[8] = get_kstat_value (ksp, "write");
+       values[9] = get_kstat_value (ksp, "create");
+       values[10] = get_kstat_value (ksp, "remove");
+       values[11] = get_kstat_value (ksp, "rename");
+       values[12] = get_kstat_value (ksp, "link");
+       values[13] = get_kstat_value (ksp, "symlink");
+       values[14] = get_kstat_value (ksp, "mkdir");
+       values[15] = get_kstat_value (ksp, "rmdir");
+       values[16] = get_kstat_value (ksp, "readdir");
+       values[17] = get_kstat_value (ksp, "statfs");
+
+       nfs2_procedures_submit (values, inst);
+}
+#endif
+
+void nfs_read (void)
+{
+#if defined(KERNEL_LINUX)
+       FILE *fh;
+
+       if ((fh = fopen ("/proc/net/rpc/nfs", "r")) != NULL)
+       {
+               nfs_read_stats_file (fh, "client");
+               fclose (fh);
+       }
+
+       if ((fh = fopen ("/proc/net/rpc/nfsd", "r")) != NULL)
+       {
+               nfs_read_stats_file (fh, "server");
+               fclose (fh);
+       }
+
+/* #endif defined(KERNEL_LINUX) */
+
+#elif defined(HAVE_LIBKSTAT)
+       if (nfs2_ksp_client != NULL)
+               nfs2_read_kstat (nfs2_ksp_client, "client");
+       if (nfs2_ksp_server != NULL)
+               nfs2_read_kstat (nfs2_ksp_server, "server");
+#endif /* defined(HAVE_LIBKSTAT) */
+}
+
+void module_register (void)
+{
+    plugin_register (MODULE_NAME, nfs_init, nfs_read, NULL);
+    plugin_register ("nfs2_procedures", NULL, NULL, nfs2_procedures_write);
+    plugin_register ("nfs3_procedures", NULL, NULL, nfs3_procedures_write);
+}
+
+#undef MODULE_NAME
+#endif /* COLLECT_LOAD */
diff --git a/src/nfs.h b/src/nfs.h
new file mode 100644 (file)
index 0000000..ae752be
--- /dev/null
+++ b/src/nfs.h
@@ -0,0 +1,37 @@
+/**
+ * collectd - src/nfs.h
+ * Copyright (C) 2005  Jason Pepas
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Jason Pepas <cell at ices.utexas.edu>
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#ifndef NFS_H
+#define NFS_H
+
+#include "collectd.h"
+
+#ifndef COLLECT_NFS
+#if defined(KERNEL_LINUX)
+#define COLLECT_NFS 1
+#else
+#define COLLECT_NFS 0
+#endif
+#endif /* !defined(COLLECT_NFS) */
+
+#endif /* NFS_H */
diff --git a/src/ping.c b/src/ping.c
new file mode 100644 (file)
index 0000000..eb35360
--- /dev/null
@@ -0,0 +1,137 @@
+/**
+ * collectd - src/ping.c
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "ping.h"
+
+#if COLLECT_PING
+#define MODULE_NAME "ping"
+
+#include "plugin.h"
+#include "common.h"
+
+#include <netinet/in.h>
+#include "libping/ping.h"
+
+extern char *pinghosts[MAX_PINGHOSTS];
+extern int   num_pinghosts;
+static int   pingerrors[MAX_PINGHOSTS];
+
+static char *file_template = "ping-%s.rrd";
+
+static char *ds_def[] = 
+{
+       "DS:ping:GAUGE:25:0:65535",
+       NULL
+};
+static int ds_num = 1;
+
+extern time_t curtime;
+
+void ping_init (void)
+{
+       int i;
+
+       for (i = 0; i < num_pinghosts; i++)
+               pingerrors[i] = 0;
+
+       return;
+}
+
+void ping_write (char *host, char *inst, char *val)
+{
+       char file[512];
+       int status;
+
+       status = snprintf (file, 512, file_template, inst);
+       if (status < 1)
+               return;
+       else if (status >= 512)
+               return;
+
+       rrd_update_file (host, file, val, ds_def, ds_num);
+}
+
+#define BUFSIZE 256
+void ping_submit (int ping_time, char *host)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%u", (unsigned int) curtime, ping_time) >= BUFSIZE)
+               return;
+
+       plugin_submit (MODULE_NAME, host, buf);
+}
+#undef BUFSIZE
+
+void ping_read (void)
+{
+       int ping;
+       int i;
+
+       for (i = 0; i < num_pinghosts; i++)
+       {
+               if (pingerrors[i] & 0x30)
+                       continue;
+               
+               ping = tpinghost (pinghosts[i]);
+
+               switch (ping)
+               {
+                       case 0:
+                               if (!(pingerrors[i] & 0x01))
+                                       syslog (LOG_WARNING, "ping %s: Connection timed out.", pinghosts[i]);
+                               pingerrors[i] |= 0x01;
+                               break;
+
+                       case -1:
+                               if (!(pingerrors[i] & 0x02))
+                                       syslog (LOG_WARNING, "ping %s: Host or service is not reachable.", pinghosts[i]);
+                               pingerrors[i] |= 0x02;
+                               break;
+
+                       case -2:
+                               syslog (LOG_ERR, "ping %s: Socket error. Ping will be disabled.", pinghosts[i]);
+                               pingerrors[i] |= 0x10;
+                               break;
+
+                       case -3:
+                               if (!(pingerrors[i] & 0x04))
+                                       syslog (LOG_WARNING, "ping %s: Connection refused.", pinghosts[i]);
+                               pingerrors[i] |= 0x04;
+                               break;
+
+                       default:
+                               if (pingerrors[i] != 0x00)
+                                       syslog (LOG_NOTICE, "ping %s: Back to normal: %ims.", pinghosts[i], ping);
+                               pingerrors[i] = 0x00;
+                               ping_submit (ping, pinghosts[i]);
+               } /* switch (ping) */
+       } /* for (i = 0; i < num_pinghosts; i++) */
+}
+
+void module_register (void)
+{
+       plugin_register (MODULE_NAME, ping_init, ping_read, ping_write);
+}
+
+#undef MODULE_NAME
+#endif /* COLLECT_PING */
diff --git a/src/ping.h b/src/ping.h
new file mode 100644 (file)
index 0000000..c5f26c4
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * collectd - src/ping.h
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#ifndef COLLECTD_PING_H
+#define COLLECTD_PING_H
+
+#include "collectd.h"
+#include "common.h"
+
+#ifndef COLLECT_PING
+#if defined(HAVE_NETINET_IN_H)
+#define COLLECT_PING 1
+#else
+#define COLLECT_PING 0
+#endif /* defined(HAVE_NETINET_IN_H) */
+#endif /* !defined(COLLECT_PING) */
+
+#if COLLECT_PING
+
+#define MAX_PINGHOSTS 32
+
+#endif /* COLLECT_PING */
+#endif
index 20735ba..a6792de 100644 (file)
@@ -1,3 +1,25 @@
+/**
+ * collectd - src/plugin.c
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
 #include "collectd.h"
 
 #include <ltdl.h>
diff --git a/src/plugin.h b/src/plugin.h
new file mode 100644 (file)
index 0000000..4a8b7ad
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * collectd - src/plugin.h
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#ifndef PLUGIN_H
+#define PLUGIN_H
+
+int  plugin_load_all (char *dir);
+void plugin_init_all (void);
+void plugin_read_all (void);
+
+void plugin_register (char *type,
+               void (*init) (void),
+               void (*read) (void),
+               void (*write) (char *, char *, char *));
+#ifdef HAVE_LIBRRD
+void plugin_write    (char *host, char *type, char *inst, char *val);
+#endif /* HAVE_LIBRRD */
+void plugin_submit   (char *type, char *inst, char *val);
+
+#endif /* PLUGIN_H */
index 94e86dd..fcf9197 100644 (file)
@@ -1,8 +1,27 @@
-#include "processes.h"
+/**
+ * collectd - src/processes.c
+ * Copyright (C) 2005  Lyonel Vincent
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Lyonel Vincent <lyonel at ezix.org>
+ *   Florian octo Forster <octo at verplant.org>
+ **/
 
-/*
- * Originally written by Lyonel Vincent
- */
+#include "processes.h"
 
 #if COLLECT_PROCESSES
 #define MODULE_NAME "processes"
diff --git a/src/processes.h b/src/processes.h
new file mode 100644 (file)
index 0000000..db8446a
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * collectd - src/processes.h
+ * Copyright (C) 2005  Lyonel Vincent
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Lyonel Vincent <lyonel at ezix.org>
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#ifndef PROCESSES_H
+#define PROCESSES_H
+
+#include "collectd.h"
+#include "common.h"
+
+#ifndef COLLECT_PROCESSES
+#if defined(KERNEL_LINUX)
+#define COLLECT_PROCESSES 1
+#else
+#define COLLECT_PROCESSES 0
+#endif
+#endif /* !defined(COLLECT_PROCESSES) */
+
+#endif /* PROCESSES_H */
diff --git a/src/sensors.c b/src/sensors.c
new file mode 100644 (file)
index 0000000..390a7a0
--- /dev/null
@@ -0,0 +1,189 @@
+/**
+ * collectd - src/sensors.c
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "sensors.h"
+
+#if COLLECT_SENSORS
+#define MODULE_NAME "sensors"
+
+#include <sensors/sensors.h>
+
+#include "plugin.h"
+#include "common.h"
+
+typedef struct featurelist
+{
+       const sensors_chip_name    *chip;
+       const sensors_feature_data *data;
+       struct featurelist         *next;
+} featurelist_t;
+
+featurelist_t *first_feature = NULL;
+
+static char *filename_format = "sensors-%s.rrd";
+
+static char *ds_def[] =
+{
+       "DS:value:GAUGE:25:U:U",
+       NULL
+};
+static int ds_num = 1;
+
+extern time_t curtime;
+
+void collectd_sensors_init (void)
+{
+       FILE *fh;
+       featurelist_t *last_feature = NULL;
+       featurelist_t *new_feature;
+       
+       const sensors_chip_name *chip;
+       int chip_num;
+
+       const sensors_feature_data *data;
+       int data_num0, data_num1;
+       
+       new_feature = first_feature;
+       while (new_feature != NULL)
+       {
+               last_feature = new_feature->next;
+               free (new_feature);
+               new_feature = last_feature;
+       }
+
+#ifdef assert
+       assert (new_feature == NULL);
+       assert (last_feature == NULL);
+#endif
+
+       if ((fh = fopen ("/etc/sensors.conf", "r")) == NULL)
+               return;
+
+       if (sensors_init (fh))
+       {
+               fclose (fh);
+               syslog (LOG_ERR, "sensors: Cannot initialize sensors. Data will not be collected.");
+               return;
+       }
+
+       fclose (fh);
+
+       chip_num = 0;
+       while ((chip = sensors_get_detected_chips (&chip_num)) != NULL)
+       {
+               data = NULL;
+               data_num0 = data_num1 = 0;
+
+               while ((data = sensors_get_all_features (*chip, &data_num0, &data_num1)) != NULL)
+               {
+                       /* "master features" only */
+                       if (data->mapping != SENSORS_NO_MAPPING)
+                               continue;
+
+                       /* Only temperature for now.. */
+                       if (strncmp (data->name, "temp", 4)
+                                       && strncmp (data->name, "fan", 3))
+                               continue;
+
+                       if ((new_feature = (featurelist_t *) malloc (sizeof (featurelist_t))) == NULL)
+                       {
+                               perror ("malloc");
+                               continue;
+                       }
+
+                       /*
+                       syslog (LOG_INFO, "sensors: Adding feature: %s/%s", chip->prefix, data->name);
+                       */
+
+                       new_feature->chip = chip;
+                       new_feature->data = data;
+                       new_feature->next = NULL;
+
+                       if (first_feature == NULL)
+                       {
+                               first_feature = new_feature;
+                               last_feature  = new_feature;
+                       }
+                       else
+                       {
+                               last_feature->next = new_feature;
+                               last_feature = new_feature;
+                       }
+               }
+       }
+
+       if (first_feature == NULL)
+               sensors_cleanup ();
+}
+
+void sensors_write (char *host, char *inst, char *val)
+{
+       char file[512];
+       int status;
+
+       status = snprintf (file, 512, filename_format, inst);
+       if (status < 1)
+               return;
+       else if (status >= 512)
+               return;
+
+       rrd_update_file (host, file, val, ds_def, ds_num);
+}
+
+#define BUFSIZE 512
+void sensors_submit (const char *feat_name, const char *chip_prefix, double value)
+{
+       char buf[BUFSIZE];
+       char inst[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%.3f", (unsigned int) curtime, value) >= BUFSIZE)
+               return;
+
+       if (snprintf (inst, BUFSIZE, "%s-%s", chip_prefix, feat_name) >= BUFSIZE)
+               return;
+
+       plugin_submit (MODULE_NAME, inst, buf);
+}
+#undef BUFSIZE
+
+void sensors_read (void)
+{
+       featurelist_t *feature;
+       double value;
+
+       for (feature = first_feature; feature != NULL; feature = feature->next)
+       {
+               if (sensors_get_feature (*feature->chip, feature->data->number, &value) < 0)
+                       continue;
+
+               sensors_submit (feature->data->name, feature->chip->prefix, value);
+       }
+}
+
+void module_register (void)
+{
+       plugin_register (MODULE_NAME, collectd_sensors_init, sensors_read,
+                       sensors_write);
+}
+
+#undef MODULE_NAME
+#endif /* COLLECT_SENSORS */
diff --git a/src/sensors.h b/src/sensors.h
new file mode 100644 (file)
index 0000000..9fb1767
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * collectd - src/sensors.h
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#ifndef SENSORS_H
+#define SENSORS_H
+
+#include "collectd.h"
+#include "common.h"
+
+/* Won't compile without header file */
+#ifndef HAVE_SENSORS_SENSORS_H
+#undef HAVE_LIBSENSORS
+#endif
+
+#ifndef COLLECT_SENSORS
+#ifdef HAVE_LIBSENSORS
+#define COLLECT_SENSORS 1
+#else
+#define COLLECT_SENSORS 0
+#endif
+#endif /* !defined(COLLECT_SENSORS) */
+
+#endif /* SENSORS_H */
diff --git a/src/serial.c b/src/serial.c
new file mode 100644 (file)
index 0000000..9d41fde
--- /dev/null
@@ -0,0 +1,150 @@
+/**
+ * collectd - src/serial.c
+ * Copyright (C) 2005  David Bacher
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   David Bacher <drbacher at gmail.com>
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "serial.h"
+
+#if COLLECT_SERIAL
+#define MODULE_NAME "serial"
+
+#include "plugin.h"
+#include "common.h"
+
+static char *serial_filename_template = "serial-%s.rrd";
+
+static char *ds_def[] =
+{
+       "DS:incoming:COUNTER:25:0:U",
+       "DS:outgoing:COUNTER:25:0:U",
+       NULL
+};
+static int ds_num = 2;
+
+void serial_init (void)
+{
+}
+
+void serial_write (char *host, char *inst, char *val)
+{
+       char file[512];
+       int status;
+
+       status = snprintf (file, 512, serial_filename_template, inst);
+       if (status < 1)
+               return;
+       else if (status >= 512)
+               return;
+
+       rrd_update_file (host, file, val, ds_def, ds_num);
+}
+
+#define BUFSIZE 512
+void serial_submit (char *device,
+               unsigned long long incoming,
+               unsigned long long outgoing)
+{
+       char buf[BUFSIZE];
+        time_t curtime = time(NULL);
+        
+       if (snprintf (buf, BUFSIZE, "%u:%llu:%llu", (unsigned int) curtime,
+                               incoming, outgoing) >= BUFSIZE)
+               return;
+
+       plugin_submit (MODULE_NAME, device, buf);
+}
+#undef BUFSIZE
+
+void serial_read (void)
+{
+#ifdef KERNEL_LINUX
+
+       FILE *fh;
+       char buffer[1024];
+       unsigned long long incoming, outgoing;
+       
+       char *fields[16];
+       int i, numfields;
+       int len;
+
+       /* there are a variety of names for the serial device */
+       if ((fh = fopen ("/proc/tty/driver/serial", "r")) == NULL &&
+               (fh = fopen ("/proc/tty/driver/ttyS", "r")) == NULL)
+       {
+               syslog (LOG_WARNING, "serial: fopen: %s", strerror (errno));
+               return;
+       }
+
+       while (fgets (buffer, 1024, fh) != NULL)
+       {
+               int have_rx = 0, have_tx = 0;
+
+               numfields = strsplit (buffer, fields, 16);
+
+               if (numfields < 6)
+                       continue;
+
+               /*
+                * 0: uart:16550A port:000003F8 irq:4 tx:0 rx:0
+                * 1: uart:16550A port:000002F8 irq:3 tx:0 rx:0
+                */
+               len = strlen (fields[0]) - 1;
+               if (len < 1)
+                       continue;
+               if (fields[0][len] != ':')
+                       continue;
+               fields[0][len] = '\0';
+
+               for (i = 1; i < numfields; i++)
+               {
+                       len = strlen (fields[i]);
+                       if (len < 4)
+                               continue;
+
+                       if (strncmp (fields[i], "tx:", 3) == 0)
+                       {
+                               outgoing = atoll (fields[i] + 3);
+                               have_tx++;
+                       }
+                       else if (strncmp (fields[i], "rx:", 3) == 0)
+                       {
+                               incoming = atoll (fields[i] + 3);
+                               have_rx++;
+                       }
+               }
+
+               if ((have_rx == 0) || (have_tx == 0))
+                       continue;
+
+               serial_submit (fields[0], incoming, outgoing);
+       }
+
+       fclose (fh);
+#endif /* KERNEL_LINUX */
+}
+
+void module_register (void)
+{
+   plugin_register (MODULE_NAME, serial_init, serial_read, serial_write);
+}
+
+#undef MODULE_NAME
+#endif /* COLLECT_SERIAL */
diff --git a/src/serial.h b/src/serial.h
new file mode 100644 (file)
index 0000000..8337280
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * collectd - src/serial.h
+ * Copyright (C) 2005  David Bacher
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   David Bacher <drbacher at gmail.com>
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#ifndef SERIAL_H
+#define SERIAL_H
+
+#include "collectd.h"
+#include "common.h"
+
+#ifndef COLLECT_SERIAL
+#if defined(KERNEL_LINUX)
+#define COLLECT_SERIAL 1
+#else
+#define COLLECT_SERIAL 0
+#endif
+#endif /* !defined(COLLECT_SERIAL) */
+
+#endif /* SERIAL_H */
+
+
+
+
diff --git a/src/swap.c b/src/swap.c
new file mode 100644 (file)
index 0000000..c3e399d
--- /dev/null
@@ -0,0 +1,196 @@
+/**
+ * collectd - src/swap.c
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "swap.h"
+
+#if COLLECT_SWAP
+#define MODULE_NAME "swap"
+
+#ifdef KERNEL_SOLARIS
+#include <sys/swap.h>
+#endif /* KERNEL_SOLARIS */
+
+#include "plugin.h"
+#include "common.h"
+
+#undef  MAX
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+
+static char *swap_file = "swap.rrd";
+
+/* 1099511627776 == 1TB ought to be enough for anyone ;) */
+static char *ds_def[] =
+{
+       "DS:used:GAUGE:25:0:1099511627776",
+       "DS:free:GAUGE:25:0:1099511627776",
+       "DS:cached:GAUGE:25:0:1099511627776",
+       "DS:resv:GAUGE:25:0:1099511627776",
+       NULL
+};
+static int ds_num = 4;
+
+#ifdef KERNEL_SOLARIS
+static int pagesize;
+static kstat_t *ksp;
+#endif /* KERNEL_SOLARIS */
+
+void module_init (void)
+{
+#ifdef KERNEL_SOLARIS
+       /* getpagesize(3C) tells me this does not fail.. */
+       pagesize = getpagesize ();
+       if (get_kstat (&ksp, "unix", 0, "system_pages"))
+               ksp = NULL;
+#endif /* KERNEL_SOLARIS */
+
+       return;
+}
+
+void module_write (char *host, char *inst, char *val)
+{
+       rrd_update_file (host, swap_file, val, ds_def, ds_num);
+}
+
+void module_submit (unsigned long long swap_used,
+               unsigned long long swap_free,
+               unsigned long long swap_cached,
+               unsigned long long swap_resv)
+{
+       char buffer[512];
+
+       if (snprintf (buffer, 512, "N:%llu:%llu:%llu:%llu", swap_used,
+                               swap_free, swap_cached, swap_resv) >= 512)
+               return;
+
+       plugin_submit (MODULE_NAME, "-", buffer);
+}
+
+void module_read (void)
+{
+#ifdef KERNEL_LINUX
+       FILE *fh;
+       char buffer[1024];
+       
+       char *fields[8];
+       int numfields;
+
+       unsigned long long swap_used   = 0LL;
+       unsigned long long swap_cached = 0LL;
+       unsigned long long swap_free   = 0LL;
+       unsigned long long swap_total  = 0LL;
+
+       if ((fh = fopen ("/proc/meminfo", "r")) == NULL)
+       {
+               syslog (LOG_WARNING, "memory: fopen: %s", strerror (errno));
+               return;
+       }
+
+       while (fgets (buffer, 1024, fh) != NULL)
+       {
+               unsigned long long *val = NULL;
+
+               if (strncasecmp (buffer, "SwapTotal:", 10) == 0)
+                       val = &swap_total;
+               else if (strncasecmp (buffer, "SwapFree:", 9) == 0)
+                       val = &swap_free;
+               else if (strncasecmp (buffer, "SwapCached:", 11) == 0)
+                       val = &swap_cached;
+               else
+                       continue;
+
+               numfields = strsplit (buffer, fields, 8);
+
+               if (numfields < 2)
+                       continue;
+
+               *val = atoll (fields[1]) * 1024LL;
+       }
+
+       if (fclose (fh))
+               syslog (LOG_WARNING, "memory: fclose: %s", strerror (errno));
+
+       if ((swap_total == 0LL) || ((swap_free + swap_cached) > swap_total))
+               return;
+
+       swap_used = swap_total - (swap_free + swap_cached);
+
+       module_submit (swap_used, swap_free, swap_cached, -1LL);
+/* #endif defined(KERNEL_LINUX) */
+
+#elif defined(KERNEL_SOLARIS)
+       unsigned long long swap_alloc;
+       unsigned long long swap_resv;
+       unsigned long long swap_avail;
+       /* unsigned long long swap_free; */
+
+       long long availrmem;
+       long long swapfs_minfree;
+
+       struct anoninfo ai;
+
+       if (swapctl (SC_AINFO, &ai) == -1)
+               return;
+
+       availrmem      = get_kstat_value (ksp, "availrmem");
+       swapfs_minfree = get_kstat_value (ksp, "minfree");
+
+       if ((availrmem < 0LL) || (swapfs_minfree < 0LL))
+               return;
+
+       /* 
+        * Calculations learned by reading
+        * http://www.itworld.com/Comp/2377/UIR980701perf/
+        *
+        * swap_resv += ani_resv
+        * swap_alloc += MAX(ani_resv, ani_max) - ani_free
+        * swap_avail += MAX(ani_max - ani_resv, 0) + (availrmem - swapfs_minfree)
+        * swap_free += ani_free + (availrmem - swapfs_minfree)
+        *
+        * To clear up the terminology a bit:
+        * resv  = reserved (but not neccessarily used)
+        * alloc = used     (neccessarily reserved)
+        * avail = not reserved  (neccessarily free)
+        * free  = not allocates (possibly reserved)
+        */
+       swap_resv  = pagesize * ai.ani_resv;
+       swap_alloc = pagesize * (MAX(ai.ani_resv, ai.ani_max) - ai.ani_free);
+       swap_avail = pagesize * (MAX(ai.ani_max - ai.ani_resv, 0) + (availrmem - swapfs_minfree));
+       /* swap_free  = pagesize * (ai.ani_free + (availrmem - swapfs_minfree)); */
+
+       module_submit (swap_alloc, swap_avail, -1LL, swap_resv - swap_alloc);
+/* #endif defined(KERNEL_SOLARIS) */
+
+#elif defined(HAVE_LIBSTATGRAB)
+       sg_swap_stats *swap;
+
+       if ((swap = sg_get_swap_stats ()) != NULL)
+               module_submit (swap->used, swap->free, -1LL, -1LL);
+#endif /* HAVE_LIBSTATGRAB */
+}
+
+void module_register (void)
+{
+       plugin_register (MODULE_NAME, module_init, module_read, module_write);
+}
+
+#undef MODULE_NAME
+#endif /* COLLECT_SWAP */
diff --git a/src/swap.h b/src/swap.h
new file mode 100644 (file)
index 0000000..dfe5d36
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * collectd - src/swap.h
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#ifndef SWAP_H
+#define SWAP_H
+
+#include "collectd.h"
+#include "common.h"
+
+#ifndef COLLECT_SWAP
+#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_LIBSTATGRAB)
+#define COLLECT_SWAP 1
+#else
+#define COLLECT_SWAP 0
+#endif
+#endif /* !defined(COLLECT_SWAP) */
+
+#endif /* SWAP_H */
diff --git a/src/tape.c b/src/tape.c
new file mode 100644 (file)
index 0000000..c0fba0c
--- /dev/null
@@ -0,0 +1,152 @@
+/**
+ * collectd - src/tape.c
+ * Copyright (C) 2005  Scott Garrett
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Scott Garrett <sgarrett at technomancer.com>
+ **/
+
+#include "tape.h"
+
+#if COLLECT_TAPE
+#define MODULE_NAME "tape"
+
+#include "plugin.h"
+#include "common.h"
+
+#if defined(HAVE_LIBKSTAT)
+#define MAX_NUMTAPE 256
+extern kstat_ctl_t *kc;
+static kstat_t *ksp[MAX_NUMTAPE];
+static int numtape = 0;
+#endif /* HAVE_LIBKSTAT */
+
+static char *tape_filename_template = "tape-%s.rrd";
+
+/* 104857600 == 100 MB */
+static char *tape_ds_def[] =
+{
+       "DS:rcount:COUNTER:25:0:U",
+       "DS:rmerged:COUNTER:25:0:U",
+       "DS:rbytes:COUNTER:25:0:U",
+       "DS:rtime:COUNTER:25:0:U",
+       "DS:wcount:COUNTER:25:0:U",
+       "DS:wmerged:COUNTER:25:0:U",
+       "DS:wbytes:COUNTER:25:0:U",
+       "DS:wtime:COUNTER:25:0:U",
+       NULL
+};
+static int tape_ds_num = 8;
+
+extern time_t curtime;
+
+void tape_init (void)
+{
+#ifdef HAVE_LIBKSTAT
+       kstat_t *ksp_chain;
+
+       numtape = 0;
+
+       if (kc == NULL)
+               return;
+
+       for (numtape = 0, ksp_chain = kc->kc_chain;
+                       (numtape < MAX_NUMTAPE) && (ksp_chain != NULL);
+                       ksp_chain = ksp_chain->ks_next)
+       {
+               if (strncmp (ksp_chain->ks_class, "tape", 4) )
+                       continue;
+               if (ksp_chain->ks_type != KSTAT_TYPE_IO)
+                       continue;
+               ksp[numtape++] = ksp_chain;
+       }
+#endif
+
+       return;
+}
+
+void tape_write (char *host, char *inst, char *val)
+{
+       char file[512];
+       int status;
+
+       status = snprintf (file, 512, tape_filename_template, inst);
+       if (status < 1)
+               return;
+       else if (status >= 512)
+               return;
+
+       rrd_update_file (host, file, val, tape_ds_def, tape_ds_num);
+}
+
+
+#define BUFSIZE 512
+void tape_submit (char *tape_name,
+               unsigned long long read_count,
+               unsigned long long read_merged,
+               unsigned long long read_bytes,
+               unsigned long long read_time,
+               unsigned long long write_count,
+               unsigned long long write_merged,
+               unsigned long long write_bytes,
+               unsigned long long write_time)
+
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%llu:%llu:%llu:%llu:%llu:%llu:%llu:%llu",
+                               (unsigned int) curtime,
+                               read_count, read_merged, read_bytes, read_time,
+                               write_count, write_merged, write_bytes,
+                               write_time) >= BUFSIZE)
+               return;
+
+       plugin_submit (MODULE_NAME, tape_name, buf);
+}
+
+#undef BUFSIZE
+
+void tape_read (void)
+{
+
+#if defined(HAVE_LIBKSTAT)
+       static kstat_io_t kio;
+       int i;
+
+       if (kc == NULL)
+               return;
+
+       for (i = 0; i < numtape; i++)
+       {
+               if (kstat_read (kc, ksp[i], &kio) == -1)
+                       continue;
+
+               if (strncmp (ksp[i]->ks_class, "tape", 4) == 0)
+                       tape_submit (ksp[i]->ks_name,
+                                       kio.reads,  0LL, kio.nread,    kio.rtime,
+                                       kio.writes, 0LL, kio.nwritten, kio.wtime);
+       }
+#endif /* defined(HAVE_LIBKSTAT) */
+}
+
+void module_register (void)
+{
+       plugin_register (MODULE_NAME, tape_init, tape_read, tape_write);
+}
+
+#undef MODULE_NAME
+#endif /* COLLECT_TAPE */
diff --git a/src/tape.h b/src/tape.h
new file mode 100644 (file)
index 0000000..acf03a3
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * collectd - src/tape.h
+ * Copyright (C) 2005  Scott Garrett
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Scott Garrett <sgarrett at technomancer.com>
+ **/
+
+#ifndef TAPESTATS_H
+#define TAPESTATS_H
+
+#include "collectd.h"
+#include "common.h"
+
+#ifndef COLLECT_TAPE
+#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT)
+#define COLLECT_TAPE 1
+#else
+#define COLLECT_TAPE 0
+#endif
+#endif /* !defined(COLLECT_TAPE) */
+
+#endif /* TAPESTATS_H */
diff --git a/src/traffic.c b/src/traffic.c
new file mode 100644 (file)
index 0000000..66f2b13
--- /dev/null
@@ -0,0 +1,191 @@
+/**
+ * collectd - src/traffic.c
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "traffic.h"
+
+#if COLLECT_TRAFFIC
+#define MODULE_NAME "traffic"
+
+#include "plugin.h"
+#include "common.h"
+
+#ifdef HAVE_LIBKSTAT
+#define MAX_NUMIF 256
+extern kstat_ctl_t *kc;
+static kstat_t *ksp[MAX_NUMIF];
+static int numif = 0;
+#endif /* HAVE_LIBKSTAT */
+
+static char *traffic_filename_template = "traffic-%s.rrd";
+
+static char *ds_def[] =
+{
+       "DS:incoming:COUNTER:25:0:U",
+       "DS:outgoing:COUNTER:25:0:U",
+       NULL
+};
+static int ds_num = 2;
+
+extern time_t curtime;
+
+void traffic_init (void)
+{
+#ifdef HAVE_LIBKSTAT
+       kstat_t *ksp_chain;
+       kstat_named_t *kn;
+       unsigned long long val;
+
+       numif = 0;
+
+       if (kc == NULL)
+               return;
+
+       for (numif = 0, ksp_chain = kc->kc_chain;
+                       (numif < MAX_NUMIF) && (ksp_chain != NULL);
+                       ksp_chain = ksp_chain->ks_next)
+       {
+               if (strncmp (ksp_chain->ks_class, "net", 3))
+                       continue;
+               if (ksp_chain->ks_type != KSTAT_TYPE_NAMED)
+                       continue;
+               if (kstat_read (kc, ksp_chain, NULL) == -1)
+                       continue;
+               if ((val = get_kstat_value (ksp_chain, "obytes")) == -1LL)
+                       continue;
+               ksp[numif++] = ksp_chain;
+       }
+#endif /* HAVE_LIBKSTAT */
+}
+
+void traffic_write (char *host, char *inst, char *val)
+{
+       char file[512];
+       int status;
+
+       status = snprintf (file, 512, traffic_filename_template, inst);
+       if (status < 1)
+               return;
+       else if (status >= 512)
+               return;
+
+       rrd_update_file (host, file, val, ds_def, ds_num);
+}
+
+#define BUFSIZE 512
+void traffic_submit (char *device,
+               unsigned long long incoming,
+               unsigned long long outgoing)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%lld:%lld", (unsigned int) curtime, incoming, outgoing) >= BUFSIZE)
+               return;
+
+       plugin_submit (MODULE_NAME, device, buf);
+}
+#undef BUFSIZE
+
+void traffic_read (void)
+{
+#ifdef KERNEL_LINUX
+       FILE *fh;
+       char buffer[1024];
+       unsigned long long incoming, outgoing;
+       char *device;
+       
+       char *dummy;
+       char *fields[16];
+       int numfields;
+
+       if ((fh = fopen ("/proc/net/dev", "r")) == NULL)
+       {
+               syslog (LOG_WARNING, "traffic: fopen: %s", strerror (errno));
+               return;
+       }
+
+       while (fgets (buffer, 1024, fh) != NULL)
+       {
+               if (buffer[6] != ':')
+                       continue;
+               buffer[6] = '\0';
+
+               device = buffer;
+               while (device[0] == ' ')
+                       device++;
+
+               if (device[0] == '\0')
+                       continue;
+               
+               dummy = buffer + 7;
+               numfields = strsplit (dummy, fields, 16);
+
+               if (numfields < 9)
+                       continue;
+
+               incoming = atoll (fields[0]);
+               outgoing = atoll (fields[8]);
+
+               traffic_submit (device, incoming, outgoing);
+       }
+
+       fclose (fh);
+/* #endif KERNEL_LINUX */
+
+#elif defined(HAVE_LIBKSTAT)
+       int i;
+       unsigned long long incoming, outgoing;
+
+       if (kc == NULL)
+               return;
+
+       for (i = 0; i < numif; i++)
+       {
+               if (kstat_read (kc, ksp[i], NULL) == -1)
+                       continue;
+
+               if ((incoming = get_kstat_value (ksp[i], "rbytes")) == -1LL)
+                       continue;
+               if ((outgoing = get_kstat_value (ksp[i], "obytes")) == -1LL)
+                       continue;
+
+               traffic_submit (ksp[i]->ks_name, incoming, outgoing);
+       }
+/* #endif HAVE_LIBKSTAT */
+
+#elif defined(HAVE_LIBSTATGRAB)
+       sg_network_io_stats *ios;
+       int i, num;
+
+       ios = sg_get_network_io_stats (&num);
+
+       for (i = 0; i < num; i++)
+               traffic_submit (ios[i].interface_name, ios[i].rx, ios[i].tx);
+#endif /* HAVE_LIBSTATGRAB */
+}
+
+void module_register (void)
+{
+       plugin_register (MODULE_NAME, traffic_init, traffic_read, traffic_write);
+}
+
+#undef MODULE_NAME
+#endif /* COLLECT_TRAFFIC */
diff --git a/src/traffic.h b/src/traffic.h
new file mode 100644 (file)
index 0000000..3b95927
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * collectd - src/traffic.h
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#ifndef TRAFFIC_H
+#define TRAFFIC_H
+
+#include "collectd.h"
+#include "common.h"
+
+#ifndef COLLECT_TRAFFIC
+#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_LIBSTATGRAB)
+#define COLLECT_TRAFFIC 1
+#else
+#define COLLECT_TRAFFIC 0
+#endif
+#endif /* !defined(COLLECT_TRAFFIC) */
+
+#endif /* TRAFFIC_H */
index 96cd621..9e8dc34 100644 (file)
@@ -1,26 +1,24 @@
-/* 
- * users.c
+/**
+ * collectd - src/users.c
+ * Copyright (C) 2005  Sebastian Harl
  *
- * users plugin for collectd
+ * 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 plugin collects the number of users currently logged into the system.
+ * 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.
  *
- * Written by Sebastian Harl <sh@tokkee.org>
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
  *
- * 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
- */
+ * Authors:
+ *   Sebastian Harl <sh at tokkee.org>
+ **/
 
 #include "users.h"
 
index 1295901..8665cb4 100644 (file)
@@ -1,26 +1,24 @@
-/* 
- * users.h
+/**
+ * collectd - src/users.h
+ * Copyright (C) 2005  Sebastian Harl
  *
- * users plugin for collectd
+ * 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 plugin collects the number of users currently logged into the system.
+ * 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.
  *
- * Written by Sebastian Harl <sh@tokkee.org>
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
  *
- * 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
- */
+ * Authors:
+ *   Sebastian Harl <sh at tokkee.org>
+ **/
 
 #ifndef USERS_H
 #define USERS_H 1
index 3f432e1..db59525 100644 (file)
@@ -2,24 +2,23 @@
  * collectd - src/utils_debug.c
  * Copyright (C) 2005  Niki W. Waibel
  *
- * This program is free software; you can redistribute it and/
- * or modify it under the terms of the GNU General Public Li-
- * cence as published by the Free Software Foundation; either
- * version 2 of the Licence, or any later version.
+ * 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 use-
- * ful, but WITHOUT ANY WARRANTY; without even the implied war-
- * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public Licence for more details.
+ * 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
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
  *
- * Author:
- *   Niki W. Waibel <niki.waibel@gmx.net>
-**/
+ * Authors:
+ *   Niki W. Waibel <niki.waibel at gmx.net>
+ **/
 
 #include "common.h"
 #include "utils_debug.h"