Projet

Général

Profil

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

root / plugins / system / multicpu1sec / multicpu1sec-c.c @ 4a9b0e47

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

1 81e9ffca Steve Schnepp
/*
2
 * multicpu1sec C plugin
3
 */
4
#include <stdio.h>
5
#include <string.h>
6 9ac74f8d Steve Schnepp
#include <unistd.h>
7
8
#include <time.h>
9 81e9ffca Steve Schnepp
10 339bfec6 Steve Schnepp
#include <sys/file.h>
11
12 81e9ffca Steve Schnepp
#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 9ac74f8d Steve Schnepp
                "graph_vlabel average cpu use %%\n"
44 81e9ffca Steve Schnepp
                "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.min 0\n", i);
55
        }
56
57
58 9ac74f8d Steve Schnepp
        return 0;
59
}
60
61
char* pid_filename = "./multicpu1sec.pid";
62
char* cache_filename = "./multicpu1sec.value";
63
64
/* Wait until the next second, and return the EPOCH */
65
time_t wait_until_next_second() {
66
        struct timespec tp;
67
        clock_gettime(CLOCK_REALTIME, &tp);
68
69
        time_t current_epoch = tp.tv_sec;
70
        long nsec_to_sleep = 1000*1000*1000 - tp.tv_nsec;
71
72
73
        /* Only sleep if needed */
74
        if (nsec_to_sleep > 0) {
75
                tp.tv_sec = 0;
76
                tp.tv_nsec = nsec_to_sleep;
77
                nanosleep(&tp, NULL);
78
        }
79
80
        return current_epoch + 1;
81 81e9ffca Steve Schnepp
}
82
83
int acquire() {
84 9ac74f8d Steve Schnepp
85
        /* write the pid */
86
        FILE* pid_file = fopen(pid_filename, "w");
87
        fprintf(pid_file, "%d\n", getpid());
88
        fclose(pid_file);
89
90
        /* loop each second */
91
        while (1) {
92
                /* wait until next second */
93
                time_t epoch = wait_until_next_second();
94
95
                /* Reading /proc/stat */
96
                FILE* f = fopen(PROC_STAT, "r");
97
                // Read and ignore the 1rst line
98
                char buffer[1024];
99
                fgets(buffer, 1024, f);
100
101
                /* open the spoolfile */
102
                FILE* cache_file = fopen(cache_filename, "a");
103 339bfec6 Steve Schnepp
                /* lock */
104
                flock(fileno(cache_file), LOCK_EX);
105 9ac74f8d Steve Schnepp
106
                while (! feof(f)) {
107
                        if (fgets(buffer, 1024, f) == 0) {
108
                                // EOF
109
                                break;
110
                        }
111
112
                        // Not on CPU lines anymore
113
                        if (strncmp(buffer, "cpu", 3)) break;
114
115
                        char cpu_id[64];
116
                        long usr, nice, sys, idle, iowait, irq, softirq;
117
                        sscanf(buffer, "%s %ld %ld %ld %ld %ld", cpu_id, &usr, &nice, &sys, &idle, &iowait, &irq, &softirq);
118
119
                        long used = usr + nice + sys + idle + iowait + irq + softirq;
120
121
                        fprintf(cache_file, "%s.value %ld:%ld\n", cpu_id, epoch, used);
122
                }
123
124
                fclose(cache_file);
125
                fclose(f);
126
        }
127 81e9ffca Steve Schnepp
}
128
129
int fetch() {
130 6dec8c33 Steve Schnepp
        FILE* cache_file = fopen(cache_filename, "r+");
131 9ac74f8d Steve Schnepp
132 339bfec6 Steve Schnepp
        /* lock */
133
        flock(fileno(cache_file), LOCK_EX);
134
135 c86e4ab2 Steve Schnepp
        /* cat the cache_file to stdout */
136
        char buffer[1024];
137
        while (fgets(buffer, 1024, cache_file)) {
138
                printf("%s", buffer);
139
        }
140
141
        ftruncate(fileno(cache_file), 0);
142
        fclose(cache_file);
143 81e9ffca Steve Schnepp
}
144
145
int main(int argc, char **argv) {
146
        if (argc > 1) {
147
                char* first_arg = argv[1];
148
                if (! strcmp(first_arg, "config")) {
149
                        return config();
150
                }
151
152
                if (! strcmp(first_arg, "acquire")) {
153
                        return acquire();
154
                }
155
        }
156
157
        return fetch();
158
}