-
Notifications
You must be signed in to change notification settings - Fork 1
/
systwit.c
170 lines (138 loc) · 4.94 KB
/
systwit.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
* A daemon that reads the /proc/stats file, calculates the cpu usage
* percentage and writes it to syslog.
*
* Copyright (C) 2015-2016 Sebastian Glinski <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <sys/types.h>
#define STAT_FILE "/proc/stat"
#define READ_SIZE 200
#define SLEEP_CYCLE 5
typedef struct {
u_int32_t user; /* Time spent in user mode */
u_int32_t nice; /* Time spent in user mode with low priority (nice) */
u_int32_t systm; /* Time spent in system mode */
u_int32_t idle; /* Time spent in the idle task */
u_int32_t iowait; /* Time waiting for I/O to complete */
u_int32_t irq; /* Time servicing interrupts */
u_int32_t softirq; /* Time servicing softirqs */
u_int32_t steal; /* Stolen time, which is the time spent in other operating systems when running in a virtualized environment */
u_int32_t guest; /* Time spent running a virtual CPU for guest operating systems under the control of the Linux kernel */
u_int32_t guest_nice; /* Time spent running a niced guest */
} cpu_stats;
cpu_stats cur_stat, pre_stat;
void read_stats_file(void);
cpu_stats read_cpu_stats(char[]);
float calculate_percentage(void);
int main(int argc, char const *argv[]) {
pid_t pid, sid;
/* Fork off the parent process */
if((pid = fork()) < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good pid then we
* can exit the parent process
*/
if(pid > 0) {
exit(EXIT_SUCCESS);
}
/* Change the file mode mask to 0
* so we will have full access to the
* files generated by the daemon.
*/
umask(0);
/* Connect to the syslog daemon */
openlog(argv[0], LOG_NOWAIT|LOG_PID, LOG_USER);
syslog(LOG_NOTICE, "Successfully started daemon");
/* Create a new session id for the
* child process
*/
sid = setsid();
if(sid < 0) {
syslog(LOG_ERR, "Could not create process group\n");
exit(EXIT_FAILURE);
}
/* Change the working directory
* where the daemon operates in
*/
if((chdir("/")) < 0) {
syslog(LOG_ERR, "Could not change working directory to /\n");
exit(EXIT_FAILURE);
}
/* Close the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
/* The main loop where the daemon runs in */
while(1) {
read_stats_file();
syslog(LOG_INFO, "CPU Percentage: %f", calculate_percentage());
sleep(5);
}
close_syslog();
return 0;
}
void read_stats_file(void) {
FILE *file;
file = fopen(STAT_FILE, "r");
char puffer[READ_SIZE];
int t_idle = 0, t_iowait = 0;
/* Read the first line of the stat file */
fgets(puffer, READ_SIZE, file);
/* Keep the statistics from the last run
* in pre_stat
*/
pre_stat = cur_stat;
cur_stat = read_cpu_stats(puffer);
/*
syslog(LOG_INFO, "%u - %u - %u - %u - %u - %u - %u - %u - %u - %u", pre_stat.user, pre_stat.nice, pre_stat.systm, pre_stat.idle, pre_stat.iowait, pre_stat.irq, pre_stat.softirq, pre_stat.steal, pre_stat.guest, pre_stat.guest_nice);
syslog(LOG_INFO, "%u - %u - %u - %u - %u - %u - %u - %u - %u - %u", cur_stat.user, cur_stat.nice, cur_stat.systm, cur_stat.idle, cur_stat.iowait, cur_stat.irq, cur_stat.softirq, cur_stat.steal, cur_stat.guest, cur_stat.guest_nice);
*/
fclose(file);
}
cpu_stats read_cpu_stats(char c[]) {
cpu_stats s;
char *tokens[15];
char *t;
int i = 0;
/* Skip the first token which is the string 'cpu' */
strtok(c, " ");
/* Read the tokens from the first cpu-line and parse
* them into the structure
*/
t = strtok(NULL, " ");
while(t != NULL) {
sscanf(t, "%u", &((u_int32_t*)&s)[i]);
t = strtok(NULL, " ");
i++;
}
return s;
}
float calculate_percentage(void) {
u_int32_t prevIdle = pre_stat.idle + pre_stat.iowait;
u_int32_t idle = cur_stat.idle + cur_stat.iowait;
u_int32_t prevNonIdle = pre_stat.user + pre_stat.nice + pre_stat.systm + pre_stat.irq + pre_stat.softirq + pre_stat.steal;
u_int32_t nonIdle = cur_stat.user + cur_stat.nice + cur_stat.systm + cur_stat.irq + cur_stat.softirq + cur_stat.steal;
u_int32_t totald = (idle + nonIdle) - (prevIdle + prevNonIdle);
u_int32_t idled = idle - prevIdle;
/* float CPU_Percentage = (totald - idled)/(float)totald; */
return (totald - idled) / (float)totald;
}