--- /dev/null
+/**
+ * collectd - src/fscache.c
+ * Copyright (C) 2009 Edward "Koko" Konetzko
+ *
+ * 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; only version 2 of the License is applicable.
+ *
+ * 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:
+ * Edward "Koko" Konetzko <konetzed at quixoticagony.com>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include <stdio.h> /* a header needed for FILE */
+#include <string.h> /* a header needed for scanf function */
+#include <stdlib.h> /* used for atoi */
+
+
+#if !KERNEL_LINUX
+# error "This module only supports the Linux implementation of fscache"
+#endif
+
+#define BUFSIZE 1024
+
+/*
+see /proc/fs/fscache/stats
+see Documentation/filesystems/caching/fscache.txt in linux kernel >= 2.6.30
+
+This shows counts of a number of events that can happen in FS-Cache:
+
+CLASS EVENT MEANING
+======= ======= =======================================================
+Cookies idx=N Number of index cookies allocated
+ dat=N Number of data storage cookies allocated
+ spc=N Number of special cookies allocated
+Objects alc=N Number of objects allocated
+ nal=N Number of object allocation failures
+ avl=N Number of objects that reached the available state
+ ded=N Number of objects that reached the dead state
+ChkAux non=N Number of objects that didn't have a coherency check
+ ok=N Number of objects that passed a coherency check
+ upd=N Number of objects that needed a coherency data update
+ obs=N Number of objects that were declared obsolete
+Pages mrk=N Number of pages marked as being cached
+ unc=N Number of uncache page requests seen
+Acquire n=N Number of acquire cookie requests seen
+ nul=N Number of acq reqs given a NULL parent
+ noc=N Number of acq reqs rejected due to no cache available
+ ok=N Number of acq reqs succeeded
+ nbf=N Number of acq reqs rejected due to error
+ oom=N Number of acq reqs failed on ENOMEM
+Lookups n=N Number of lookup calls made on cache backends
+ neg=N Number of negative lookups made
+ pos=N Number of positive lookups made
+ crt=N Number of objects created by lookup
+Updates n=N Number of update cookie requests seen
+ nul=N Number of upd reqs given a NULL parent
+ run=N Number of upd reqs granted CPU time
+Relinqs n=N Number of relinquish cookie requests seen
+ nul=N Number of rlq reqs given a NULL parent
+ wcr=N Number of rlq reqs waited on completion of creation
+AttrChg n=N Number of attribute changed requests seen
+ ok=N Number of attr changed requests queued
+ nbf=N Number of attr changed rejected -ENOBUFS
+ oom=N Number of attr changed failed -ENOMEM
+ run=N Number of attr changed ops given CPU time
+Allocs n=N Number of allocation requests seen
+ ok=N Number of successful alloc reqs
+ wt=N Number of alloc reqs that waited on lookup completion
+ nbf=N Number of alloc reqs rejected -ENOBUFS
+ ops=N Number of alloc reqs submitted
+ owt=N Number of alloc reqs waited for CPU time
+Retrvls n=N Number of retrieval (read) requests seen
+ ok=N Number of successful retr reqs
+ wt=N Number of retr reqs that waited on lookup completion
+ nod=N Number of retr reqs returned -ENODATA
+ nbf=N Number of retr reqs rejected -ENOBUFS
+ int=N Number of retr reqs aborted -ERESTARTSYS
+ oom=N Number of retr reqs failed -ENOMEM
+ ops=N Number of retr reqs submitted
+ owt=N Number of retr reqs waited for CPU time
+Stores n=N Number of storage (write) requests seen
+ ok=N Number of successful store reqs
+ agn=N Number of store reqs on a page already pending storage
+ nbf=N Number of store reqs rejected -ENOBUFS
+ oom=N Number of store reqs failed -ENOMEM
+ ops=N Number of store reqs submitted
+ run=N Number of store reqs granted CPU time
+Ops pend=N Number of times async ops added to pending queues
+ run=N Number of times async ops given CPU time
+ enq=N Number of times async ops queued for processing
+ dfr=N Number of async ops queued for deferred release
+ rel=N Number of async ops released
+ gc=N Number of deferred-release async ops garbage collected
+
+63 events to collect in 13 groups
+*/
+static void fscache_submit (const char *section, const char *name,
+ counter_t counter_value)
+{
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
+
+ vl.values = values;
+ vl.values_len = 1;
+
+ vl.values[0].counter = counter_value;
+
+ sstrncpy(vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy(vl.plugin, "fscache", sizeof (vl.plugin));
+ sstrncpy(vl.plugin_instance, section, sizeof (vl.plugin_instance));
+ sstrncpy(vl.type, "fscache_stat", sizeof(vl.type));
+ sstrncpy(vl.type_instance, name, sizeof(vl.type_instance));
+
+ plugin_dispatch_values (&vl);
+}
+
+static void fscache_read_stats_file (FILE *fh)
+{
+ char section[DATA_MAX_NAME_LEN];
+ size_t section_len;
+
+ char linebuffer[BUFSIZE];
+
+/*
+ * cat /proc/fs/fscache/stats
+ * FS-Cache statistics
+ * Cookies: idx=2 dat=0 spc=0
+ * Objects: alc=0 nal=0 avl=0 ded=0
+ * ChkAux : non=0 ok=0 upd=0 obs=0
+ * Pages : mrk=0 unc=0
+ * Acquire: n=2 nul=0 noc=0 ok=2 nbf=0 oom=0
+ * Lookups: n=0 neg=0 pos=0 crt=0
+ * Updates: n=0 nul=0 run=0
+ * Relinqs: n=0 nul=0 wcr=0
+ * AttrChg: n=0 ok=0 nbf=0 oom=0 run=0
+ * Allocs : n=0 ok=0 wt=0 nbf=0
+ * Allocs : ops=0 owt=0
+ * Retrvls: n=0 ok=0 wt=0 nod=0 nbf=0 int=0 oom=0
+ * Retrvls: ops=0 owt=0
+ * Stores : n=0 ok=0 agn=0 nbf=0 oom=0
+ * Stores : ops=0 run=0
+ * Ops : pend=0 run=0 enq=0
+ * Ops : dfr=0 rel=0 gc=0
+ */
+
+ /* Read file line by line */
+ while (fgets (linebuffer, sizeof (linebuffer), fh) != NULL)
+ {
+ char *lineptr;
+ char *fields[32];
+ int fields_num;
+ int i;
+
+ /* Find the colon and replace it with a null byte */
+ lineptr = strchr (linebuffer, ':');
+ if (lineptr == NULL)
+ continue;
+ *lineptr = 0;
+ lineptr++;
+
+ /* Copy and clean up the section name */
+ sstrncpy (section, linebuffer, sizeof (section));
+ section_len = strlen (section);
+ while ((section_len > 0) && isspace ((int) section[section_len - 1]))
+ {
+ section_len--;
+ section[section_len] = 0;
+ }
+ if (section_len <= 0)
+ continue;
+
+ fields_num = strsplit (lineptr, fields, STATIC_ARRAY_SIZE (fields));
+ if (fields_num <= 0)
+ continue;
+
+ for (i = 0; i < fields_num; i++)
+ {
+ char *field_name;
+ char *field_value_str;
+ char *endptr;
+ counter_t field_value_cnt;
+
+ field_name = fields[i];
+ assert (field_name != NULL);
+
+ field_value_str = strchr (field_name, '=');
+ if (field_value_str == NULL)
+ continue;
+ *field_value_str = 0;
+ field_value_str++;
+
+ errno = 0;
+ endptr = NULL;
+ field_value_cnt = (counter_t) strtoull (field_value_str,
+ &endptr, /* base = */ 10);
+ if ((errno != 0) || (endptr == field_value_str))
+ continue;
+
+ fscache_submit (section, field_name, field_value_cnt);
+ }
+ } /* while (fgets) */
+} /* void fscache_read_stats_file */
+
+static int fscache_read (void){
+ FILE *fh;
+ fh = fopen("/proc/fs/fscache/stats", "r");
+ if (fh != NULL){
+ fscache_read_stats_file(fh);
+ fclose(fh);
+
+ }else{
+ printf("cant open file\n");
+ return (-1);
+ }
+ return (0);
+}
+
+void module_register (void)
+{
+ plugin_register_read ("fscache", fscache_read);
+} /* void module_register */
+
+/* vim: set sw=4 sts=4 et : */