Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

allow for filtering from read()

  • Loading branch information...
commit 7c6ce0c6ead0e25a842d3ee046a5498df019ab58 1 parent f2847e7
@davepacheco davepacheco authored
View
3  README
@@ -17,7 +17,8 @@ the kstat framework on Solaris. The "kstat" module exports a single class,
Together, these members form a specification of kstats to read.
read(): Returns an array of kstats that match the specification with
- which the reader instance was constructed. Each element of the
+ which the reader instance was constructed *and* an optional
+ specification passed to this function. Each element of the
array is an object that contains the following members:
class => string denoting class of kstat
View
2  examples/badops.js
@@ -11,4 +11,4 @@ console.log(reader.read());
reader.close();
assert.throws(function () { reader.read(); }, /already been closed/);
assert.throws(function () { reader.close(); }, /already been closed/);
-console.log('test okay');
+console.log('test passsed');
View
94 examples/filter.js
@@ -0,0 +1,94 @@
+/*
+ * filter.js: tests filtering in both the Reader constructor and read().
+ */
+
+var assert = require('assert');
+var kstat = require('kstat');
+
+function kstatToIdent(kstat)
+{
+ return ({
+ 'module': kstat['module'],
+ 'name': kstat['name'],
+ 'class': kstat['class'],
+ 'instance': kstat['instance'],
+ });
+}
+
+function identCompare(k1, k2)
+{
+ var key1 = k1['module'] + '.' + k1['name'] + '.' + k1['class'] + '.' +
+ k1['instance'];
+ var key2 = k2['module'] + '.' + k2['name'] + '.' + k2['class'] + '.' +
+ k2['instance'];
+ if (key1 < key2)
+ return (-1);
+ if (key1 > key2)
+ return (1);
+ return (0);
+}
+
+var all_reader = new kstat.Reader({});
+var cpu_reader = new kstat.Reader({ 'module': 'cpu' });
+
+/*
+ * Test constructor-based filtering.
+ */
+var allstats = all_reader.read();
+assert.ok(allstats.length > 0);
+console.log('%d total stats', allstats.length);
+
+var cpustats = cpu_reader.read();
+assert.ok(cpustats.length > 0);
+assert.ok(allstats.length > cpustats.length);
+console.log('%d cpu stats', cpustats.length);
+
+var ncpustats = 0;
+allstats.forEach(function (kstat) {
+ if (kstat['module'] == 'cpu')
+ ncpustats++;
+});
+
+assert.ok(cpustats.length == ncpustats);
+
+
+/*
+ * Test read-based filtering.
+ */
+var filteredstats = all_reader.read({ 'module': 'cpu' });
+assert.equal(filteredstats.length, ncpustats);
+assert.deepEqual(filteredstats.map(kstatToIdent).sort(identCompare),
+ cpustats.map(kstatToIdent).sort(identCompare));
+
+filteredstats = all_reader.read({ 'instance': 1 });
+assert.ok(filteredstats.length < allstats.length);
+assert.ok(filteredstats.length > 0);
+filteredstats.forEach(
+ function (kstat) { assert.equal(kstat['instance'], 1); });
+console.log('%d stats with instance == 1', filteredstats.length);
+
+filteredstats = all_reader.read({ 'class': 'net' });
+assert.ok(filteredstats.length < allstats.length);
+assert.ok(filteredstats.length > 0);
+filteredstats.forEach(
+ function (kstat) { assert.equal(kstat['class'], 'net'); });
+console.log('%d stats with class == "net"', filteredstats.length);
+
+filteredstats = all_reader.read({ 'name': 'intrstat' });
+assert.ok(filteredstats.length < allstats.length);
+assert.ok(filteredstats.length > 0);
+filteredstats.forEach(
+ function (kstat) { assert.equal(kstat['name'], 'intrstat'); });
+console.log('%d stats with name == "intrstat"', filteredstats.length);
+
+/*
+ * Test both kinds of filtering at once.
+ */
+filteredstats = cpu_reader.read({ 'instance': 0 });
+assert.ok(filteredstats.length < cpustats.length);
+assert.ok(filteredstats.length > 0);
+filteredstats.forEach(
+ function (kstat) { assert.ok(kstat['instance'] === 0); });
+console.log('%d cpu stats with instance === 0', filteredstats.length);
+
+console.log('test passed');
View
55 kstat.cc
@@ -25,6 +25,7 @@ class KStatReader : node::ObjectWrap {
void close();
Handle<Value> error(const char *fmt, ...);
Handle<Value> read(kstat_t *);
+ bool matches(kstat_t *, string *, string *, string *, int64_t);
int update();
~KStatReader();
@@ -76,6 +77,22 @@ KStatReader::close()
ksr_ctl = NULL;
}
+bool
+KStatReader::matches(kstat_t *ksp, string* fmodule, string* fclass,
+ string* fname, int64_t finstance)
+{
+ if (!fmodule->empty() && fmodule->compare(ksp->ks_module) != 0)
+ return (false);
+
+ if (!fclass->empty() && fclass->compare(ksp->ks_class) != 0)
+ return (false);
+
+ if (!fname->empty() && fname->compare(ksp->ks_name) != 0)
+ return (false);
+
+ return (finstance == -1 || ksp->ks_instance == finstance);
+}
+
int
KStatReader::update()
{
@@ -92,18 +109,8 @@ KStatReader::update()
ksr_kstats.clear();
for (ksp = ksr_ctl->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
- if (!ksr_module->empty() &&
- ksr_module->compare(ksp->ks_module) != 0)
- continue;
-
- if (!ksr_class->empty() &&
- ksr_class->compare(ksp->ks_class) != 0)
- continue;
-
- if (!ksr_name->empty() && ksr_name->compare(ksp->ks_name) != 0)
- continue;
-
- if (ksr_instance != -1 && ksp->ks_instance != ksr_instance)
+ if (!this->matches(ksp,
+ ksr_module, ksr_class, ksr_name, ksr_instance))
continue;
ksr_kstats.push_back(ksp);
@@ -341,7 +348,7 @@ KStatReader::Read(const Arguments& args)
KStatReader *k = ObjectWrap::Unwrap<KStatReader>(args.Holder());
Handle<Array> rval;
HandleScope scope;
- int i;
+ int i, j;
if (k->ksr_ctl == NULL)
return (k->error("kstat reader has already been closed\n"));
@@ -349,15 +356,31 @@ KStatReader::Read(const Arguments& args)
if (k->update() == -1)
return (k->error("failed to update kstat chain"));
- rval = Array::New(k->ksr_kstats.size());
+ string *rmodule = stringMember(args[0], "module", "");
+ string *rclass = stringMember(args[0], "class", "");
+ string *rname = stringMember(args[0], "name", "");
+ int64_t rinstance = intMember(args[0], "instance", -1);
+
+ rval = Array::New();
try {
- for (i = 0; i < k->ksr_kstats.size(); i++)
- rval->Set(i, k->read(k->ksr_kstats[i]));
+ for (i = 0, j = 0; i < k->ksr_kstats.size(); i++) {
+ if (!k->matches(k->ksr_kstats[i],
+ rmodule, rclass, rname, rinstance))
+ continue;
+
+ rval->Set(j++, k->read(k->ksr_kstats[i]));
+ }
} catch (Handle<Value> err) {
+ delete rmodule;
+ delete rclass;
+ delete rname;
return (err);
}
+ delete rmodule;
+ delete rclass;
+ delete rname;
return (rval);
}
View
2  package.json
@@ -1,6 +1,6 @@
{
"name": "kstat",
- "version": "0.2.0",
+ "version": "0.3.0",
"description": "illumos libkstat bindings",
"homepage": "https://github.com/bcantrill/node-kstat",
"author": "Joyent (joyent.com)",
Please sign in to comment.
Something went wrong with that request. Please try again.