On Nov 5, 2007 7:19 PM, William Fretts-Saxton
<william.fretts.saxton at sun.com> wrote:
> I'm trying to duplicate the following kstat code in jkstat:
>
> # kstat -p cpu_stat:::execpgin
> cpu_stat:0:cpu_stat0:execpgin 57553
> cpu_stat:1:cpu_stat1:execpgin 53963
>
> It doesn't look like you can use a filter to directly gather the kstat
> information using jkstat. The filter's "getKstats()" method returns a Set of
> Kstats, with the module, instance, and name variables populated, but the
> actual Map of statistics is empty.
This is deliberate, in a way. The idea is (a) to keep the code small
and (b) to keep
the code fast. One of the consequences of (b) is to avoid retrieving
the actual statistics
unless you're sure you need to. (Actually getting the data is many
times more expensive
than simply enumerating which statistics exist.) Add constraint (a) to
that and there's
only one set of calls to enumerate, and they don't return any data. At
some point in
the past I did have calls that returned Kstats with data and others
that returned
you Kstats without data. I cleaned it up to reduce the variety and
make things more
consistent.
I could have made the wrong choices, of course. That's entirely
possible, especially
as I've based the design largely on the usage patterns that I've
tended to use myself.
I'm willing to do something different if it's worthwhile, though.
> So, in order to actually get the statistics, I had to create the filter, get
> the Set of "empty" Kstats, then run "getKstat()" on each of them to actually
> get the statistic data.
That's the idea.
(I usually end up doing this over and over to continually update the display.)
> Is there a better way to do this? My java code is below:
> <pre>
> // Initialize JKstat and filter
> JKstat jkstat = new JKstat();
> KstatFilter ksf = new KstatFilter(jkstat);
> ksf.addFilter("cpu_stat:::");
>
> // Get the list of empty Kstats
> Set <Kstat> vfilter = ksf.getKstats();
>
> // Now iterate through them
> Iterator kItr = vfilter.iterator();
> while(kItr.hasNext()) {
>
> Kstat kstat = (Kstat)kItr.next();
>
> // Use empty Kstat module, instance, and name data to get the statistic
> information
> Kstat kstat2 =
> jkstat.getKstat(kstat.getModule(),kstat.getInst(),kstat.getName());
> Map <String, KstatData> kstat2Map = kstat2.getMap();
> KstatData execpgin2Data = kstat2Map.get("execpgin");
> System.out.println(kstat2.getTriplet() + ":execpgin: " +
> (Long)execpginData2.getData());
>
> }
I would use a slightly shorter idiom:
JKstat jkstat = new JKstat();
KstatFilter ksf = new KstatFilter(jkstat);
ksf.addFilter("cpu_stat:::");
for (Kstat kstat : ksf.getKstats()) {
Kstat kstat2 = jkstat.getKstat(kstat);
System.out.println(kstat2.getTriplet() + ":execpgin: " +
kstat2.longData("execpgin"));
}
Pulling a long out of the statistics Map is such a common operation that
there's a shortcut. (Which has no sanity checking really.)
--
-Peter Tribble
http://www.petertribble.co.uk/ - http://ptribble.blogspot.com/