proceso 0.0.0 → 0.1.1
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.
- checksums.yaml +4 -4
- data/ext/proceso/darwin.c +69 -0
- data/ext/proceso/darwin.h +18 -0
- data/ext/proceso/extconf.rb +17 -1
- data/ext/proceso/linux.c +90 -0
- data/ext/proceso/linux.h +64 -0
- data/ext/proceso/pid.c +87 -0
- data/ext/proceso/proceso.c +36 -0
- data/ext/proceso/proceso.h +20 -0
- data/ext/proceso/utility.c +88 -0
- data/ext/proceso/utility.h +4 -0
- data/lib/proceso/middleware.rb +71 -0
- data/lib/proceso/pid.rb +26 -0
- data/lib/proceso/version.rb +2 -2
- data/lib/proceso.rb +29 -1
- data/spec/proceso/pid_spec.rb +72 -0
- data/spec/proceso_spec.rb +10 -30
- metadata +30 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ba2fac203e9bf0d1bec8ad20defc3ff07582c5f
|
4
|
+
data.tar.gz: a40f55f136b868bd641129c5c8680feb2e3855d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9d453e1d265a4d3625328733ceadc4cbc26a34cd22c90cf131512ca1f57caf5fcabb54da937953a4c14802c17221f59f149bd588249541a3ebaa02b4c548dfd
|
7
|
+
data.tar.gz: d914eddb8fe44c1fdafaf6c73b689481f7a94c9b06b26e1ee66d738d4120dc910958b227227a4a7b528e4994abb7f06a0d593a35874dc35a24e17c949b16872a
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#ifdef __APPLE__
|
2
|
+
|
3
|
+
#include "darwin.h"
|
4
|
+
|
5
|
+
int rb_sysctl_kern_argmax() {
|
6
|
+
int ret, argmax;
|
7
|
+
int mib[2] = { CTL_KERN, KERN_ARGMAX };
|
8
|
+
size_t buf_size = sizeof(argmax);
|
9
|
+
ret = sysctl(mib, 2, &argmax, &buf_size, NULL, 0);
|
10
|
+
if (ret == 0) {
|
11
|
+
return argmax;
|
12
|
+
}
|
13
|
+
return 0;
|
14
|
+
}
|
15
|
+
|
16
|
+
int rb_sysctl_kern_procargs2(int pid, char **process_name, int argmax, size_t buf_size) {
|
17
|
+
int ret, nargs;
|
18
|
+
int mib[3] = { CTL_KERN, KERN_PROCARGS, pid };
|
19
|
+
char *process;
|
20
|
+
process = (char *)malloc(argmax);
|
21
|
+
ret = sysctl(mib, 3, process, &buf_size, NULL, 0);
|
22
|
+
if (ret < 0) {
|
23
|
+
free(process);
|
24
|
+
return 0;
|
25
|
+
}
|
26
|
+
memcpy(&nargs, process, sizeof(nargs));
|
27
|
+
*process_name = process + sizeof(nargs);
|
28
|
+
return 1;
|
29
|
+
}
|
30
|
+
|
31
|
+
int rb_process_info(int pid, int flavor, void *pti, int size) {
|
32
|
+
int ret = proc_pidinfo(pid, flavor, 0, pti, size);
|
33
|
+
if ((ret == 0) || (ret != size)) {
|
34
|
+
return 0;
|
35
|
+
} else {
|
36
|
+
return 1;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
/* List of Processes */
|
41
|
+
int * rb_process_list() {
|
42
|
+
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
|
43
|
+
size_t buf_size;
|
44
|
+
int ret;
|
45
|
+
int list[4096];
|
46
|
+
ret = sysctl(mib, 4, NULL, &buf_size, NULL, 0);
|
47
|
+
if (ret >= 0) {
|
48
|
+
struct kinfo_proc *processes = NULL;
|
49
|
+
int i, nb_entries;
|
50
|
+
nb_entries = buf_size / sizeof(struct kinfo_proc);
|
51
|
+
processes = (struct kinfo_proc*) malloc(buf_size);
|
52
|
+
if (processes != NULL) {
|
53
|
+
ret = sysctl(mib, 4, processes, &buf_size, NULL, 0);
|
54
|
+
if (ret >= 0) {
|
55
|
+
for (i = 0; i < nb_entries; i++) {
|
56
|
+
int pid = processes[i].kp_proc.p_pid;
|
57
|
+
list[i] = pid;
|
58
|
+
}
|
59
|
+
free(processes);
|
60
|
+
return list;
|
61
|
+
}
|
62
|
+
free(processes);
|
63
|
+
return 0;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
return 0;
|
67
|
+
}
|
68
|
+
|
69
|
+
#endif
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <unistd.h>
|
3
|
+
#include <stdlib.h>
|
4
|
+
#include <string.h>
|
5
|
+
#include <errno.h>
|
6
|
+
#include <sys/sysctl.h>
|
7
|
+
#include <signal.h>
|
8
|
+
|
9
|
+
#if defined(__APPLE__)
|
10
|
+
# include <mach/mach.h>
|
11
|
+
# include <libproc.h>
|
12
|
+
#endif
|
13
|
+
|
14
|
+
|
15
|
+
int rb_sysctl_kern_argmax();
|
16
|
+
int rb_sysctl_kern_procargs2(int pid, char **process_name, int argmax, size_t buf_size);
|
17
|
+
int rb_process_info(int pid, int flavor, void *pti, int size);
|
18
|
+
int * rb_process_list();
|
data/ext/proceso/extconf.rb
CHANGED
@@ -1,3 +1,19 @@
|
|
1
1
|
require "mkmf"
|
2
2
|
|
3
|
-
|
3
|
+
RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
|
4
|
+
|
5
|
+
def have_platform(name)
|
6
|
+
have_header("#{name}.h")
|
7
|
+
$objs.unshift "#{name}.o"
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
$objs = ["utility.o", "pid.o", "proceso.o"]
|
12
|
+
case RUBY_PLATFORM
|
13
|
+
when /linux/ then have_platform("linux")
|
14
|
+
when /darwin/ then have_platform("darwin")
|
15
|
+
else
|
16
|
+
raise "#{RUBY_PLATFORM} is not currently supported. Send Pull Request for platform support"
|
17
|
+
end
|
18
|
+
|
19
|
+
create_makefile('proceso/proceso')
|
data/ext/proceso/linux.c
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#if defined(__linux) || defined(__LINUX__) || defined(__linux__)
|
2
|
+
|
3
|
+
#include "linux.h"
|
4
|
+
// const char *format = "%d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu";
|
5
|
+
|
6
|
+
int rb_proc_ncpu() {
|
7
|
+
int ncpu = 0;
|
8
|
+
char buffer[120];
|
9
|
+
FILE *fp;
|
10
|
+
fp = fopen("/proc/cpuinfo","r");
|
11
|
+
if(!fp)
|
12
|
+
return 0;
|
13
|
+
while(fgets(buffer,120,fp)){
|
14
|
+
if(strncmp(buffer,"processor",9) == 0)
|
15
|
+
++ncpu;
|
16
|
+
}
|
17
|
+
fclose(fp);
|
18
|
+
return ncpu;
|
19
|
+
}
|
20
|
+
int rb_proc_pid_rss(int pid) {
|
21
|
+
const char *format = "%*d %*s %*c %*d %*d %*d %*d %*d %*lu %*lu %*lu %*lu %*lu %*lu %*lu %*ld %*ld %*ld %*ld %*ld %*ld %*lu %*lu %ld";
|
22
|
+
int rss_size = 0;
|
23
|
+
char buffer[256];
|
24
|
+
FILE *fp;
|
25
|
+
sprintf(buffer, "/proc/%d/stat", pid);
|
26
|
+
fp = fopen(buffer, "r");
|
27
|
+
if (!fp)
|
28
|
+
return 0;
|
29
|
+
fscanf(fp, format, &rss_size);
|
30
|
+
fclose(fp);
|
31
|
+
return rss_size;
|
32
|
+
}
|
33
|
+
|
34
|
+
int rb_proc_pid_vsize(int pid) {
|
35
|
+
const char *format = "%*d %*s %*c %*d %*d %*d %*d %*d %*lu %*lu %*lu %*lu %*lu %*lu %*lu %*ld %*ld %*ld %*ld %*ld %*ld %*lu %lu";
|
36
|
+
int vsize = 0;
|
37
|
+
char buffer[256];
|
38
|
+
FILE *fp;
|
39
|
+
sprintf(buffer, "/proc/%d/stat", pid);
|
40
|
+
fp = fopen(buffer, "r");
|
41
|
+
if (!fp)
|
42
|
+
return 0;
|
43
|
+
fscanf(fp, format, &vsize);
|
44
|
+
fclose(fp);
|
45
|
+
return vsize;
|
46
|
+
}
|
47
|
+
|
48
|
+
float rb_proc_pid_stime(int pid) {
|
49
|
+
const char *format = "%*d %*s %*c %*d %*d %*d %*d %*d %*lu %*lu %*lu %*lu %*lu %*lu %lu";
|
50
|
+
int stime = 0;
|
51
|
+
char buffer[256];
|
52
|
+
FILE *fp;
|
53
|
+
sprintf(buffer, "/proc/%d/stat", pid);
|
54
|
+
fp = fopen(buffer, "r");
|
55
|
+
if (!fp)
|
56
|
+
return 0;
|
57
|
+
fscanf(fp, format, &stime);
|
58
|
+
fclose(fp);
|
59
|
+
return stime / 1000000.0;
|
60
|
+
}
|
61
|
+
|
62
|
+
float rb_proc_pid_utime(int pid) {
|
63
|
+
const char *format = "%*d %*s %*c %*d %*d %*d %*d %*d %*lu %*lu %*lu %*lu %*lu %lu";
|
64
|
+
int utime = 0;
|
65
|
+
char buffer[256];
|
66
|
+
FILE *fp;
|
67
|
+
sprintf(buffer, "/proc/%d/stat", pid);
|
68
|
+
fp = fopen(buffer, "r");
|
69
|
+
if (!fp)
|
70
|
+
return 0;
|
71
|
+
fscanf(fp, format, &utime);
|
72
|
+
fclose(fp);
|
73
|
+
return utime / 1000000.0;
|
74
|
+
}
|
75
|
+
|
76
|
+
char * rb_proc_pid_cmdline(int pid) {
|
77
|
+
char buffer[512];
|
78
|
+
FILE *fp;
|
79
|
+
char *cmdline;
|
80
|
+
size_t size = 0;
|
81
|
+
sprintf(buffer, "/proc/%d/cmdline", pid);
|
82
|
+
fp = fopen(buffer, "rb");
|
83
|
+
if (!fp)
|
84
|
+
return NULL;
|
85
|
+
getdelim(&cmdline, &size, 0 , fp);
|
86
|
+
fclose(fp);
|
87
|
+
return cmdline;
|
88
|
+
}
|
89
|
+
|
90
|
+
#endif
|
data/ext/proceso/linux.h
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <unistd.h>
|
3
|
+
#include <stdlib.h>
|
4
|
+
#include <string.h>
|
5
|
+
#include <errno.h>
|
6
|
+
#include <sys/sysctl.h>
|
7
|
+
#include <signal.h>
|
8
|
+
|
9
|
+
#ifndef __LINUX__
|
10
|
+
# define __LINUX__
|
11
|
+
#endif
|
12
|
+
|
13
|
+
struct proc_pid_stat {
|
14
|
+
int pid; // %d
|
15
|
+
char comm[256]; // %s
|
16
|
+
char state; // %c
|
17
|
+
int ppid; // %d
|
18
|
+
int pgrp; // %d
|
19
|
+
int session; // %d
|
20
|
+
int tty_nr; // %d
|
21
|
+
int tpgid; // %d
|
22
|
+
unsigned long flags; // %lu
|
23
|
+
unsigned long minflt; // %lu
|
24
|
+
unsigned long cminflt; // %lu
|
25
|
+
unsigned long majflt; // %lu
|
26
|
+
unsigned long cmajflt; // %lu
|
27
|
+
unsigned long utime; // %lu
|
28
|
+
unsigned long stime; // %lu
|
29
|
+
long cutime; // %ld
|
30
|
+
long cstime; // %ld
|
31
|
+
long priority; // %ld
|
32
|
+
long nice; // %ld
|
33
|
+
long num_threads; // %ld
|
34
|
+
long itrealvalue; // %ld
|
35
|
+
unsigned long starttime; // %lu
|
36
|
+
unsigned long vsize; // %lu
|
37
|
+
long rss; // %ld
|
38
|
+
unsigned long rlim; // %lu
|
39
|
+
unsigned long startcode; // %lu
|
40
|
+
unsigned long endcode; // %lu
|
41
|
+
unsigned long startstack; // %lu
|
42
|
+
unsigned long kstkesp; // %lu
|
43
|
+
unsigned long kstkeip; // %lu
|
44
|
+
unsigned long signal; // %lu
|
45
|
+
unsigned long blocked; // %lu
|
46
|
+
unsigned long sigignore; // %lu
|
47
|
+
unsigned long sigcatch; // %lu
|
48
|
+
unsigned long wchan; // %lu
|
49
|
+
unsigned long nswap; // %lu
|
50
|
+
unsigned long cnswap; // %lu
|
51
|
+
int exit_signal; // %d
|
52
|
+
int processor; // %d
|
53
|
+
unsigned long rt_priority; // %lu
|
54
|
+
unsigned long policy; // %lu
|
55
|
+
unsigned long long delayacct_blkio_ticks; // %llu
|
56
|
+
};
|
57
|
+
|
58
|
+
int rb_proc_ncpu();
|
59
|
+
int rb_proc_pid_vsize(int pid);
|
60
|
+
int rb_proc_pid_rss(int pid);
|
61
|
+
float rb_proc_pid_stime(int pid);
|
62
|
+
float rb_proc_pid_utime(int pid);
|
63
|
+
char * rb_proc_pid_cmdline(int pid);
|
64
|
+
char * rb_proc_pid_name(int pid);
|
data/ext/proceso/pid.c
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
#include "proceso.h"
|
2
|
+
|
3
|
+
static VALUE rb_cProcesoPID;
|
4
|
+
|
5
|
+
static VALUE
|
6
|
+
proceso__process_init(VALUE self, VALUE pid) {
|
7
|
+
rb_iv_set(self, "@pid", pid);
|
8
|
+
return self;
|
9
|
+
}
|
10
|
+
|
11
|
+
/* PID running? */
|
12
|
+
static VALUE
|
13
|
+
proceso__process_running(VALUE self) {
|
14
|
+
int pid = iv2pid(self);
|
15
|
+
rb_pid_t i = getpgid(pid);
|
16
|
+
if (i < 0) {
|
17
|
+
return Qfalse;
|
18
|
+
}
|
19
|
+
return Qtrue;
|
20
|
+
}
|
21
|
+
|
22
|
+
/* PID command line */
|
23
|
+
static VALUE
|
24
|
+
proceso__process_command(VALUE self) {
|
25
|
+
int pid = iv2pid(self);
|
26
|
+
char *process_cmd = rb_process_command(pid);
|
27
|
+
if (process_cmd == NULL)
|
28
|
+
return Qnil;
|
29
|
+
return rb_str_new2(process_cmd);
|
30
|
+
}
|
31
|
+
|
32
|
+
/* PID Resident Size (bytes) */
|
33
|
+
static VALUE
|
34
|
+
proceso__process_rss(VALUE self) {
|
35
|
+
int ret = rb_process_memory_size(iv2pid(self), PROCESS_RSS);
|
36
|
+
return INT2NUM(ret);
|
37
|
+
}
|
38
|
+
|
39
|
+
/* PID Virtual Size (bytes) */
|
40
|
+
static VALUE
|
41
|
+
proceso__process_vms(VALUE self) {
|
42
|
+
int ret = rb_process_memory_size(iv2pid(self), PROCESS_VMS);
|
43
|
+
return INT2NUM(ret);
|
44
|
+
}
|
45
|
+
|
46
|
+
/* PID User CPU */
|
47
|
+
static VALUE
|
48
|
+
proceso__process_user_cpu(VALUE self) {
|
49
|
+
float val = rb_process_cpu_times(iv2pid(self), FCPU_USR);
|
50
|
+
return rb_float_new(val);
|
51
|
+
}
|
52
|
+
|
53
|
+
/* PID System CPU */
|
54
|
+
static VALUE
|
55
|
+
proceso__process_system_cpu(VALUE self) {
|
56
|
+
float val = rb_process_cpu_times(iv2pid(self), FCPU_SYS);
|
57
|
+
return rb_float_new(val);
|
58
|
+
}
|
59
|
+
|
60
|
+
/* PID CPU Usage */
|
61
|
+
static VALUE
|
62
|
+
proceso__process_cpu_usage(VALUE self) {
|
63
|
+
int ncpu = rb_hw_ncpu();
|
64
|
+
float u1, u2;
|
65
|
+
float usage;
|
66
|
+
u1 = rb_process_cpu_times(iv2pid(self), FCPU_USR);
|
67
|
+
usleep(100000);
|
68
|
+
u2 = rb_process_cpu_times(iv2pid(self), FCPU_USR);
|
69
|
+
usage = ncpu * ((u2 - u1) * 100);
|
70
|
+
return rb_float_new(usage);
|
71
|
+
}
|
72
|
+
|
73
|
+
void Init__proceso_pid() {
|
74
|
+
|
75
|
+
VALUE rb_mProceso = rb_define_module("Proceso");
|
76
|
+
rb_cProcesoPID = rb_define_class_under(rb_mProceso, "PID", rb_cObject);
|
77
|
+
|
78
|
+
rb_define_method(rb_cProcesoPID, "initialize", proceso__process_init, 1);
|
79
|
+
rb_define_method(rb_cProcesoPID, "running?", proceso__process_running, 0);
|
80
|
+
rb_define_method(rb_cProcesoPID, "command", proceso__process_command, 0);
|
81
|
+
rb_define_method(rb_cProcesoPID, "resident_size", proceso__process_rss, 0);
|
82
|
+
rb_define_method(rb_cProcesoPID, "virtual_size", proceso__process_vms, 0);
|
83
|
+
rb_define_method(rb_cProcesoPID, "user_cpu_times", proceso__process_user_cpu, 0);
|
84
|
+
rb_define_method(rb_cProcesoPID, "system_cpu_times", proceso__process_system_cpu, 0);
|
85
|
+
rb_define_method(rb_cProcesoPID, "cpu_usage", proceso__process_cpu_usage, 0);
|
86
|
+
|
87
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#include "proceso.h"
|
2
|
+
|
3
|
+
static VALUE rb_mProceso;
|
4
|
+
|
5
|
+
int iv2pid(VALUE self) {
|
6
|
+
return FIX2INT(rb_iv_get(self, "@pid"));
|
7
|
+
}
|
8
|
+
|
9
|
+
#ifdef __APPLE__
|
10
|
+
/* Process PIDs */
|
11
|
+
static VALUE
|
12
|
+
proceso__pids(VALUE self) {
|
13
|
+
int *pids = rb_process_list();
|
14
|
+
VALUE processes = rb_ary_new();
|
15
|
+
int i;
|
16
|
+
for(i = 0; i < sizeof(pids); i++) {
|
17
|
+
rb_ary_push(processes, INT2NUM(pids[i]));
|
18
|
+
}
|
19
|
+
return processes;
|
20
|
+
}
|
21
|
+
#endif
|
22
|
+
|
23
|
+
void Init_proceso() {
|
24
|
+
|
25
|
+
rb_mProceso = rb_define_module("Proceso");
|
26
|
+
|
27
|
+
rb_define_const(rb_mProceso, "NCPU", INT2NUM(rb_hw_ncpu()));
|
28
|
+
|
29
|
+
#ifdef __APPLE__
|
30
|
+
rb_define_singleton_method(rb_mProceso, "pids", proceso__pids, 0);
|
31
|
+
#endif
|
32
|
+
|
33
|
+
Init__proceso_pid();
|
34
|
+
}
|
35
|
+
|
36
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#ifndef PROCESO_H
|
2
|
+
|
3
|
+
#define PROCSEO_H
|
4
|
+
|
5
|
+
#define PROCESS_RSS 0
|
6
|
+
#define PROCESS_VMS 1
|
7
|
+
#define FCPU_USR 0
|
8
|
+
#define FCPU_SYS 1
|
9
|
+
|
10
|
+
#include <ruby.h>
|
11
|
+
|
12
|
+
#if defined(__APPLE__)
|
13
|
+
# include "darwin.h"
|
14
|
+
#elif defined(__linux) || defined(__linux__) || defined(__LINUX__)
|
15
|
+
# include "linux.h"
|
16
|
+
#endif
|
17
|
+
|
18
|
+
#include "utility.h"
|
19
|
+
|
20
|
+
#endif // PROCESO_H
|
@@ -0,0 +1,88 @@
|
|
1
|
+
#include "proceso.h"
|
2
|
+
|
3
|
+
int rb_hw_ncpu() {
|
4
|
+
int ncpu = 0;
|
5
|
+
#if defined(__APPLE__)
|
6
|
+
int mib[2] = { CTL_HW, HW_NCPU };
|
7
|
+
int ret;
|
8
|
+
size_t len;
|
9
|
+
len = sizeof(ncpu);
|
10
|
+
ret = sysctl(mib, 2, &ncpu, &len, NULL, 0);
|
11
|
+
if (ret == -1) {
|
12
|
+
return 0;
|
13
|
+
}
|
14
|
+
#elif defined(__LINUX__)
|
15
|
+
ncpu = rb_proc_ncpu();
|
16
|
+
#endif
|
17
|
+
return ncpu;
|
18
|
+
}
|
19
|
+
|
20
|
+
float rb_process_cpu_times(int pid, int flag) {
|
21
|
+
int ret;
|
22
|
+
#if defined(__APPLE__)
|
23
|
+
struct proc_taskinfo pti;
|
24
|
+
ret = rb_process_info(pid, PROC_PIDTASKINFO, &pti, sizeof(pti));
|
25
|
+
if (ret == 0)
|
26
|
+
return 0.0;
|
27
|
+
if (flag == FCPU_SYS) { // total system
|
28
|
+
return (float)pti.pti_total_system / 1000000000.0;
|
29
|
+
} else {
|
30
|
+
return (float)pti.pti_total_user / 1000000000.0;
|
31
|
+
}
|
32
|
+
#elif defined(__LINUX__)
|
33
|
+
if (flag == FCPU_SYS) {
|
34
|
+
return rb_proc_pid_stime(pid);
|
35
|
+
} else {
|
36
|
+
return rb_proc_pid_utime(pid);
|
37
|
+
}
|
38
|
+
#endif
|
39
|
+
return 0.0;
|
40
|
+
}
|
41
|
+
|
42
|
+
char * rb_process_command(int pid) {
|
43
|
+
int ret;
|
44
|
+
char *process_name;
|
45
|
+
#if defined(__APPLE__)
|
46
|
+
int argmax;
|
47
|
+
argmax = rb_sysctl_kern_argmax();
|
48
|
+
if (argmax) {
|
49
|
+
ret = rb_sysctl_kern_procargs2(pid, &process_name, argmax, (size_t)argmax);
|
50
|
+
if (ret == 1)
|
51
|
+
return process_name;
|
52
|
+
}
|
53
|
+
#elif defined(__LINUX__)
|
54
|
+
process_name = rb_proc_pid_cmdline(pid);
|
55
|
+
return process_name;
|
56
|
+
#endif
|
57
|
+
return NULL;
|
58
|
+
}
|
59
|
+
|
60
|
+
int rb_process_memory_size(int pid, int flag) {
|
61
|
+
int result = 0;
|
62
|
+
#if defined(__APPLE__)
|
63
|
+
kern_return_t kr;
|
64
|
+
task_t task;
|
65
|
+
kr = task_for_pid(mach_task_self(), pid, &task);
|
66
|
+
if (kr == KERN_SUCCESS) {
|
67
|
+
task_basic_info_data_t basic_info;
|
68
|
+
mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
|
69
|
+
kr = task_info(task, TASK_BASIC_INFO, (task_info_t)&basic_info, &count);
|
70
|
+
if (kr == KERN_SUCCESS) {
|
71
|
+
if (count == TASK_BASIC_INFO_COUNT) {
|
72
|
+
if (flag == 1) {
|
73
|
+
result = (int)basic_info.virtual_size;
|
74
|
+
} else {
|
75
|
+
result = (int)basic_info.resident_size;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
#elif defined(__LINUX__)
|
81
|
+
if (flag == 1) {
|
82
|
+
result = rb_proc_pid_vsize(pid);
|
83
|
+
} else {
|
84
|
+
result = rb_proc_pid_rss(pid);
|
85
|
+
}
|
86
|
+
#endif
|
87
|
+
return result;
|
88
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'rack'
|
2
|
+
|
3
|
+
module Proceso
|
4
|
+
class Middleware
|
5
|
+
|
6
|
+
SUBSCRIPTION = 'proceso.usage'
|
7
|
+
|
8
|
+
def self.report
|
9
|
+
subscribe do |name, start, finish, id, payload|
|
10
|
+
puts
|
11
|
+
puts "******* PROCESO INFORMATION *******"
|
12
|
+
mem_used = (payload[:mem_used].to_f / 1024.0).round(1)
|
13
|
+
cpu_used = payload[:cpu_used].to_f.round(1)
|
14
|
+
path = payload[:request].path_info
|
15
|
+
resp_time = payload[:resp_time]
|
16
|
+
puts "MEM: #{mem_used}KB CPU: #{cpu_used} RESP: #{resp_time}ms PATH: #{path}"
|
17
|
+
puts "******* END OF PROCESO INFORMATION *******"
|
18
|
+
puts
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.subscribe(&blk)
|
23
|
+
return unless defined?(ActiveSupport::Notifications)
|
24
|
+
ActiveSupport::Notifications.subscribe(SUBSCRIPTION, &blk)
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :app, :pid, :notifier
|
28
|
+
|
29
|
+
def initialize(app)
|
30
|
+
@app = app
|
31
|
+
@notifier ||= ActiveSupport::Notifications if defined?(ActiveSupport::Notifications)
|
32
|
+
@pid = Process.pid
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(env)
|
36
|
+
measure_process_usage(env) do
|
37
|
+
@app.call(env)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def measure_process_usage(env)
|
42
|
+
mem_1 = process.mem_size
|
43
|
+
cpu_1 = process.user_cpu_times
|
44
|
+
resp_1 = Time.now.to_i
|
45
|
+
response = yield
|
46
|
+
mem_2 = process.mem_size
|
47
|
+
cpu_2 = process.user_cpu_times
|
48
|
+
resp_2 = Time.now.to_i
|
49
|
+
process_usage = process_info(env, (mem_2 - mem_1), (cpu_2 - cpu_1), (resp_2 - resp_1))
|
50
|
+
notifier.instrument(SUBSCRIPTION, process_usage)
|
51
|
+
response
|
52
|
+
end
|
53
|
+
|
54
|
+
def process_info(env, mem_used, cpu_used, resp_time)
|
55
|
+
req = Rack::Request.new(env)
|
56
|
+
{
|
57
|
+
pid: process.pid,
|
58
|
+
mem_used: mem_used,
|
59
|
+
cpu_used: cpu_used,
|
60
|
+
resp_time: resp_time,
|
61
|
+
request: req
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def process
|
66
|
+
@process ||= Proceso::PID.new(pid)
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
data/lib/proceso/pid.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Proceso
|
2
|
+
class PID
|
3
|
+
|
4
|
+
attr_accessor :pid
|
5
|
+
|
6
|
+
def path
|
7
|
+
File.dirname(command)
|
8
|
+
end
|
9
|
+
|
10
|
+
def executable
|
11
|
+
File.basename(command)
|
12
|
+
end
|
13
|
+
|
14
|
+
def mem_size(format = :bytes)
|
15
|
+
rss = resident_size
|
16
|
+
rss *= 1024 if RUBY_PLATFORM =~ /linux/
|
17
|
+
case format.to_s
|
18
|
+
when "bytes" then rss
|
19
|
+
when "kb", "kilobytes" then rss.to_f / 1024.0
|
20
|
+
when "mb", "megabytes" then rss.to_f / 1024.0 / 1024.0
|
21
|
+
when "gb", "gigabytes" then rss.to_f / 1024.0 / 1024.0 / 1024.0
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/lib/proceso/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Proceso
|
2
|
-
VERSION = "0.
|
3
|
-
end
|
2
|
+
VERSION = "0.1.1"
|
3
|
+
end
|
data/lib/proceso.rb
CHANGED
@@ -1 +1,29 @@
|
|
1
|
-
require 'proceso/proceso'
|
1
|
+
require 'proceso/proceso'
|
2
|
+
require 'proceso/pid'
|
3
|
+
|
4
|
+
module Proceso
|
5
|
+
extend self
|
6
|
+
|
7
|
+
if RUBY_PLATFORM =~ /linux/
|
8
|
+
def pids
|
9
|
+
Dir["/proc/*"].select do
|
10
|
+
|x| x =~ /\/\d+$/
|
11
|
+
end.map(&File.method(:basename)).map(&:to_i)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def processes
|
16
|
+
pids.map do |i|
|
17
|
+
Proceso::PID.new(i)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def current
|
22
|
+
@current ||= Proceso::PID.new(Process.pid)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
if defined?(Rails) || defined?(Rack)
|
28
|
+
require 'proceso/middleware'
|
29
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Proceso::PID do
|
4
|
+
|
5
|
+
let(:process) { Proceso::PID.new($$) }
|
6
|
+
|
7
|
+
it "should create new Process object with pid" do
|
8
|
+
expect { Proceso::PID.new($$) }.to_not raise_error
|
9
|
+
end
|
10
|
+
|
11
|
+
it "creates new Base object without argument will raise error" do
|
12
|
+
expect { Proceso::PID.new }.to raise_error
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be running" do
|
16
|
+
process.running?.should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should return process command" do
|
20
|
+
process.command.should =~ /ruby/
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return executable name" do
|
24
|
+
process.executable.should == "ruby"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return path name" do
|
28
|
+
process.path.should =~ /bin$/
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return resident size in bytes" do
|
32
|
+
process.resident_size.should be_kind_of(Numeric)
|
33
|
+
process.stub(:resident_size).and_return(100)
|
34
|
+
process.resident_size.should == 100
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return virtual size in bytes" do
|
38
|
+
process.virtual_size.should be_kind_of(Numeric)
|
39
|
+
process.stub(:virtual_size).and_return(100)
|
40
|
+
process.virtual_size.should == 100
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should return cpu usage" do
|
44
|
+
process.cpu_usage.should be_kind_of(Float)
|
45
|
+
process.stub(:cpu_usage).and_return(0.1)
|
46
|
+
process.cpu_usage.should == 0.1
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return user cpu times" do
|
50
|
+
process.user_cpu_times.should be_kind_of(Float)
|
51
|
+
process.stub(:user_cpu_times).and_return(0.1)
|
52
|
+
process.user_cpu_times.should == 0.1
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return system cpu times" do
|
56
|
+
process.system_cpu_times.should be_kind_of(Float)
|
57
|
+
process.stub(:system_cpu_times).and_return(0.1)
|
58
|
+
process.system_cpu_times.should == 0.1
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should return mem size" do
|
62
|
+
process.mem_size.should be_kind_of(Numeric)
|
63
|
+
rss = process.resident_size
|
64
|
+
process.stub(:resident_size).and_return(rss)
|
65
|
+
rss *= 1024 if RUBY_PLATFORM =~ /linux/
|
66
|
+
process.mem_size.should == rss
|
67
|
+
process.mem_size(:kb).should == (rss / 1024.0)
|
68
|
+
process.mem_size(:mb).should == (rss / 1024.0 / 1024.0)
|
69
|
+
process.mem_size(:gb).should == (rss / 1024.0 / 1024.0 / 1024.0)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/spec/proceso_spec.rb
CHANGED
@@ -2,42 +2,22 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Proceso do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
it "should create new Process object with pid" do
|
8
|
-
expect { Proceso::Info.new($$) }.to_not raise_error
|
9
|
-
end
|
10
|
-
|
11
|
-
it "creates new Base object without argument will raise error" do
|
12
|
-
expect { Proceso::Info.new }.to raise_error
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should be running" do
|
16
|
-
process.running?.should be_true
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should return process name" do
|
20
|
-
process.name.should =~ /ruby/
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should return resident size in bytes" do
|
24
|
-
process.resident_size.should be_kind_of(Numeric)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should return virtual size in bytes" do
|
28
|
-
process.virtual_size.should be_kind_of(Numeric)
|
5
|
+
it "should return cpu core" do
|
6
|
+
Proceso::NCPU.should_not == 0
|
29
7
|
end
|
30
8
|
|
31
|
-
it "should return
|
32
|
-
|
9
|
+
it "should return list of pids" do
|
10
|
+
Proceso.pids.should be_kind_of(Array)
|
33
11
|
end
|
34
12
|
|
35
|
-
it "should return
|
36
|
-
|
13
|
+
it "should return list of Proceso::PID objects" do
|
14
|
+
Proceso.processes.should be_kind_of(Array)
|
15
|
+
Proceso.processes.last.should be_kind_of(Proceso::PID)
|
37
16
|
end
|
38
17
|
|
39
|
-
it "should return
|
40
|
-
|
18
|
+
it "should return current process" do
|
19
|
+
Proceso.current.should_not be_nil
|
20
|
+
Proceso.current.pid.should == Process.pid
|
41
21
|
end
|
42
22
|
|
43
23
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: proceso
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan Goines
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rake
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,11 +88,23 @@ extensions:
|
|
74
88
|
- ext/proceso/extconf.rb
|
75
89
|
extra_rdoc_files: []
|
76
90
|
files:
|
91
|
+
- lib/proceso/middleware.rb
|
92
|
+
- lib/proceso/pid.rb
|
77
93
|
- lib/proceso/version.rb
|
78
94
|
- lib/proceso.rb
|
95
|
+
- ext/proceso/extconf.rb
|
96
|
+
- ext/proceso/darwin.c
|
97
|
+
- ext/proceso/linux.c
|
98
|
+
- ext/proceso/pid.c
|
99
|
+
- ext/proceso/proceso.c
|
100
|
+
- ext/proceso/utility.c
|
101
|
+
- ext/proceso/darwin.h
|
102
|
+
- ext/proceso/linux.h
|
103
|
+
- ext/proceso/proceso.h
|
104
|
+
- ext/proceso/utility.h
|
105
|
+
- spec/proceso/pid_spec.rb
|
79
106
|
- spec/proceso_spec.rb
|
80
107
|
- spec/spec_helper.rb
|
81
|
-
- ext/proceso/extconf.rb
|
82
108
|
homepage: https://github.com/bry4n/proceso
|
83
109
|
licenses:
|
84
110
|
- MIT
|
@@ -105,5 +131,6 @@ signing_key:
|
|
105
131
|
specification_version: 4
|
106
132
|
summary: Simple process information gather
|
107
133
|
test_files:
|
134
|
+
- spec/proceso/pid_spec.rb
|
108
135
|
- spec/proceso_spec.rb
|
109
136
|
- spec/spec_helper.rb
|