package com.bigdata.counters.osx;
import com.bigdata.counters.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.regex.Pattern;
/**
* OSX does have an <code>iostat</code>. This is not the same as the utility we
* support under linux. <code>iostat -d -C -n 999 -w 60</code> provides an
* update every 60 seconds. The -d tells it to report just device statistics (it
* will report CPU and load average statistics as well by default). The "-C"
* option tells it that you want the CPU stats anyway (this includes IOWait). (A
* "-U" option may be used to explicitly request the load average stats.) The
* "-n 999" tells it to display up to 999 devices. Otherwise it will truncate
* the output at 80 columns.
*
* <pre>
* disk0 disk1 disk2 disk3 disk4 cpu
* KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s us sy id
* 197.14 26 5.10 79.10 1 0.07 3.74 0 0.00 41.31 0 0.00 13.03 0 0.00 31 6 63
* 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 53 4 43
* 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 56 8 37
* 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 54 9 37
* 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 57 8 35
* </pre>
*
* The output of this command depends on the #of devices which are attached, and
* that can actually change over time (device connect/disconnect). Unless we are
* going to aggregate across the devices reported in each time period it might
* make more sense to only use this for the CPU stats, which can be done by
* specifying "-n 0" for NO devices.
*
* <pre>
* iostat -d -C -n 0 -w 1 | cat
* cpu
* us sy id
* 31 6 63
* 57 8 35
* 57 6 37
* </pre>
*
* Regardless, the headers will repeat periodically.
*
* @author thompsonbry@users.sourceforge.net
*/
public class TestParse_iostat extends AbstractParserTestCase {
public TestParse_iostat() {
super();
}
public TestParse_iostat(String name) {
super(name);
}
/**
* Test parsing of a CPU only report from
* <code>iostat -d -C -n 0 -w 1 | cat</code>
*/
public void test_parsing_iostat_cpu_only() {
final String h0 = " cpu";
final String h1 = " us sy id";
final String d0 = " 38 7 55";
final Pattern pattern = IOStatCollector.pattern;
// test 1st header parse.
{
final String[] fields = pattern.split(h0.trim(), 0/* limit */);
for (int i = 0; i < fields.length; i++) {
if (log.isInfoEnabled())
log.info("fields[" + i + "]=[" + fields[i] + "]");
}
assertField(h0, fields, 0, "cpu");
assertEquals(1, fields.length);
}
// test 2nd header parse.
{
final String[] fields = pattern.split(h1.trim(), 0/* limit */);
for (int i = 0; i < fields.length; i++) {
if (log.isInfoEnabled())
log.info("fields[" + i + "]=[" + fields[i] + "]");
}
assertField(h1, fields, 0, "us");
assertField(h1, fields, 1, "sy");
assertField(h1, fields, 2, "id");
assertEquals(3, fields.length);
}
// test data parse.
{
final String[] fields = pattern.split(d0.trim(), 0/* limit */);
for (int i = 0; i < fields.length; i++) {
if (log.isInfoEnabled())
log.info("fields[" + i + "]=[" + fields[i] + "]");
}
assertField(d0, fields, 0, "38");
assertField(d0, fields, 1, "7");
assertField(d0, fields, 2, "55");
assertEquals(3, fields.length);
}
}
/**
* Test parsing of the output of <code>iostat -d -C -n 999 -w 60</code>
*
* <pre>
* disk0 disk1 disk2 disk3 disk4 cpu
* KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s us sy id
* 197.14 26 5.10 79.10 1 0.07 3.74 0 0.00 41.31 0 0.00 13.03 0 0.00 31 6 63
* 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 53 4 43
* 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 56 8 37
* 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 54 9 37
* 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 57 8 35
* </pre>
*
* Note that the #of device columns will vary for this format. The headers
* will also periodically repeat. The #of columns for the report can
* presumably vary as devices are connected and disconnected!
*/
public void test_parsing_iostat_devices_plus_cpu() {
final String h0 = " disk0 disk1 disk2 disk3 disk4 cpu";
final String h1 = " KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s us sy id";
final String d0 = " 197.14 26 5.10 79.10 1 0.07 3.74 0 0.00 41.31 0 0.00 13.03 0 0.00 31 6 63";
final Pattern pattern = IOStatCollector.pattern;
// test 1st header parse.
{
final String[] fields = pattern.split(h0.trim(), 0/* limit */);
for (int i = 0; i < fields.length; i++) {
if (log.isInfoEnabled())
log.info("fields[" + i + "]=[" + fields[i] + "]");
}
assertField(h0, fields, 0, "disk0");
assertField(h0, fields, 1, "disk1");
assertField(h0, fields, 2, "disk2");
assertField(h0, fields, 3, "disk3");
assertField(h0, fields, 4, "disk4");
assertField(h0, fields, 5, "cpu");
assertEquals(6, fields.length);
}
// test 2nd header parse.
{
// final String h0 = " disk0 disk1 disk2 disk3 disk4 cpu";
// final String h1 = " KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s us sy id";
// final String d0 = " 197.14 26 5.10 79.10 1 0.07 3.74 0 0.00 41.31 0 0.00 13.03 0 0.00 31 6 63";
final String[] fields = pattern.split(h1.trim(), 0/* limit */);
for (int i = 0; i < fields.length; i++) {
if (log.isInfoEnabled())
log.info("fields[" + i + "]=[" + fields[i] + "]");
}
assertField(h1, fields, 0, "KB/t");
assertField(h1, fields, 1, "tps");
assertField(h1, fields, 2, "MB/s");
assertField(h1, fields, 3, "KB/t");
assertField(h1, fields, 4, "tps");
assertField(h1, fields, 5, "MB/s");
assertField(h1, fields, 6, "KB/t");
assertField(h1, fields, 7, "tps");
assertField(h1, fields, 8, "MB/s");
assertField(h1, fields, 9, "KB/t");
assertField(h1, fields,10, "tps");
assertField(h1, fields,11, "MB/s");
assertField(h1, fields,12, "KB/t");
assertField(h1, fields,13, "tps");
assertField(h1, fields,14, "MB/s");
assertField(h1, fields,15, "us");
assertField(h1, fields,16, "sy");
assertField(h1, fields,17, "id");
assertEquals(18, fields.length);
}
// test data parse.
{
// final String h0 = " disk0 disk1 disk2 disk3 disk4 cpu";
// final String h1 = " KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s us sy id";
// final String d0 = " 197.14 26 5.10 79.10 1 0.07 3.74 0 0.00 41.31 0 0.00 13.03 0 0.00 31 6 63";
final String[] fields = pattern.split(d0.trim(), 0/* limit */);
for (int i = 0; i < fields.length; i++) {
if (log.isInfoEnabled())
log.info("fields[" + i + "]=[" + fields[i] + "]");
}
assertField(d0, fields, 0, "197.14");
assertField(d0, fields, 1, "26");
assertField(d0, fields, 2, "5.10");
assertField(d0, fields, 3, "79.10");
assertField(d0, fields, 4, "1");
assertField(d0, fields, 5, "0.07");
assertField(d0, fields, 6, "3.74");
assertField(d0, fields, 7, "0");
assertField(d0, fields, 8, "0.00");
assertField(d0, fields, 9, "41.31");
assertField(d0, fields,10, "0");
assertField(d0, fields,11, "0.00");
assertField(d0, fields,12, "13.03");
assertField(d0, fields,13, "0");
assertField(d0, fields,14, "0.00");
assertField(d0, fields,15, "31");
assertField(d0, fields,16, "6");
assertField(d0, fields,17, "63");
assertEquals(18, fields.length);
}
}
public void test_iostat_collector_correct() throws IOException, InterruptedException {
String output =
" disk0 disk1 disk2 disk3 disk4 cpu\n" +
" KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s KB/t tps MB/s us sy id\n" +
" 197.14 26 5.10 79.10 1 0.07 3.74 0 0.00 41.31 0 0.00 13.03 0 0.00 31 6 63\n" +
" 0.00 5 0.00 0.00 5 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 53 4 43\n";
test_iostat_collector(output);
}
protected void test_iostat_collector(String output) throws IOException, InterruptedException {
final IOStatCollector ioStatCollector = new IOStatCollector(1, true) {
@Override
public AbstractProcessReader getProcessReader() {
return new IOStatReader() {
@Override
protected ActiveProcess getActiveProcess() {
return new ActiveProcess() {
@Override
public boolean isAlive() {
return true;
}
};
}
};
}
};
final IOStatCollector.IOStatReader ioStatReader = (IOStatCollector.IOStatReader) ioStatCollector.getProcessReader();
ioStatReader.start(new ByteArrayInputStream(output.getBytes()));
Thread t = new Thread(ioStatReader);
CounterSet counterSet;
try {
t.start();
Thread.sleep(100);
counterSet = ioStatCollector.getCounters();
} finally {
t.interrupt();
}
double cpu_usr = (Double)((ICounter) counterSet.getChild(IProcessCounters.CPU).getChild("% User Time")).getInstrument().getValue();
double tps = (Double)((ICounter) counterSet.getChild(IProcessCounters.PhysicalDisk).getChild("Transfers Per Second")).getInstrument().getValue();
assertEquals(0.53, cpu_usr);
assertEquals(tps, 10.0);
/*Iterator<ICounter> counters = counterSet.getCounters(Pattern.compile(".*"));
while (counters.hasNext()) {
System.err.println(counters.next().getInstrument().getValue().toString());
}*/
}
}