Peter,
One thing I noticed is that the filters might not be fully
functional. For example, "cpu_stat::cpu_stat*" filter doesn't return
anything and "cpu_stat:::execpgin" retrieves all statistics...not just
the "execpgin" ones.
For some reason I think I saw some documentation that said both that
wild cards are and are not supported, though I can't find either
reference right now. Any plans to support either of these filters (wild
cards and per statistic) in the future?
-Bill
Peter Tribble wrote:
> 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.)
>