Projet

Général

Profil

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

root / plugins / system / multicpu1sec / multicpu1sec-c.c @ 339bfec6

Historique | Voir | Annoter | Télécharger (3,05 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
        printf("acquire()\n");
85 9ac74f8d Steve Schnepp
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 339bfec6 Steve Schnepp
                /* lock */
105
                flock(fileno(cache_file), LOCK_EX);
106 9ac74f8d Steve Schnepp
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 81e9ffca Steve Schnepp
}
129
130
int fetch() {
131
        printf("fetch()\n");
132 6dec8c33 Steve Schnepp
        FILE* cache_file = fopen(cache_filename, "r+");
133 9ac74f8d Steve Schnepp
134 339bfec6 Steve Schnepp
        /* lock */
135
        flock(fileno(cache_file), LOCK_EX);
136
137 c86e4ab2 Steve Schnepp
        /* cat the cache_file to stdout */
138
        char buffer[1024];
139
        while (fgets(buffer, 1024, cache_file)) {
140
                printf("%s", buffer);
141
        }
142
143
        ftruncate(fileno(cache_file), 0);
144
        fclose(cache_file);
145 81e9ffca Steve Schnepp
}
146
147
int main(int argc, char **argv) {
148
        if (argc > 1) {
149
                char* first_arg = argv[1];
150
                if (! strcmp(first_arg, "config")) {
151
                        return config();
152
                }
153
154
                if (! strcmp(first_arg, "acquire")) {
155
                        return acquire();
156
                }
157
        }
158
159
        return fetch();
160
}