vmstat 0.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/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .DS_Store
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vmstat.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Vincent Landgraf
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # Vmstat
2
+
3
+ This is a focused and fast library to get system information like:
4
+
5
+ * _Memory_ (free, active, ...)
6
+ * _Network Devices_ (name, in bytes, out bytes, ...)
7
+ * _CPU_ (user, system, nice, idle)
8
+ * _Load_ Average
9
+ * _Disk_ (type, disk path, free bytes, total bytes, ...)
10
+
11
+ *It currently supports:*
12
+
13
+ * FreeBSD
14
+ * MacOS X
15
+
16
+ *It might support (but not tested):*
17
+
18
+ * OpenBSD
19
+ * NetBSD
20
+
21
+ ## Installation
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ gem 'vmstat'
26
+
27
+ And then execute:
28
+
29
+ $ bundle
30
+
31
+ Or install it yourself as:
32
+
33
+ $ gem install vmstat
34
+
35
+ ## Usage
36
+
37
+ Just require the library.
38
+
39
+ require "vmstat"
40
+
41
+ ### Memory
42
+
43
+ Vmstat.memory # => {...}
44
+
45
+ The result might look like this:
46
+
47
+ {:pagesize=>4096,
48
+ :wired=>668069,
49
+ :active=>185474,
50
+ :inactive=>546881,
51
+ :free=>694851,
52
+ :wired_bytes=>2240024576,
53
+ :active_bytes=>2736410624,
54
+ :inactive_bytes=>759701504,
55
+ :free_bytes=>2846109696,
56
+ :zero_filled=>176898850,
57
+ :reactivated=>41013,
58
+ :purgeable=>344211,
59
+ :purged=>11580,
60
+ :pageins=>2254222,
61
+ :pageouts=>0,
62
+ :faults=>204524839,
63
+ :copy_on_write_faults=>14379007,
64
+ :lookups=>2255061,
65
+ :hits=>95}
66
+
67
+
68
+ ### Network Devices
69
+
70
+ Vmstat.network # => {...}
71
+
72
+ The result might look like this:
73
+
74
+ {:lo0=>
75
+ {:in_bytes=>9082607,
76
+ :in_errors=>0,
77
+ :in_drops=>0,
78
+ :out_bytes=>9082607,
79
+ :out_errors=>0,
80
+ :type=>24},
81
+ :gif0=>
82
+ {:in_bytes=>0,
83
+ :in_errors=>0,
84
+ :in_drops=>0,
85
+ :out_bytes=>0,
86
+ :out_errors=>0,
87
+ :type=>55},
88
+ :stf0=>
89
+ {:in_bytes=>0,
90
+ :in_errors=>0,
91
+ :in_drops=>0,
92
+ :out_bytes=>0,
93
+ :out_errors=>0,
94
+ :type=>57},
95
+ :en0=>
96
+ {:in_bytes=>7108891975,
97
+ :in_errors=>0,
98
+ :in_drops=>0,
99
+ :out_bytes=>479503412,
100
+ :out_errors=>0,
101
+ :type=>6},
102
+ :p2p0=>
103
+ {:in_bytes=>0,
104
+ :in_errors=>0,
105
+ :in_drops=>0,
106
+ :out_bytes=>0,
107
+ :out_errors=>0,
108
+ :type=>6}}
109
+
110
+ ### CPU
111
+
112
+ Vmstat.cpu # => [...]
113
+
114
+ The result might look like this, depending on the number of cpus:
115
+
116
+ [{:user=>297003, :system=>475804, :nice=>0, :idle=>11059640},
117
+ {:user=>23349, :system=>14186, :nice=>0, :idle=>11792093},
118
+ {:user=>247171, :system=>195309, :nice=>0, :idle=>11387262},
119
+ {:user=>21783, :system=>12823, :nice=>0, :idle=>11794993},
120
+ {:user=>221323, :system=>163723, :nice=>0, :idle=>11444653},
121
+ {:user=>20608, :system=>11808, :nice=>0, :idle=>11797154},
122
+ {:user=>195015, :system=>145772, :nice=>0, :idle=>11488869},
123
+ {:user=>19793, :system=>11077, :nice=>0, :idle=>11798671}]
124
+
125
+ ### Load
126
+
127
+ Vmstat.load_avg #=> [0.35791015625, 0.4296875, 0.4609375]
128
+
129
+ ### Disk
130
+
131
+ To get the disk data one can pass the mount point or the device name.
132
+
133
+ # like so
134
+ Vmstat.disk("/") # => {...}
135
+
136
+ # or so
137
+ Vmstat.disk("/dev/disk0s2") # => {...}
138
+
139
+ The result looks like this:
140
+
141
+ {:type => :devfs,
142
+ :origin => "devfs",
143
+ :mount => "/dev",
144
+ :free_bytes => 0,
145
+ :available_bytes => 0,
146
+ :used_bytes => 192000,
147
+ :total_bytes => 192000}
148
+
149
+ ## Contributing
150
+
151
+ 1. Fork it
152
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
153
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
154
+ 4. Push to the branch (`git push origin my-new-feature`)
155
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+ require 'rake/extensiontask'
4
+ require 'rspec/core/rake_task'
5
+
6
+ Rake::ExtensionTask.new(:vmstat) do |ext|
7
+ ext.lib_dir = 'lib/vmstat'
8
+ end
9
+
10
+ desc "Run specs"
11
+ RSpec::Core::RakeTask.new(:spec)
12
+
13
+ desc "Open an irb session preloaded with smartstat"
14
+ task :console do
15
+ sh "irb -rubygems -I ./lib -r vmstat"
16
+ end
17
+
18
+ desc 'Default: run specs.'
19
+ task :default => :spec
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile 'vmstat/vmstat'
@@ -0,0 +1,282 @@
1
+ #include <sys/types.h>
2
+ #include <sys/socket.h>
3
+ #include <sys/sysctl.h>
4
+ #include <net/if.h>
5
+ #include <net/if_mib.h>
6
+ #include <net/if_types.h>
7
+ #include <sys/param.h>
8
+ #include <sys/mount.h>
9
+ #if defined(__APPLE__)
10
+ #include <mach/mach.h>
11
+ #endif
12
+ #include <vmstat.h>
13
+
14
+ void Init_vmstat() {
15
+ vmstat = rb_define_module("Vmstat");
16
+
17
+ rb_define_singleton_method(vmstat, "network", method_network, 0);
18
+ rb_define_singleton_method(vmstat, "cpu", method_cpu, 0);
19
+ rb_define_singleton_method(vmstat, "memory", method_memory, 0);
20
+ rb_define_singleton_method(vmstat, "disk", method_disk, 1);
21
+ rb_define_singleton_method(vmstat, "load_avg", method_load_avg, 0);
22
+ rb_define_singleton_method(vmstat, "boot_time", method_boot_time, 0);
23
+
24
+ // widely used symbols
25
+ SYM_TYPE = ID2SYM(rb_intern("type"));
26
+ SYM_FREE = ID2SYM(rb_intern("free"));
27
+
28
+ // network symbols
29
+ SYM_IN_BYTES = ID2SYM(rb_intern("in_bytes"));
30
+ SYM_IN_ERRORS = ID2SYM(rb_intern("in_errors"));
31
+ SYM_IN_DROPS = ID2SYM(rb_intern("in_drops"));
32
+ SYM_OUT_BYTES = ID2SYM(rb_intern("out_bytes"));
33
+ SYM_OUT_ERRORS = ID2SYM(rb_intern("out_errors"));
34
+
35
+ // cpu symbols
36
+ SYM_USER = ID2SYM(rb_intern("user"));
37
+ SYM_SYSTEM = ID2SYM(rb_intern("system"));
38
+ SYM_NICE = ID2SYM(rb_intern("nice"));
39
+ SYM_IDLE = ID2SYM(rb_intern("idle"));
40
+
41
+ // memory symbols
42
+ SYM_PAGESIZE = ID2SYM(rb_intern("pagesize"));
43
+ SYM_WIRED = ID2SYM(rb_intern("wired"));
44
+ SYM_ACTIVE = ID2SYM(rb_intern("active"));
45
+ SYM_INACTIVE = ID2SYM(rb_intern("inactive"));
46
+ SYM_WIRED_BYTES = ID2SYM(rb_intern("wired_bytes"));
47
+ SYM_ACTIVE_BYTES = ID2SYM(rb_intern("active_bytes"));
48
+ SYM_INACTIVE_BYTES = ID2SYM(rb_intern("inactive_bytes"));
49
+ SYM_FREE_BYTES = ID2SYM(rb_intern("free_bytes"));
50
+ SYM_ZERO_FILLED = ID2SYM(rb_intern("zero_filled"));
51
+ SYM_REACTIVATED = ID2SYM(rb_intern("reactivated"));
52
+ SYM_PURGEABLE = ID2SYM(rb_intern("purgeable"));
53
+ SYM_PURGED = ID2SYM(rb_intern("purged"));
54
+ SYM_PAGEINS = ID2SYM(rb_intern("pageins"));
55
+ SYM_PAGEOUTS = ID2SYM(rb_intern("pageouts"));
56
+ SYM_FAULTS = ID2SYM(rb_intern("faults"));
57
+ SYM_COW_FAULTS = ID2SYM(rb_intern("copy_on_write_faults"));
58
+ SYM_LOOKUPS = ID2SYM(rb_intern("lookups"));
59
+ SYM_HITS = ID2SYM(rb_intern("hits"));
60
+
61
+ // disk symbols
62
+ SYM_ORIGIN = ID2SYM(rb_intern("origin"));
63
+ SYM_MOUNT = ID2SYM(rb_intern("mount"));
64
+ SYM_AVAILABLE_BYTES = ID2SYM(rb_intern("available_bytes"));
65
+ SYM_USED_BYTES = ID2SYM(rb_intern("used_bytes"));
66
+ SYM_TOTAL_BYTES = ID2SYM(rb_intern("total_bytes"));
67
+ }
68
+
69
+ VALUE method_network(VALUE self) {
70
+ VALUE devices = rb_hash_new();
71
+ int i, err;
72
+ struct ifmibdata mibdata;
73
+ size_t len = sizeof(mibdata);
74
+ int ifmib_path[] = {
75
+ CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, -1, IFDATA_GENERAL
76
+ };
77
+
78
+ for (i = 1, err = 0; err == 0; i++) {
79
+ ifmib_path[4] = i; // set the current row
80
+ err = sysctl(ifmib_path, 6, &mibdata, &len, NULL, 0);
81
+ if (err == 0) {
82
+ VALUE device = rb_hash_new();
83
+ rb_hash_aset(device, SYM_IN_BYTES, ULL2NUM(mibdata.ifmd_data.ifi_ibytes));
84
+ rb_hash_aset(device, SYM_IN_ERRORS, ULL2NUM(mibdata.ifmd_data.ifi_ierrors));
85
+ rb_hash_aset(device, SYM_IN_DROPS, ULL2NUM(mibdata.ifmd_data.ifi_iqdrops));
86
+ rb_hash_aset(device, SYM_OUT_BYTES, ULL2NUM(mibdata.ifmd_data.ifi_obytes));
87
+ rb_hash_aset(device, SYM_OUT_ERRORS, ULL2NUM(mibdata.ifmd_data.ifi_oerrors));
88
+ rb_hash_aset(device, SYM_TYPE, ULL2NUM(mibdata.ifmd_data.ifi_type));
89
+ rb_hash_aset(devices, ID2SYM(rb_intern(mibdata.ifmd_name)), device);
90
+ }
91
+ }
92
+
93
+ return devices;
94
+ }
95
+
96
+ #if defined(__APPLE__)
97
+ VALUE method_cpu(VALUE self) {
98
+ VALUE cpus = rb_ary_new();
99
+ processor_info_array_t cpuInfo;
100
+ mach_msg_type_number_t numCpuInfo;
101
+ natural_t numCPUsU = 0U;
102
+ kern_return_t err = host_processor_info(mach_host_self(),
103
+ PROCESSOR_CPU_LOAD_INFO, &numCPUsU, &cpuInfo, &numCpuInfo);
104
+
105
+ if(err == KERN_SUCCESS) {
106
+ for(unsigned i = 0U; i < numCPUsU; ++i) {
107
+ VALUE cpu = rb_hash_new();
108
+ int pos = CPU_STATE_MAX * i;
109
+ rb_hash_aset(cpu, SYM_USER, ULL2NUM(cpuInfo[pos + CPU_STATE_USER]));
110
+ rb_hash_aset(cpu, SYM_SYSTEM, ULL2NUM(cpuInfo[pos + CPU_STATE_SYSTEM]));
111
+ rb_hash_aset(cpu, SYM_NICE, ULL2NUM(cpuInfo[pos + CPU_STATE_NICE]));
112
+ rb_hash_aset(cpu, SYM_IDLE, ULL2NUM(cpuInfo[pos + CPU_STATE_IDLE]));
113
+ rb_ary_push(cpus, cpu);
114
+ }
115
+ }
116
+
117
+ return cpus;
118
+ }
119
+
120
+ VALUE method_memory(VALUE self) {
121
+ VALUE memory = Qnil;
122
+ vm_size_t pagesize;
123
+ uint host_count = HOST_VM_INFO_COUNT;
124
+ kern_return_t err;
125
+ vm_statistics_data_t vm_stat;
126
+
127
+ err = host_page_size(mach_host_self(), &pagesize);
128
+ if (err == KERN_SUCCESS) {
129
+ err = host_statistics(mach_host_self(), HOST_VM_INFO,
130
+ (host_info_t)&vm_stat, &host_count);
131
+ if (err == KERN_SUCCESS) {
132
+ memory = rb_hash_new();
133
+ rb_hash_aset(memory, SYM_PAGESIZE, ULL2NUM(pagesize));
134
+ rb_hash_aset(memory, SYM_WIRED, ULL2NUM(vm_stat.active_count));
135
+ rb_hash_aset(memory, SYM_ACTIVE, ULL2NUM(vm_stat.inactive_count));
136
+ rb_hash_aset(memory, SYM_INACTIVE, ULL2NUM(vm_stat.wire_count));
137
+ rb_hash_aset(memory, SYM_FREE, ULL2NUM(vm_stat.free_count));
138
+ rb_hash_aset(memory, SYM_WIRED_BYTES, ULL2NUM(vm_stat.wire_count * pagesize));
139
+ rb_hash_aset(memory, SYM_ACTIVE_BYTES, ULL2NUM(vm_stat.active_count * pagesize));
140
+ rb_hash_aset(memory, SYM_INACTIVE_BYTES, ULL2NUM(vm_stat.inactive_count * pagesize));
141
+ rb_hash_aset(memory, SYM_FREE_BYTES, ULL2NUM(vm_stat.free_count * pagesize));
142
+ rb_hash_aset(memory, SYM_ZERO_FILLED, ULL2NUM(vm_stat.zero_fill_count));
143
+ rb_hash_aset(memory, SYM_REACTIVATED, ULL2NUM(vm_stat.reactivations));
144
+ rb_hash_aset(memory, SYM_PURGEABLE, ULL2NUM(vm_stat.purgeable_count));
145
+ rb_hash_aset(memory, SYM_PURGED, ULL2NUM(vm_stat.purges));
146
+ rb_hash_aset(memory, SYM_PAGEINS, ULL2NUM(vm_stat.pageins));
147
+ rb_hash_aset(memory, SYM_PAGEOUTS, ULL2NUM(vm_stat.pageouts));
148
+ rb_hash_aset(memory, SYM_FAULTS, ULL2NUM(vm_stat.faults));
149
+ rb_hash_aset(memory, SYM_COW_FAULTS, ULL2NUM(vm_stat.cow_faults));
150
+ rb_hash_aset(memory, SYM_LOOKUPS, ULL2NUM(vm_stat.lookups));
151
+ rb_hash_aset(memory, SYM_HITS, ULL2NUM(vm_stat.hits));
152
+ }
153
+ }
154
+
155
+ return memory;
156
+ }
157
+ #elif __linux
158
+ // linux
159
+ #elif __unix // all unices not caught above
160
+ typedef struct {
161
+ long user;
162
+ long nice;
163
+ long system;
164
+ long intr;
165
+ long idle;
166
+ } cpu_time_t;
167
+
168
+ VALUE method_cpu(VALUE self) {
169
+ VALUE cpus = rb_ary_new();
170
+ int cpu_count = system_int("hw.ncpu");
171
+ size_t len = sizeof(cpu_time_t) * cpu_count;
172
+ cpu_time_t * cp_times = ALLOC_N(cpu_time_t, cpu_count);
173
+ int i;
174
+
175
+ if (sysctlbyname("kern.cp_times", cp_times, &len, NULL, 0) == 0) {
176
+ for (i = 0; i < cpu_count; i++) {
177
+ VALUE cpu = rb_hash_new();
178
+ cpu_time_t cp_time = cp_times[i];
179
+ rb_hash_aset(cpu, SYM_USER, LONG2NUM(cp_time.user));
180
+ rb_hash_aset(cpu, SYM_SYSTEM, LONG2NUM(cp_time.system + cp_time.intr));
181
+ rb_hash_aset(cpu, SYM_NICE, LONG2NUM(cp_time.nice));
182
+ rb_hash_aset(cpu, SYM_IDLE, LONG2NUM(cp_time.idle));
183
+ rb_ary_push(cpus, cpu);
184
+ }
185
+ }
186
+ free(cp_times);
187
+
188
+ return cpus;
189
+ }
190
+
191
+ VALUE method_memory(VALUE self) {
192
+ VALUE memory = rb_hash_new();
193
+ unsigned long long pagesize = system_ull("vm.stats.vm.v_page_size");
194
+
195
+ rb_hash_aset(memory, SYM_PAGESIZE, ULL2NUM(pagesize));
196
+ rb_hash_aset(memory, SYM_WIRED, ULL2NUM(system_ull("vm.stats.vm.v_inactive_count")));
197
+ rb_hash_aset(memory, SYM_ACTIVE, ULL2NUM(system_ull("vm.stats.vm.v_active_count")));
198
+ rb_hash_aset(memory, SYM_INACTIVE, ULL2NUM(system_ull("vm.stats.vm.v_wire_count")));
199
+ rb_hash_aset(memory, SYM_FREE, ULL2NUM(system_ull("vm.stats.vm.v_free_count")));
200
+ rb_hash_aset(memory, SYM_WIRED_BYTES, ULL2NUM((system_ull("vm.stats.vm.v_cache_count") +
201
+ system_ull("vm.stats.vm.v_wire_count")) * pagesize));
202
+ rb_hash_aset(memory, SYM_ACTIVE_BYTES, ULL2NUM(system_ull("vm.stats.vm.v_active_count") * pagesize));
203
+ rb_hash_aset(memory, SYM_INACTIVE_BYTES, ULL2NUM(system_ull("vm.stats.vm.v_inactive_count") * pagesize));
204
+ rb_hash_aset(memory, SYM_FREE_BYTES, ULL2NUM(system_ull("vm.stats.vm.v_free_count") * pagesize));
205
+ rb_hash_aset(memory, SYM_ZERO_FILLED, ULL2NUM(system_ull("vm.stats.misc.zero_page_count")));
206
+ rb_hash_aset(memory, SYM_REACTIVATED, ULL2NUM(system_ull("vm.stats.vm.v_reactivated")));
207
+ rb_hash_aset(memory, SYM_PURGEABLE, Qnil);
208
+ rb_hash_aset(memory, SYM_PURGED, Qnil);
209
+ rb_hash_aset(memory, SYM_PAGEINS, Qnil);
210
+ rb_hash_aset(memory, SYM_PAGEOUTS, Qnil);
211
+ rb_hash_aset(memory, SYM_FAULTS, ULL2NUM(system_ull("vm.stats.vm.v_vm_faults")));
212
+ rb_hash_aset(memory, SYM_COW_FAULTS, ULL2NUM(system_ull("vm.stats.vm.v_cow_faults")));
213
+ rb_hash_aset(memory, SYM_LOOKUPS, Qnil);
214
+ rb_hash_aset(memory, SYM_HITS, Qnil);
215
+
216
+ return memory;
217
+ }
218
+ #elif __posix
219
+ // POSIX
220
+ #endif
221
+
222
+ VALUE method_disk(VALUE self, VALUE path) {
223
+ VALUE disk = Qnil;
224
+ struct statfs stat;
225
+
226
+ if (statfs(StringValueCStr(path), &stat) != -1) {
227
+ disk = rb_hash_new();
228
+ rb_hash_aset(disk, SYM_TYPE, ID2SYM(rb_intern(stat.f_fstypename)));
229
+ rb_hash_aset(disk, SYM_ORIGIN, rb_str_new(stat.f_mntfromname, strlen(stat.f_mntfromname)));
230
+ rb_hash_aset(disk, SYM_MOUNT, rb_str_new(stat.f_mntonname, strlen(stat.f_mntonname)));
231
+ rb_hash_aset(disk, SYM_FREE_BYTES, ULL2NUM(stat.f_bfree * stat.f_bsize));
232
+ rb_hash_aset(disk, SYM_AVAILABLE_BYTES, ULL2NUM(stat.f_bavail * stat.f_bsize));
233
+ rb_hash_aset(disk, SYM_USED_BYTES, ULL2NUM((stat.f_blocks - stat.f_bfree) * stat.f_bsize));
234
+ rb_hash_aset(disk, SYM_TOTAL_BYTES, ULL2NUM(stat.f_blocks * stat.f_bsize));
235
+ }
236
+
237
+ return disk;
238
+ }
239
+
240
+ #define AVGCOUNT 3
241
+ VALUE method_load_avg(VALUE self) {
242
+ VALUE loads = rb_ary_new();
243
+ double loadavg[AVGCOUNT];
244
+ int i;
245
+
246
+ getloadavg(&loadavg[0], AVGCOUNT);
247
+ for(i = 0; i < AVGCOUNT; i++) {
248
+ rb_ary_push(loads, rb_float_new(loadavg[i]));
249
+ }
250
+
251
+ return loads;
252
+ }
253
+
254
+ VALUE method_boot_time(VALUE self) {
255
+ struct timeval tv;
256
+ size_t size = sizeof(tv);
257
+ static int which[] = { CTL_KERN, KERN_BOOTTIME };
258
+
259
+ if (sysctl(which, 2, &tv, &size, NULL, 0) == 0) {
260
+ return rb_time_new(tv.tv_sec, tv.tv_usec);
261
+ } else {
262
+ return Qnil;
263
+ }
264
+ }
265
+
266
+ int system_int(const char * name) {
267
+ int number;
268
+ size_t number_size = sizeof(number);
269
+ sysctlbyname(name, &number, &number_size, NULL, 0);
270
+ return number;
271
+ }
272
+
273
+ unsigned long long system_ull(const char * name) {
274
+ long number;
275
+ size_t number_size = sizeof(number);
276
+ if (sysctlbyname(name, &number, &number_size, NULL, 0) == -1) {
277
+ perror("sysctlbyname");
278
+ return -1;
279
+ } else {
280
+ return number;
281
+ }
282
+ }
@@ -0,0 +1,22 @@
1
+ #include <ruby.h>
2
+
3
+ VALUE vmstat = Qnil;
4
+ VALUE vmstat_hardware = Qnil;
5
+ VALUE method_network(VALUE self);
6
+ VALUE method_cpu(VALUE self);
7
+ VALUE method_memory(VALUE self);
8
+ VALUE method_disk(VALUE self, VALUE path);
9
+ VALUE method_load_avg(VALUE self);
10
+ VALUE method_boot_time(VALUE self);
11
+
12
+ int system_int(const char *);
13
+ unsigned long long system_ull(const char *);
14
+
15
+ VALUE SYM_TYPE, SYM_FREE, SYM_FREE_BYTES;
16
+ VALUE SYM_IN_BYTES, SYM_IN_ERRORS, SYM_IN_DROPS, SYM_OUT_BYTES, SYM_OUT_ERRORS;
17
+ VALUE SYM_USER, SYM_SYSTEM, SYM_NICE, SYM_IDLE;
18
+ VALUE SYM_ORIGIN, SYM_MOUNT, SYM_AVAILABLE_BYTES, SYM_TOTAL_BYTES, SYM_USED_BYTES;
19
+ VALUE SYM_PAGESIZE, SYM_WIRED, SYM_ACTIVE, SYM_INACTIVE, SYM_ZERO_FILLED,
20
+ SYM_REACTIVATED, SYM_PURGEABLE, SYM_PURGED, SYM_PAGEINS, SYM_PAGEOUTS,
21
+ SYM_FAULTS, SYM_COW_FAULTS, SYM_LOOKUPS, SYM_HITS, SYM_WIRED_BYTES,
22
+ SYM_ACTIVE_BYTES, SYM_INACTIVE_BYTES;
data/lib/vmstat.rb ADDED
@@ -0,0 +1,50 @@
1
+ require "vmstat/version"
2
+ require "vmstat/vmstat" # native lib
3
+
4
+ module Vmstat
5
+ # The type of ethernet devices on freebsd/mac os x
6
+ ETHERNET_TYPE = 0x06
7
+
8
+ # The type of loopback devices on freebsd/mac os x
9
+ LOOPBACK_TYPE = 0x18
10
+
11
+ # Filters all available ethernet devices.
12
+ # @return [Hash<Symbol, Hash>] the ethernet device name and values
13
+ # @example
14
+ # Vmstat.ethernet_devices # => { :en0 => {
15
+ # # :in_bytes=>7104874723,
16
+ # # :in_errors=>0,
17
+ # # :in_drops=>0,
18
+ # # :out_bytes=>478849502,
19
+ # # :out_errors=>0,
20
+ # # :type=>6},
21
+ # # :p2p0=> ...
22
+ def self.ethernet_devices
23
+ filter_devices ETHERNET_TYPE
24
+ end
25
+
26
+ # Filters all available loopback devices.
27
+ # @return [Hash<Symbol, Hash>] the loopback device name and values
28
+ # @example
29
+ # Vmstat.loopback_devices # => { :lo0 => {
30
+ # # :in_bytes=>6935997,
31
+ # # :in_errors=>0,
32
+ # # :in_drops=>0,
33
+ # # :out_bytes=>6935997,
34
+ # # :out_errors=>0,
35
+ # # :type=>24
36
+ # # }}
37
+ def self.loopback_devices
38
+ filter_devices LOOPBACK_TYPE
39
+ end
40
+
41
+ # A method to filter the devices.
42
+ # @param [Fixnum] type the type to filter for
43
+ # @return [Hash<Symbol, Hash>] the filtered device name and values
44
+ # @api private
45
+ def self.filter_devices(type)
46
+ network.select do |name, attrbutes|
47
+ attrbutes[:type] == type
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module Vmstat
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,20 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ $:.unshift(File.expand_path("../lib", __FILE__))
8
+ require 'vmstat'
9
+
10
+ RSpec.configure do |config|
11
+ config.treat_symbols_as_metadata_keys_with_true_values = true
12
+ config.run_all_when_everything_filtered = true
13
+ config.filter_run :focus
14
+
15
+ # Run specs in random order to surface order dependencies. If you find an
16
+ # order dependency and want to debug it, you can fix the order by providing
17
+ # the seed, which is printed after each run.
18
+ # --seed 1234
19
+ config.order = 'random'
20
+ end
@@ -0,0 +1,184 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ describe Vmstat do
5
+ context "#network" do
6
+ let(:network) { Vmstat.network }
7
+
8
+ it "should return the enthernet and loopback network data as hash" do
9
+ network.should be_a(Hash)
10
+ end
11
+
12
+ context "loopback device" do
13
+ let(:loopback) { network[:lo0] }
14
+ subject { loopback }
15
+
16
+ it "should contain the a loopback device info also as a hash" do
17
+ should be_a(Hash)
18
+ end
19
+
20
+ context "keys" do
21
+ it { should have_key(:in_bytes) }
22
+ it { should have_key(:out_bytes) }
23
+ it { should have_key(:in_errors) }
24
+ it { should have_key(:out_errors) }
25
+ it { should have_key(:in_drops) }
26
+ it { should have_key(:type) }
27
+ end
28
+
29
+ context "type" do
30
+ subject { OpenStruct.new loopback }
31
+
32
+ its(:in_bytes) { should be_a_kind_of(Numeric) }
33
+ its(:out_bytes) { should be_a_kind_of(Numeric) }
34
+ its(:in_errors) { should be_a_kind_of(Numeric) }
35
+ its(:out_errors) { should be_a_kind_of(Numeric) }
36
+ its(:in_drops) { should be_a_kind_of(Numeric) }
37
+ its(:type) { should be_a_kind_of(Numeric) }
38
+ end
39
+ end
40
+ end
41
+
42
+ context "#cpu" do
43
+ let(:cpu) { Vmstat.cpu }
44
+
45
+ it "should return an array of ethernet information" do
46
+ cpu.should be_a(Array)
47
+ end
48
+
49
+ context "first cpu" do
50
+ let(:first_cpu) { cpu.first }
51
+ subject { first_cpu }
52
+
53
+ it "should return a hash containing per cpu information" do
54
+ should be_a(Hash)
55
+ end
56
+
57
+ context "keys" do
58
+ it { should have_key(:user) }
59
+ it { should have_key(:system) }
60
+ it { should have_key(:nice) }
61
+ it { should have_key(:idle) }
62
+ end
63
+
64
+ context "type" do
65
+ subject { OpenStruct.new first_cpu }
66
+
67
+ its(:user) { should be_a_kind_of(Numeric) }
68
+ its(:system) { should be_a_kind_of(Numeric) }
69
+ its(:nice) { should be_a_kind_of(Numeric) }
70
+ its(:idle) { should be_a_kind_of(Numeric) }
71
+ end
72
+ end
73
+ end
74
+
75
+ context "#memory" do
76
+ let(:memory) { Vmstat.memory }
77
+ subject { memory }
78
+
79
+ it "should be a hash of memory data" do
80
+ should be_a(Hash)
81
+ end
82
+
83
+ context "keys" do
84
+ it { should have_key(:pagesize) }
85
+ it { should have_key(:wired) }
86
+ it { should have_key(:active) }
87
+ it { should have_key(:inactive) }
88
+ it { should have_key(:free) }
89
+ it { should have_key(:wired_bytes) }
90
+ it { should have_key(:active_bytes) }
91
+ it { should have_key(:inactive_bytes) }
92
+ it { should have_key(:free_bytes) }
93
+ it { should have_key(:zero_filled) }
94
+ it { should have_key(:reactivated) }
95
+ it { should have_key(:faults) }
96
+ it { should have_key(:copy_on_write_faults) }
97
+ end
98
+
99
+ context "type" do
100
+ subject { OpenStruct.new memory }
101
+
102
+ its(:pagesize) { should be_a_kind_of(Numeric) }
103
+ its(:wired) { should be_a_kind_of(Numeric) }
104
+ its(:active) { should be_a_kind_of(Numeric) }
105
+ its(:inactive) { should be_a_kind_of(Numeric) }
106
+ its(:free) { should be_a_kind_of(Numeric) }
107
+ its(:wired_bytes) { should be_a_kind_of(Numeric) }
108
+ its(:active_bytes) { should be_a_kind_of(Numeric) }
109
+ its(:inactive_bytes) { should be_a_kind_of(Numeric) }
110
+ its(:free_bytes) { should be_a_kind_of(Numeric) }
111
+ its(:zero_filled) { should be_a_kind_of(Numeric) }
112
+ its(:reactivated) { should be_a_kind_of(Numeric) }
113
+ its(:faults) { should be_a_kind_of(Numeric) }
114
+ its(:copy_on_write_faults) { should be_a_kind_of(Numeric) }
115
+ end
116
+ end
117
+
118
+ context "#disk" do
119
+ let(:disk) { Vmstat.disk("/") }
120
+ subject { disk }
121
+
122
+ it "should be a hash of disk data" do
123
+ should be_a(Hash)
124
+ end
125
+
126
+ context "keys" do
127
+ it { should have_key(:type) }
128
+ it { should have_key(:origin) }
129
+ it { should have_key(:mount) }
130
+ it { should have_key(:free_bytes) }
131
+ it { should have_key(:available_bytes) }
132
+ it { should have_key(:used_bytes) }
133
+ it { should have_key(:total_bytes) }
134
+ end
135
+
136
+ context "type" do
137
+ subject { OpenStruct.new disk }
138
+
139
+ its(:type) { should be_a(Symbol) }
140
+ its(:origin) { should be_a(String) }
141
+ its(:mount) { should be_a(String) }
142
+ its(:free_bytes) { should be_a_kind_of(Numeric) }
143
+ its(:available_bytes) { should be_a_kind_of(Numeric) }
144
+ its(:used_bytes) { should be_a_kind_of(Numeric) }
145
+ its(:total_bytes) { should be_a_kind_of(Numeric) }
146
+ end
147
+ end
148
+
149
+ context "#load_avg" do
150
+ subject { Vmstat.load_avg }
151
+
152
+ it "should be an array" do
153
+ should be_a(Array)
154
+ end
155
+
156
+ it "should have three floats" do
157
+ subject[0].should be_a(Float)
158
+ subject[1].should be_a(Float)
159
+ subject[2].should be_a(Float)
160
+ end
161
+ end
162
+
163
+ context "#boot_time" do
164
+ let(:boot_time) { Vmstat.boot_time }
165
+
166
+ it "should be an array" do
167
+ boot_time.should be_a(Time)
168
+ end
169
+
170
+ it "has to be a time before now" do
171
+ boot_time.should < Time.now
172
+ end
173
+ end
174
+
175
+ context "#filter_devices" do
176
+ it "should filter ethernet devices" do
177
+ Vmstat.ethernet_devices.size.should == 2
178
+ end
179
+
180
+ it "should filter loopback devices" do
181
+ Vmstat.loopback_devices.size.should == 1
182
+ end
183
+ end
184
+ end
data/vmstat.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vmstat/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "vmstat"
8
+ gem.version = Vmstat::VERSION
9
+ gem.authors = ["Vincent Landgraf"]
10
+ gem.email = ["vilandgr@googlemail.com"]
11
+ gem.description = %q{
12
+ A focused and fast library t gather memory,
13
+ cpu, network, load avg and disk information
14
+ }
15
+ gem.summary = %q{A focused and fast library t gather system information}
16
+ gem.homepage = "http://threez.github.com/ruby-vmstat/"
17
+
18
+ gem.files = `git ls-files`.split($/)
19
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
20
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
21
+ gem.require_paths = ["lib"]
22
+ gem.extensions = ["ext/vmstat/extconf.rb"]
23
+
24
+ gem.add_development_dependency('rspec')
25
+ gem.add_development_dependency('rake-compiler')
26
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vmstat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Vincent Landgraf
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake-compiler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: ! "\n A focused and fast library t gather memory, \n cpu, network,
47
+ load avg and disk information\n "
48
+ email:
49
+ - vilandgr@googlemail.com
50
+ executables: []
51
+ extensions:
52
+ - ext/vmstat/extconf.rb
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - .rspec
57
+ - .rvmrc
58
+ - Gemfile
59
+ - LICENSE.txt
60
+ - README.md
61
+ - Rakefile
62
+ - ext/vmstat/extconf.rb
63
+ - ext/vmstat/vmstat.c
64
+ - ext/vmstat/vmstat.h
65
+ - lib/vmstat.rb
66
+ - lib/vmstat/version.rb
67
+ - spec/spec_helper.rb
68
+ - spec/vmstat_spec.rb
69
+ - vmstat.gemspec
70
+ homepage: http://threez.github.com/ruby-vmstat/
71
+ licenses: []
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 1.8.24
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: A focused and fast library t gather system information
94
+ test_files:
95
+ - spec/spec_helper.rb
96
+ - spec/vmstat_spec.rb
97
+ has_rdoc: