Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / system / multicpu1sec / multicpu1sec-c.c @ b0e8dcea

Historique | Voir | Annoter | Télécharger (3,04 ko)

1
/*
2
 * multicpu1sec C plugin
3
 */
4
#include <stdio.h>
5
#include <string.h>
6
#include <unistd.h>
7

    
8
#include <time.h>
9

    
10
#include <sys/file.h>
11

    
12
#define PROC_STAT "/proc/stat"
13

    
14
int fail(char* msg) {
15
        perror(msg);
16

    
17
        return 1;
18
}
19

    
20
int config() {
21
        /* Get the number of CPU */
22
        FILE* f;
23
        if ( !(f=fopen(PROC_STAT, "r")) ) {
24
                return fail("cannot open " PROC_STAT);
25
        }
26

    
27
        // Starting with -1, since the first line is the "global cpu line"
28
        int ncpu = -1;
29
        while (! feof(f)) {
30
                char buffer[1024];
31
                if (fgets(buffer, 1024, f) == 0) {
32
                        break;
33
                }
34

    
35
                if (! strncmp(buffer, "cpu", 3)) ncpu ++;
36
        }
37

    
38
        fclose(f);
39

    
40
        printf(
41
                "graph_title multicpu1sec\n"
42
                "graph_category system::1sec\n"
43
                "graph_vlabel average cpu use %%\n"
44
                "graph_scale no\n"
45
                "graph_total All CPUs\n"
46
                "update_rate 1\n"
47
                "graph_data_size custom 1d, 10s for 1w, 1m for 1t, 5m for 1y\n"
48
        );
49

    
50
        int i;
51
        for (i = 0; i < ncpu; i++) {
52
                printf("cpu%d.label CPU %d\n", i, i);
53
                printf("cpu%d.draw %s\n", i, "AREASTACK");
54
                printf("cpu%d.type %s\n", i, "DERIVE");
55
                printf("cpu%d.min 0\n", i);
56
        }
57

    
58

    
59
        return 0;
60
}
61

    
62
char* pid_filename = "./multicpu1sec.pid";
63
char* cache_filename = "./multicpu1sec.value";
64

    
65
/* Wait until the next second, and return the EPOCH */
66
time_t wait_until_next_second() {
67
        struct timespec tp;
68
        clock_gettime(CLOCK_REALTIME, &tp);
69

    
70
        time_t current_epoch = tp.tv_sec;
71
        long nsec_to_sleep = 1000*1000*1000 - tp.tv_nsec;
72

    
73

    
74
        /* Only sleep if needed */
75
        if (nsec_to_sleep > 0) {
76
                tp.tv_sec = 0;
77
                tp.tv_nsec = nsec_to_sleep;
78
                nanosleep(&tp, NULL);
79
        }
80

    
81
        return current_epoch + 1;
82
}
83

    
84
int acquire() {
85

    
86
        /* write the pid */
87
        FILE* pid_file = fopen(pid_filename, "w");
88
        fprintf(pid_file, "%d\n", getpid());
89
        fclose(pid_file);
90

    
91
        /* loop each second */
92
        while (1) {
93
                /* wait until next second */
94
                time_t epoch = wait_until_next_second();
95

    
96
                /* Reading /proc/stat */
97
                FILE* f = fopen(PROC_STAT, "r");
98
                // Read and ignore the 1rst line
99
                char buffer[1024];
100
                fgets(buffer, 1024, f);
101

    
102
                /* open the spoolfile */
103
                FILE* cache_file = fopen(cache_filename, "a");
104
                /* lock */
105
                flock(fileno(cache_file), LOCK_EX);
106

    
107
                while (! feof(f)) {
108
                        if (fgets(buffer, 1024, f) == 0) {
109
                                // EOF
110
                                break;
111
                        }
112

    
113
                        // Not on CPU lines anymore
114
                        if (strncmp(buffer, "cpu", 3)) break;
115

    
116
                        char cpu_id[64];
117
                        long usr, nice, sys, idle, iowait, irq, softirq;
118
                        sscanf(buffer, "%s %ld %ld %ld %ld %ld", cpu_id, &usr, &nice, &sys, &idle, &iowait, &irq, &softirq);
119

    
120
                        long used = usr + nice + sys + idle + iowait + irq + softirq;
121

    
122
                        fprintf(cache_file, "%s.value %ld:%ld\n", cpu_id, epoch, used);
123
                }
124

    
125
                fclose(cache_file);
126
                fclose(f);
127
        }
128
}
129

    
130
int fetch() {
131
        FILE* cache_file = fopen(cache_filename, "r+");
132

    
133
        /* lock */
134
        flock(fileno(cache_file), LOCK_EX);
135

    
136
        /* cat the cache_file to stdout */
137
        char buffer[1024];
138
        while (fgets(buffer, 1024, cache_file)) {
139
                printf("%s", buffer);
140
        }
141

    
142
        ftruncate(fileno(cache_file), 0);
143
        fclose(cache_file);
144
}
145

    
146
int main(int argc, char **argv) {
147
        if (argc > 1) {
148
                char* first_arg = argv[1];
149
                if (! strcmp(first_arg, "config")) {
150
                        return config();
151
                }
152

    
153
                if (! strcmp(first_arg, "acquire")) {
154
                        return acquire();
155
                }
156
        }
157

    
158
        return fetch();
159
}