proceso 0.0.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|