vmstat 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in vmstat.gemspec
4
4
  gemspec
5
+
6
+ gem 'rb-fsevent', '~> 0.9.1' if RUBY_PLATFORM =~ /darwin/
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
data/README.md CHANGED
@@ -7,17 +7,20 @@ This is a focused and fast library to get system information like:
7
7
  * _CPU_ (user, system, nice, idle)
8
8
  * _Load_ Average
9
9
  * _Disk_ (type, disk path, free bytes, total bytes, ...)
10
+ * _Boot time_
10
11
  * _Current Task_ (used bytes and usage time *MAC OS X ONLY*)
11
12
 
12
13
  *It currently supports:*
13
14
 
14
15
  * FreeBSD
15
16
  * MacOS X
17
+ * Linux (>= 2.6)
16
18
 
17
19
  *It might support (but not tested):*
18
20
 
19
21
  * OpenBSD
20
22
  * NetBSD
23
+ * Older versions of linux
21
24
 
22
25
  ## Installation
23
26
 
@@ -35,10 +38,10 @@ Or install it yourself as:
35
38
 
36
39
  ## Usage
37
40
 
38
- Just require the library and make a snapshot or use the distinct methods to just capture parts of the statistics.
41
+ Just require the library and make a snapshot or use the distinct methods to just capture parts of the statistics. For further information have a look at the [rdoc](http://rdoc.info/gems/vmstat/frames).
39
42
 
40
43
  require "vmstat"
41
- require "pp"
44
+
42
45
  Vmstat.snapshot # => #<Vmstat::Snapshot:0x007fe5f22df660
43
46
  # @at=2012-10-09 21:48:57 +0200,
44
47
  # @boot_time=2012-10-09 18:42:37 +0200,
@@ -136,6 +139,13 @@ Just require the library and make a snapshot or use the distinct methods to just
136
139
  # user_time_ms=28,
137
140
  # system_time_ms=83>>
138
141
 
142
+ ## Todo
143
+
144
+ * Swap information
145
+ * Reduce the number of memory information gatherd
146
+ * Support more platforms (hp ux, aix, solaris, ...)
147
+ * Server performance information (open file handles, cache sizes, ...)
148
+
139
149
  ## Contributing
140
150
 
141
151
  1. Fork it
@@ -1,3 +1,60 @@
1
1
  require 'mkmf'
2
2
 
3
+ # posix.h
4
+ have_header 'unistd.h'
5
+ have_func 'getpagesize'
6
+ have_header 'stdlib.h'
7
+ have_func 'getloadavg'
8
+
9
+ # mach.h
10
+ have_header 'mach/mach.h'
11
+ have_header 'mach/mach_host.h'
12
+ have_func 'host_processor_info'
13
+ have_func 'mach_host_self'
14
+ have_func 'mach_task_self'
15
+ have_func 'vm_deallocate'
16
+ have_func 'mach_error_string'
17
+ have_func 'task_info'
18
+ mach_headers = ['mach/mach.h', 'mach/mach_host.h']
19
+ have_const 'KERN_SUCCESS', mach_headers
20
+ have_const 'TASK_BASIC_INFO', mach_headers
21
+ have_const 'HOST_VM_INFO', mach_headers
22
+ have_const 'CPU_STATE_MAX', mach_headers
23
+ have_const 'PROCESSOR_CPU_LOAD_INFO', mach_headers
24
+ have_const 'CPU_STATE_USER', mach_headers
25
+ have_const 'CPU_STATE_SYSTEM', mach_headers
26
+ have_const 'CPU_STATE_NICE', mach_headers
27
+ have_const 'CPU_STATE_IDLE', mach_headers
28
+
29
+ # statfs.h
30
+ have_header 'sys/param.h'
31
+ have_header 'sys/mount.h'
32
+ have_header 'sys/statfs.h'
33
+ have_func 'statfs'
34
+
35
+ # sysctl.h
36
+ sys_headers = ['unistd.h', 'sys/sysctl.h', 'sys/types.h', 'sys/socket.h',
37
+ 'net/if.h', 'net/if_mib.h', 'net/if_types.h']
38
+ sys_headers.each { |header| have_header header }
39
+ have_func 'getloadavg'
40
+ have_func 'sysctl'
41
+ have_type 'struct ifmibdata', sys_headers
42
+ have_const 'CTL_NET', sys_headers
43
+ have_const 'PF_LINK', sys_headers
44
+ have_const 'NETLINK_GENERIC', sys_headers
45
+ have_const 'IFMIB_IFDATA', sys_headers
46
+ have_const 'IFDATA_GENERAL', sys_headers
47
+ have_const 'CTL_KERN', sys_headers
48
+ have_const 'KERN_BOOTTIME', sys_headers
49
+
50
+ # bsd.h
51
+ # only if we have *bsd like stats check for sysctlbyname
52
+ if xsystem 'sysctl vm.stats.vm.v_page_size'
53
+ have_header 'sys/sysctl.h'
54
+ have_header 'sys/types.h'
55
+ have_func 'sysctlbyname'
56
+ end
57
+
58
+ create_header
59
+
3
60
  create_makefile 'vmstat/vmstat'
@@ -0,0 +1,88 @@
1
+ #if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYS_TYPES_H) && \
2
+ defined(HAVE_SYSCTLBYNAME)
3
+ #include <vmstat.h>
4
+ #include <sys/sysctl.h>
5
+ #include <sys/types.h>
6
+
7
+ // helper methods
8
+ int system_int(const char *);
9
+ unsigned long long system_ull(const char *);
10
+
11
+ typedef struct {
12
+ long user;
13
+ long nice;
14
+ long system;
15
+ long intr;
16
+ long idle;
17
+ } cpu_time_t;
18
+
19
+ #ifndef VMSTAT_CPU
20
+ #define VMSTAT_CPU
21
+ VALUE vmstat_cpu(VALUE self) {
22
+ VALUE cpus = rb_ary_new();
23
+ int cpu_count = system_int("hw.ncpu");
24
+ size_t len = sizeof(cpu_time_t) * cpu_count;
25
+ cpu_time_t * cp_times = ALLOC_N(cpu_time_t, cpu_count);
26
+ cpu_time_t * cp_time;
27
+ int i;
28
+
29
+ if (sysctlbyname("kern.cp_times", cp_times, &len, NULL, 0) == 0) {
30
+ for (i = 0; i < cpu_count; i++) {
31
+ cp_time = &cp_times[i];
32
+ VALUE cpu = rb_funcall(rb_path2class("Vmstat::Cpu"),
33
+ rb_intern("new"), 5, ULL2NUM(i),
34
+ ULL2NUM(cp_time->user),
35
+ ULL2NUM(cp_time->system + cp_time->intr),
36
+ ULL2NUM(cp_time->nice),
37
+ ULL2NUM(cp_time->idle));
38
+ rb_ary_push(cpus, cpu);
39
+ }
40
+ }
41
+
42
+ free(cp_times);
43
+
44
+ return cpus;
45
+ }
46
+ #endif
47
+
48
+ #ifndef VMSTAT_MEMORY
49
+ #define VMSTAT_MEMORY
50
+ VALUE vmstat_memory(VALUE self) {
51
+ VALUE memory = rb_funcall(rb_path2class("Vmstat::Memory"),
52
+ rb_intern("new"), 15, ULL2NUM(system_ull("vm.stats.vm.v_page_size")),
53
+ ULL2NUM(system_ull("vm.stats.vm.v_active_count")),
54
+ ULL2NUM(system_ull("vm.stats.vm.v_wire_count")),
55
+ ULL2NUM(system_ull("vm.stats.vm.v_inactive_count")),
56
+ ULL2NUM(system_ull("vm.stats.vm.v_free_count")),
57
+ ULL2NUM(Qnil),
58
+ ULL2NUM(Qnil),
59
+ ULL2NUM(system_ull("vm.stats.misc.zero_page_count")),
60
+ ULL2NUM(system_ull("vm.stats.vm.v_reactivated")),
61
+ ULL2NUM(Qnil),
62
+ ULL2NUM(Qnil),
63
+ ULL2NUM(system_ull("vm.stats.vm.v_vm_faults")),
64
+ ULL2NUM(system_ull("vm.stats.vm.v_cow_faults")),
65
+ ULL2NUM(Qnil),
66
+ ULL2NUM(Qnil));
67
+ return memory;
68
+ }
69
+
70
+ int system_int(const char * name) {
71
+ int number;
72
+ size_t number_size = sizeof(number);
73
+ sysctlbyname(name, &number, &number_size, NULL, 0);
74
+ return number;
75
+ }
76
+
77
+ unsigned long long system_ull(const char * name) {
78
+ long number;
79
+ size_t number_size = sizeof(number);
80
+ if (sysctlbyname(name, &number, &number_size, NULL, 0) == -1) {
81
+ perror("sysctlbyname");
82
+ return -1;
83
+ } else {
84
+ return number;
85
+ }
86
+ }
87
+ #endif
88
+ #endif
@@ -0,0 +1,107 @@
1
+ #if defined(HAVE_MACH_MACH_H)
2
+ #include <vmstat.h>
3
+ #include <mach/mach.h>
4
+ #include <mach/mach_host.h>
5
+
6
+ #ifndef VMSTAT_CPU
7
+ #define VMSTAT_CPU
8
+ VALUE vmstat_cpu(VALUE self) {
9
+ VALUE cpus = rb_ary_new();
10
+ processor_info_array_t cpuInfo;
11
+ mach_msg_type_number_t numCpuInfo;
12
+ natural_t numCPUsU = 0U;
13
+ kern_return_t err = host_processor_info(mach_host_self(),
14
+ PROCESSOR_CPU_LOAD_INFO, &numCPUsU, &cpuInfo, &numCpuInfo);
15
+
16
+ if(err == KERN_SUCCESS) {
17
+ unsigned i;
18
+
19
+ for(i = 0U; i < numCPUsU; ++i) {
20
+ int pos = CPU_STATE_MAX * i;
21
+ VALUE cpu = rb_funcall(rb_path2class("Vmstat::Cpu"),
22
+ rb_intern("new"), 5, ULL2NUM(i),
23
+ ULL2NUM(cpuInfo[pos + CPU_STATE_USER]),
24
+ ULL2NUM(cpuInfo[pos + CPU_STATE_SYSTEM]),
25
+ ULL2NUM(cpuInfo[pos + CPU_STATE_NICE]),
26
+ ULL2NUM(cpuInfo[pos + CPU_STATE_IDLE]));
27
+ rb_ary_push(cpus, cpu);
28
+ }
29
+
30
+ err = vm_deallocate(mach_task_self(), (vm_address_t)cpuInfo,
31
+ (vm_size_t)sizeof(*cpuInfo) * numCpuInfo);
32
+ if (err != KERN_SUCCESS) {
33
+ rb_bug("vm_deallocate: %s\n", mach_error_string(err));
34
+ }
35
+ }
36
+
37
+ return cpus;
38
+ }
39
+ #endif
40
+
41
+ #ifndef VMSTAT_MEMORY
42
+ #define VMSTAT_MEMORY
43
+ VALUE vmstat_memory(VALUE self) {
44
+ VALUE memory = Qnil;
45
+ vm_size_t pagesize;
46
+ uint host_count = HOST_VM_INFO_COUNT;
47
+ kern_return_t err;
48
+ vm_statistics_data_t vm_stat;
49
+
50
+ err = host_page_size(mach_host_self(), &pagesize);
51
+ if (err == KERN_SUCCESS) {
52
+ err = host_statistics(mach_host_self(), HOST_VM_INFO,
53
+ (host_info_t)&vm_stat, &host_count);
54
+ if (err == KERN_SUCCESS) {
55
+ memory = rb_funcall(rb_path2class("Vmstat::Memory"),
56
+ rb_intern("new"), 15, ULL2NUM(pagesize),
57
+ ULL2NUM(vm_stat.active_count),
58
+ ULL2NUM(vm_stat.inactive_count),
59
+ ULL2NUM(vm_stat.wire_count),
60
+ ULL2NUM(vm_stat.free_count),
61
+ ULL2NUM(vm_stat.pageins),
62
+ ULL2NUM(vm_stat.pageouts),
63
+ ULL2NUM(vm_stat.zero_fill_count),
64
+ ULL2NUM(vm_stat.reactivations),
65
+ ULL2NUM(vm_stat.purgeable_count),
66
+ ULL2NUM(vm_stat.purges),
67
+ ULL2NUM(vm_stat.faults),
68
+ ULL2NUM(vm_stat.cow_faults),
69
+ ULL2NUM(vm_stat.lookups),
70
+ ULL2NUM(vm_stat.hits));
71
+ }
72
+
73
+ err = vm_deallocate(mach_task_self(), (vm_address_t)pagesize,
74
+ (vm_size_t)host_count);
75
+ if (err != KERN_SUCCESS) {
76
+ rb_bug("vm_deallocate: %s\n", mach_error_string(err));
77
+ }
78
+ }
79
+
80
+ return memory;
81
+ }
82
+ #endif
83
+
84
+ #ifndef VMSTAT_TASK
85
+ #define VMSTAT_TASK
86
+ VALUE vmstat_task(VALUE self) {
87
+ VALUE task = Qnil;
88
+ struct task_basic_info info;
89
+ kern_return_t err;
90
+ mach_msg_type_number_t size = sizeof(info);
91
+
92
+ err = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
93
+ if (err == KERN_SUCCESS) {
94
+ task = rb_funcall(rb_path2class("Vmstat::Task"),
95
+ rb_intern("new"), 5, LONG2NUM(info.suspend_count),
96
+ LONG2NUM(info.virtual_size),
97
+ LONG2NUM(info.resident_size),
98
+ LONG2NUM(info.user_time.seconds * 1000 + info.user_time.microseconds),
99
+ LONG2NUM(info.system_time.seconds * 1000 + info.system_time.microseconds));
100
+ } else {
101
+ rb_bug("task_info: %s\n", mach_error_string(err));
102
+ }
103
+
104
+ return task;
105
+ }
106
+ #endif
107
+ #endif
@@ -0,0 +1,29 @@
1
+ #if defined(HAVE_UNISTD_H) && defined(HAVE_GETPAGESIZE)
2
+ #include <unistd.h>
3
+
4
+ #ifndef VMSTAT_PAGESIZE
5
+ #define VMSTAT_PAGESIZE
6
+ VALUE vmstat_pagesize(VALUE self) {
7
+ return INT2NUM(getpagesize());
8
+ }
9
+ #endif
10
+ #endif
11
+
12
+ #if defined(HAVE_STDLIB_H) && defined(HAVE_GETLOADAVG)
13
+ #ifndef VMSTAT_LOAD_AVERAGE
14
+ #define VMSTAT_LOAD_AVERAGE
15
+ VALUE vmstat_load_average(VALUE self) {
16
+ VALUE load = Qnil;
17
+ double loadavg[AVGCOUNT];
18
+
19
+ getloadavg(&loadavg[0], AVGCOUNT);
20
+
21
+ load = rb_funcall(rb_path2class("Vmstat::LoadAverage"),
22
+ rb_intern("new"), 3, rb_float_new(loadavg[0]),
23
+ rb_float_new(loadavg[1]),
24
+ rb_float_new(loadavg[2]));
25
+
26
+ return load;
27
+ }
28
+ #endif
29
+ #endif
@@ -0,0 +1,41 @@
1
+ #if defined(HAVE_SYS_PARAM_H) && defined(HAVE_SYS_MOUNT_H) && defined(HAVE_STATFS)
2
+ #include <vmstat.h>
3
+ #include <sys/param.h>
4
+ #include <sys/mount.h>
5
+
6
+ // on linux require statfs too
7
+ #if defined(HAVE_SYS_STATFS_H)
8
+ #include <sys/statfs.h>
9
+ #endif
10
+
11
+ #ifndef VMSTAT_DISK
12
+ #define VMSTAT_DISK
13
+ VALUE vmstat_disk(VALUE self, VALUE path) {
14
+ VALUE disk = Qnil;
15
+ struct statfs stat;
16
+
17
+ if (statfs(StringValueCStr(path), &stat) != -1) {
18
+ #if defined(HAVE_SYS_STATFS_H)
19
+ disk = rb_funcall(rb_path2class("Vmstat::LinuxDisk"),
20
+ rb_intern("new"), 6, ULL2NUM(stat.f_type),
21
+ path,
22
+ ULL2NUM(stat.f_bsize),
23
+ ULL2NUM(stat.f_bfree),
24
+ ULL2NUM(stat.f_bavail),
25
+ ULL2NUM(stat.f_blocks));
26
+ #else
27
+ disk = rb_funcall(rb_path2class("Vmstat::Disk"),
28
+ rb_intern("new"), 7, ID2SYM(rb_intern(stat.f_fstypename)),
29
+ rb_str_new(stat.f_mntfromname, strlen(stat.f_mntfromname)),
30
+ rb_str_new(stat.f_mntonname, strlen(stat.f_mntonname)),
31
+ ULL2NUM(stat.f_bsize),
32
+ ULL2NUM(stat.f_bfree),
33
+ ULL2NUM(stat.f_bavail),
34
+ ULL2NUM(stat.f_blocks));
35
+ #endif
36
+ }
37
+
38
+ return disk;
39
+ }
40
+ #endif
41
+ #endif
@@ -0,0 +1,72 @@
1
+ #if defined(HAVE_SYS_SYSCTL_H) && \
2
+ defined(HAVE_SYS_TYPES_H) && \
3
+ defined(HAVE_SYS_SOCKET_H) && \
4
+ defined(HAVE_NET_IF_H) && \
5
+ defined(HAVE_NET_IF_MIB_H) && \
6
+ defined(HAVE_NET_IF_TYPES_H) && \
7
+ defined(HAVE_GETLOADAVG) && \
8
+ defined(HAVE_SYSCTL) && \
9
+ defined(HAVE_TYPE_STRUCT_IFMIBDATA) && \
10
+ defined(HAVE_CONST_CTL_NET) && \
11
+ defined(HAVE_CONST_PF_LINK) && \
12
+ defined(HAVE_CONST_NETLINK_GENERIC) && \
13
+ defined(HAVE_CONST_IFMIB_IFDATA) && \
14
+ defined(HAVE_CONST_IFDATA_GENERAL) && \
15
+ defined(HAVE_CONST_CTL_KERN) && \
16
+ defined(HAVE_CONST_KERN_BOOTTIME)
17
+ #include <vmstat.h>
18
+ #include <sys/sysctl.h>
19
+ #include <sys/types.h>
20
+ #include <sys/socket.h>
21
+ #include <net/if.h>
22
+ #include <net/if_mib.h>
23
+ #include <net/if_types.h>
24
+
25
+ #ifndef VMSTAT_NETWORK_INTERFACES
26
+ #define VMSTAT_NETWORK_INTERFACES
27
+ VALUE vmstat_network_interfaces(VALUE self) {
28
+ VALUE devices = rb_ary_new();
29
+ int i, err;
30
+ struct ifmibdata mibdata;
31
+ size_t len = sizeof(mibdata);
32
+ int ifmib_path[] = {
33
+ CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, -1, IFDATA_GENERAL
34
+ };
35
+
36
+ for (i = 1, err = 0; err == 0; i++) {
37
+ ifmib_path[4] = i; // set the current row
38
+ err = sysctl(ifmib_path, 6, &mibdata, &len, NULL, 0);
39
+ if (err == 0) {
40
+ VALUE device = rb_funcall(rb_path2class("Vmstat::NetworkInterface"),
41
+ rb_intern("new"), 7, ID2SYM(rb_intern(mibdata.ifmd_name)),
42
+ ULL2NUM(mibdata.ifmd_data.ifi_ibytes),
43
+ ULL2NUM(mibdata.ifmd_data.ifi_ierrors),
44
+ ULL2NUM(mibdata.ifmd_data.ifi_iqdrops),
45
+ ULL2NUM(mibdata.ifmd_data.ifi_obytes),
46
+ ULL2NUM(mibdata.ifmd_data.ifi_oerrors),
47
+ ULL2NUM(mibdata.ifmd_data.ifi_type));
48
+
49
+ rb_ary_push(devices, device);
50
+ }
51
+ }
52
+
53
+ return devices;
54
+ }
55
+ #endif
56
+
57
+ #ifndef VMSTAT_BOOT_TIME
58
+ #define VMSTAT_BOOT_TIME
59
+ static int BOOT_TIME_MIB[] = { CTL_KERN, KERN_BOOTTIME };
60
+
61
+ VALUE vmstat_boot_time(VALUE self) {
62
+ struct timeval tv;
63
+ size_t size = sizeof(tv);
64
+
65
+ if (sysctl(BOOT_TIME_MIB, 2, &tv, &size, NULL, 0) == 0) {
66
+ return rb_time_new(tv.tv_sec, tv.tv_usec);
67
+ } else {
68
+ return Qnil;
69
+ }
70
+ }
71
+ #endif
72
+ #endif