vmstat 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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