Diff
checker
텍스트
텍스트
이미지
문서
Excel
폴더
Legal
Enterprise
데스크톱
요금제
로그인
데스크톱 앱 다운로드
텍스트 비교
두 텍스트 파일의 차이점을 찾아보세요
도구
기록
실시간 편집
변경 없는 행 숨기기
줄바꿈 비활성화
레이아웃
나란히 보기
합쳐 보기
비교 단위
스마트
단어
글자
구문 강조
언어 선택
제외
텍스트 변환
첫 변경으로
수정
Diffchecker Desktop
가장 안전하게 Diffchecker를 사용하는 방법. 데스크톱 앱을 사용하면 비교 데이터가 외부로 전송되지 않습니다!
데스크톱 앱 받기
Untitled diff
생성일
11년 전
비교 결과 만료 없음
초기화
내보내기
공유
설명
230 삭제
행
총
삭제
글자
총
삭제
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
255 행
복사
280 추가
행
총
추가
글자
총
추가
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
321 행
복사
복사
복사됨
복사
복사됨
/*
/*
opyright (C) 2010 Ciriaco Garcia de Celis
* C
opyright (C) 2010 Ciriaco Garcia de Celis
*
*
* This program is free software: you can redistribute it and/or
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* the License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License (GPL) for more details.
* GNU General Public License (GPL) for more details.
*
*
* You should have received a copy of the GNU GPL along with this
* You should have received a copy of the GNU GPL along with this
* program. If not, see <http://www.gnu.org/licenses/>.
* program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
// compile with "g++ -O3 -lrt netmon.cpp -o netmon"
// compile with "g++ -O3 -lrt netmon.cpp -o netmon"
#include <sys/stat.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <cstdio>
#include <cstdio>
#include <cstring>
#include <cstring>
#include <cstdlib>
#include <cstdlib>
#include <ctime>
#include <ctime>
#include <climits>
#include <climits>
복사
복사됨
복사
복사됨
#include <cctype>
#define STATE_FILE_BASE "/dev/shm/netmon"
#define STATE_FILE_BASE "/dev/shm/netmon"
복사
복사됨
복사
복사됨
int exitapp(int exitcode)
{
int exitapp(int exitcode)
{
char errmsg[64];
char errmsg[64];
sprintf(errmsg, "ERROR code %d", exitcode);
sprintf(errmsg, "ERROR code %d", exitcode);
write(1, errmsg, strlen(errmsg));
write(1, errmsg, strlen(errmsg));
return exitcode;
exit(exitcode);
return exitcode;
}
}
복사
복사됨
복사
복사됨
int main(int argc, char** argv)
const int BLOCK_SIZE = 512;
{
if (argc < 2)
struct disk_stat {
{
long long read, write;
printf("usage: %s <network_interface> [CPU]\n", argv[0]);
double r_rate, w_rate;
return
1
;
char name[16];
};
const int MAX_STAT = 32;
class disk_stats {
disk_stat stat[MAX_STAT];
int total;
public:
disk_stats() : total(0) {}
const char* parse(const char* line, double seconds) {
if(total>=MAX_STAT) exitapp(11);
static char cad[256], buffer[256];
long long dummy;
disk_stat &ds = stat[total];
sscanf(line,"%lld %lld %s %lld %lld %lld %lld %lld %lld %lld",
&dummy,&dummy,ds.name,&dummy,&dummy,&ds.read,&dummy,&dummy,&dummy,&ds.write);
int len = strlen(ds.name);
if(!dummy) return 0;
if(isdigit(ds.name[len-1])) return 0;
long long prev_read = 0, prev_write = 0;
sprintf(cad,"%s.%s.%d",STATE_FILE_BASE,ds.name,getuid());
int fd = open(cad, O_RDWR | O_CREAT, 0664);
if (fd < 0) exitapp(9);
int bytes = read(fd, buffer, sizeof(buffer)-1);
if (bytes < 0) exitapp(10);
buffer[bytes] = 0;
sscanf(buffer,"%lld %lld",&prev_read,&prev_write);
lseek(fd, 0, SEEK_SET);
sprintf(buffer,"%lld %lld",ds.read,ds.write);
write(fd, buffer, 64);
close(fd);
ds.r_rate = (ds.read-prev_read)/seconds*BLOCK_SIZE/1024/1024;
ds.w_rate = (ds.write-prev_write)/seconds*BLOCK_SIZE/1024/1024;
if(ds.r_rate>0) {
if(ds.w_rate>0) sprintf(buffer," | %s: %3.0lf %3.0lf",ds.name,ds.r_rate,ds.w_rate);
else sprintf(buffer," | %s: %3.0lf .",ds.name,ds.r_rate);
} else {
if(ds.w_rate>0) sprintf(buffer," | %s: . %3.0lf",ds.name,ds.w_rate);
else sprintf(buffer," | %s: . .",ds.name);
}
++total;
return
buffer
;
}
}
복사
복사됨
복사
복사됨
};
복사
복사됨
복사
복사됨
bool reportCPU = (argc > 2) && (strcmp(argv[2], "CPU") == 0);
복사
복사됨
복사
복사됨
char
buffer[4096], cad[256], *ni, *nf;
int main(int argc,
char
** argv) {
if (argc < 2) {
// read
network
information
printf("usage: %s <
network
_interface>\n", argv[0]);
int fd = open("/proc/net/dev", O_RDONLY);
return
1
;
if (fd < 0) return exitapp(2);
}
int bytes = read(fd, buffer, sizeof(buffer)-1);
close(fd);
if (bytes < 0)
return
exitapp(3)
;
buffer[bytes] = 0;
복사
복사됨
복사
복사됨
timespec tp;
char buffer[4096], cad[256], *ni, *nf;
clock_gettime(CLOCK_MONOTONIC, &tp);
long long nanoseconds = tp.tv_sec * 1000000000LL + tp.tv_nsec;
복사
복사됨
복사
복사됨
long long recv_bytes=LLONG_MAX, sent_
bytes
=LLONG_MAX
;
// read network information
bool networkAvailable
=
false
;
int fd = open("/proc/net/dev", O_RDONLY);
if (fd < 0) return exitapp(2);
int bytes = read(fd, buffer, sizeof(buffer)-1);
close(fd);
if (
bytes
< 0) return exitapp(3)
;
buffer[bytes]
=
0
;
복사
복사됨
복사
복사됨
// search for the proper network interface
timespec tp
;
strcpy(cad, argv[1])
;
clock_gettime(CLOCK_MONOTONIC, &tp
);
strcat(cad, ":"
);
long long nanoseconds = tp.tv_sec * 1000000000LL + tp.tv_nsec;
char *pif = strstr(buffer, cad);
if (pif != NULL)
{
networkAvailable = true;
복사
복사됨
복사
복사됨
// jump to the received bytes field
long long recv_bytes=LLONG_MAX, sent_bytes=LLONG_MAX;
ni = pif + strlen(cad);
bool networkAvailable = false;
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++ = 0;
복사
복사됨
복사
복사됨
//
get the received bytes
//
search for the proper network interface
recv_bytes
=
atoll(ni)
;
strcpy(cad, argv[1]);
strcat(cad, ":");
char *pif = strstr(buffer, cad);
if (pif) {
networkAvailable
=
true
;
복사
복사됨
복사
복사됨
// jump to the
sent
bytes field
// jump to the
received
bytes field
for (int skip = 0; skip < 8; skip++)
ni =
pif + strlen(cad)
;
{
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
ni =
nf
;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
*nf++ = 0;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
if (!*nf) break;
*nf++ = 0;
}
복사
복사됨
복사
복사됨
// get the
sent
bytes
// get the
received
bytes
sent
_bytes = atoll(ni);
recv
_bytes = atoll(ni);
// jump to the sent bytes field
for (int skip = 0; skip < 8; skip++) {
ni = nf;
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
if (!*nf) break;
*nf++ = 0;
}
}
복사
복사됨
복사
복사됨
long long user_mode_time=0, user_mode_nice_time=0, system_mode_time=0, idle_time=0;
// get the sent bytes
sent_bytes = atoll(ni);
}
복사
복사됨
복사
복사됨
if (reportCPU)
long long user_mode_time=0, user_mode_nice_time=0, system_mode_time=0, idle_time=0;
{
// read CPU information
fd = open("/proc/stat", O_RDONLY);
if (fd < 0) return exitapp(4);
bytes = read(fd, buffer, sizeof(buffer)-1);
close(fd);
if (bytes < 0) return exitapp(5);
buffer[bytes] = 0;
복사
복사됨
복사
복사됨
pif
=
strstr(buffer, "cpu "
);
// read CPU information
if (
pif != NULL)
fd
=
open("/proc/stat", O_RDONLY
);
{
if (
fd < 0) return exitapp(4);
ni
=
pif + 3
;
bytes
=
read(fd, buffer, sizeof(buffer)-1)
;
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++
;
close(fd)
;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++
);
if (bytes < 0) return exitapp(5
);
*nf++
= 0;
buffer[bytes]
= 0;
복사
복사됨
복사
복사됨
// get the user mode time
pif = strstr(buffer, "cpu ");
user_mode_time
=
atoll(ni)
;
if (pif) {
ni = pif + 3;
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++
=
0
;
복사
복사됨
복사
복사됨
ni = nf;
// get the user mode time
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
user_mode_time
=
atoll(ni
);
for (nf
=
ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++
);
*nf++ = 0;
복사
복사됨
복사
복사됨
// get the user mode nice time
ni = nf;
user_mode_nice_time
=
atoll(ni)
;
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++
=
0
;
복사
복사됨
복사
복사됨
ni
= nf;
// get the user mode
ni
ce time
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
user_mode_nice_time = atoll(ni);
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++ = 0;
복사
복사됨
복사
복사됨
// get the system mode time
ni = nf;
system_mode_time
=
atoll(ni)
;
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++
=
0
;
복사
복사됨
복사
복사됨
ni = nf;
// get the system mode time
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
system_mode_time
=
atoll(ni
);
for (nf
=
ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++
);
*nf++ = 0;
복사
복사됨
복사
복사됨
// get the idle time
ni = nf;
idle_time = atoll(ni
);
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
}
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++
);
}
*nf++ = 0;
복사
복사됨
복사
복사됨
//
read the received/sent bytes, date and CPU usage stored by a previous execution
//
get the
idle
time
sprintf(cad, "%s.%s.%d", STATE_FILE_BASE, argv[1], getuid());
idle_time = atoll(
ni
);
fd = open(cad, O_RDWR | O_CREAT, 0664);
}
if (fd < 0) return exitapp(6);
bytes = read(fd, buffer, sizeof(buffer)-1);
if (bytes < 0)
{
close(fd);
return exitapp(7);
}
long long prev_recv_bytes, prev_sent_bytes, prev_nanoseconds = -1;
long long prev_user_mode_time, prev_user_mode_nice_time, prev_system_mode_time, prev_
idle
_
time
= -1;
if (bytes > 0)
{
prev_recv_bytes = atoll(buffer);
prev_sent_bytes = atoll(buffer+20);
prev_nanoseconds = atoll(buffer+40);
prev_user_mode_time = atoll(buffer+60);
prev_user_mode_nice_time = atoll(buffer+80);
prev_system_mode_time = atoll(buffer+100);
prev_
idle_time = atoll(
buffer+120
);
}
복사
복사됨
복사
복사됨
//
store in
the
file the current values for l
ate
r use
//
read
the
received/sent bytes, d
ate
and CPU usage stored by a previous execution
sprintf(
buffer
, "%
019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n
",
sprintf(
cad
, "%
s.%s.%d
",
STATE_FILE_BASE, argv[1], getuid());
recv_bytes, sent_bytes, nanoseconds,
fd = open(cad, O_RDWR | O_CREAT, 0664);
user_mode_time, user_mode_nice_time, system_mode_time, idle_time);
if
(fd
< 0) return exitapp(6
);
lseek
(fd
, 0, SEEK_SET
);
bytes = read
(fd, buffer,
sizeof(buffer)-1
);
write
(fd, buffer,
140
);
if (bytes < 0) {
close(fd);
close(fd);
복사
복사됨
복사
복사됨
return exitapp(7);
}
long long prev_recv_bytes = 0, prev_sent_bytes = 0, prev_nanoseconds = -1;
long long prev_user_mode_time = 0, prev_user_mode_nice_time = 0, prev_system_mode_time = 0, prev_idle_time = -1;
if (bytes > 0) {
prev_recv_bytes = atoll(buffer);
prev_sent_bytes = atoll(buffer+20);
prev_nanoseconds = atoll(buffer+40);
prev_user_mode_time = atoll(buffer+60);
prev_user_mode_nice_time = atoll(buffer+80);
prev_system_mode_time = atoll(buffer+100);
prev_idle_time = atoll(buffer+120);
}
복사
복사됨
복사
복사됨
//
generate the result
//
store in the file the current values for later use
sprintf(buffer, "%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n",
recv_bytes, sent_bytes, nanoseconds,
user_mode_time, user_mode_nice_time, system_mode_time, idle_time);
lseek(fd, 0, SEEK_SET);
write(fd, buffer, 140);
close(fd);
복사
복사됨
복사
복사됨
strcpy(buffer, "<txt>");
// generate the result
복사
복사됨
복사
복사됨
bool hasNet = networkAvailable && (prev_nanoseconds >= 0) && (recv_bytes >= prev_recv_bytes) && (sent_bytes >= prev_sent_bytes);
strcpy(buffer, "<txt>");
long long elapsed = nanoseconds - prev_nanoseconds;
if (elapsed < 1) elapsed = 1;
double seconds = elapsed / 1000000000.0;
복사
복사됨
복사
복사됨
if (!networkAvailable)
// NETWORK
{
bool hasNet = networkAvailable && (prev_nanoseconds >= 0) && (recv_bytes >= prev_recv_bytes) && (sent_bytes >= prev_sent_bytes);
sprintf(cad, " %s is down", argv[1]);
strcat(buffer, cad);
}
else if (!hasNet)
{
strcat(buffer, " ? kbps IN \n ? kbps OUT");
}
else
{
long long elapsed = nanoseconds - prev_nanoseconds;
if (elapsed < 1) elapsed = 1;
double seconds = elapsed / 1000000000.0;
long long sent = sent_bytes - prev_sent_bytes;
long long received = recv_bytes - prev_recv_bytes;
long inbps = (long) (8 * received / seconds + 999); // adding 999 ensures "1" for any rate above 0
long outbps = (long) (8 * sent / seconds + 999);
if (inbps < 1000000)
sprintf(cad, "%6d kbps IN \n", inbps/1000);
else
sprintf(cad, "%6.3f Mbps IN \n", inbps/1000000.0);
strcat(buffer, cad);
복사
복사됨
복사
복사됨
if (outbps < 1000000)
if (!networkAvailable) {
sprintf(cad, "%6d kbps OUT", outbps/1000);
sprintf(cad, " %s is down", argv[1]);
else
strcat(buffer, cad);
sprintf(cad, "%6.3f Mbps OUT", outbps/1000000.0);
} else if (!hasNet) {
strcat(buffer, cad);
strcat(buffer, "D: - U: -
");
} else {
}
long long sent = sent_bytes - prev_sent_bytes;
long long received = recv_bytes - prev_recv_bytes;
long inbps = (long) (8 * received / seconds + 999) / 8 / 1024; // adding 999 ensures "1" for any rate above 0
long outbps = (long) (8 * sent / seconds + 999) / 8 / 1024;
복사
복사됨
복사
복사됨
long long cpu_used = user_mode_time + user_mode_nice_time + system_mode_time
if (inbps < 1024) sprintf(cad, "D: %5ld KB/s ", inbps);
else sprintf(cad, "D: %5.0lf MB/s ", inbps/1024.0);
strcat(buffer, cad);
if (outbps < 1024) sprintf(cad, " | U: %5ld KB/s ", outbps);
else sprintf(cad, " | U: %5.0lf MB/s ", outbps/1024.0);
strcat(buffer, cad);
}
long long cpu_used = user_mode_time + user_mode_nice_time + system_mode_time
- (prev_user_mode_time + prev_user_mode_nice_time + prev_system_mode_time);
- (prev_user_mode_time + prev_user_mode_nice_time + prev_system_mode_time);
복사
복사됨
복사
복사됨
long long total_cpu = cpu_used + (idle_time - prev_idle_time);
long long total_cpu = cpu_used + (idle_time - prev_idle_time);
bool hasCPU = (prev_idle_time >= 0) && (total_cpu > 0);
int total_ram = 0, ram_used = 0;
if (reportCPU)
bool hasCPU = (prev_idle_time >= 0) && (total_cpu > 0);
{
if (!hasCPU)
{
strcat(buffer, "\n ? % CPU");
}
else
{
sprintf(cad, "\n %5.1f%% CPU", cpu_used * 100.0 / total_cpu);
strcat(buffer, cad);
}
}
복사
복사됨
복사
복사됨
strcat(buffer,
"</txt><tool>"
);
// CPU
if (!hasCPU) sprintf(cad, " | CPU: %3lld",total_cpu);
else sprintf(cad, " | CPU: %3.0lf%%", cpu_used * 100.0 / total_cpu);
strcat(buffer,
cad
);
복사
복사됨
복사
복사됨
if (networkAvailable
&&
hasNet)
// RAM
{
FILE *meminfo = fopen("/proc/meminfo", "r");
sprintf(cad,
" %s:\n %.2f
MB
received \n %.2f MB sent ",
if(meminfo) {
argv[1], recv_bytes/1000000.0, sent_bytes/1000000.0)
;
char line[256];
strcat(buffer, cad);
while(fgets(line, sizeof(line), meminfo)) {
if(!total_ram
&&
sscanf(line, "MemTotal: %d kB", &total_ram));
if(sscanf(line, "Active: %d kB", &ram_used) == 1)
{
sprintf(cad,
" | RAM: %5d
MB
",ram_used/1024);
break
;
}
}
}
복사
복사됨
복사
복사됨
fclose(meminfo);
if(!ram_used) sprintf(cad, " RAM: %5d MB",total_ram);
strcat(buffer,cad);
}
복사
복사됨
복사
복사됨
if (reportCPU && hasCPU)
// DISK
{
FILE *diskstat = fopen("/proc/diskstats","rt");
if (networkAvailable && hasNet) strcat(buffer, "\n")
;
disk_stats dss;
long long total_used_cpu = user_mode_time + user_mode_nice_time + system_mode_time;
if(diskstat)
{
sprintf(
cad
, " CPU usage:\n %5.1f%% since boot ",
char line[512]
;
total_used_cpu * 100.0 / (total_used_cpu + idle_time))
;
while(fgets(line,sizeof(line),diskstat)) {
strcat(buffer, cad);
const char *
cad
= dss.parse(line,seconds);
if(!cad) continue
;
strcat(buffer, cad);
}
}
복사
복사됨
복사
복사됨
fclose(diskstat);
}
복사
복사됨
복사
복사됨
strcat(buffer, "</
tool>");
strcat(buffer, "</
txt><
tool>");
복사
복사됨
복사
복사됨
write(1, buffer, strlen(buffer));
복사
복사됨
복사
복사됨
return 0;
// TOOLTIPS
bool useNet = networkAvailable && hasNet;
if (useNet) {
sprintf(cad, " %s:\n %.2f MB received \n %.2f MB sent ",
argv[1], recv_bytes/1024.0/1024, sent_bytes/1024.0/1024);
strcat(buffer, cad);
}
if (hasCPU) {
if (useNet) strcat(buffer, "\n");
long long total_used_cpu = user_mode_time + user_mode_nice_time + system_mode_time;
sprintf(cad, " CPU usage:\n %5.1f%% since boot \n",
total_used_cpu * 100.0 / (total_used_cpu + idle_time));
strcat(buffer, cad);
}
sprintf(cad, " RAM usage:\n %5.1f%% of %d MB",
ram_used * 100.0 / total_ram, total_ram / 1024 );
strcat(buffer, cad);
strcat(buffer, "</tool>");
write(1, buffer, strlen(buffer));
return 0;
}
}
저장된 비교 결과
원본
파일 열기
/* * Copyright (C) 2010 Ciriaco Garcia de Celis * * 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 (GPL) for more details. * * You should have received a copy of the GNU GPL along with this * program. If not, see <http://www.gnu.org/licenses/>. */ // compile with "g++ -O3 -lrt netmon.cpp -o netmon" #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <cstdio> #include <cstring> #include <cstdlib> #include <ctime> #include <climits> #define STATE_FILE_BASE "/dev/shm/netmon" int exitapp(int exitcode) { char errmsg[64]; sprintf(errmsg, "ERROR code %d", exitcode); write(1, errmsg, strlen(errmsg)); return exitcode; } int main(int argc, char** argv) { if (argc < 2) { printf("usage: %s <network_interface> [CPU]\n", argv[0]); return 1; } bool reportCPU = (argc > 2) && (strcmp(argv[2], "CPU") == 0); char buffer[4096], cad[256], *ni, *nf; // read network information int fd = open("/proc/net/dev", O_RDONLY); if (fd < 0) return exitapp(2); int bytes = read(fd, buffer, sizeof(buffer)-1); close(fd); if (bytes < 0) return exitapp(3); buffer[bytes] = 0; timespec tp; clock_gettime(CLOCK_MONOTONIC, &tp); long long nanoseconds = tp.tv_sec * 1000000000LL + tp.tv_nsec; long long recv_bytes=LLONG_MAX, sent_bytes=LLONG_MAX; bool networkAvailable = false; // search for the proper network interface strcpy(cad, argv[1]); strcat(cad, ":"); char *pif = strstr(buffer, cad); if (pif != NULL) { networkAvailable = true; // jump to the received bytes field ni = pif + strlen(cad); while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); *nf++ = 0; // get the received bytes recv_bytes = atoll(ni); // jump to the sent bytes field for (int skip = 0; skip < 8; skip++) { ni = nf; while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); if (!*nf) break; *nf++ = 0; } // get the sent bytes sent_bytes = atoll(ni); } long long user_mode_time=0, user_mode_nice_time=0, system_mode_time=0, idle_time=0; if (reportCPU) { // read CPU information fd = open("/proc/stat", O_RDONLY); if (fd < 0) return exitapp(4); bytes = read(fd, buffer, sizeof(buffer)-1); close(fd); if (bytes < 0) return exitapp(5); buffer[bytes] = 0; pif = strstr(buffer, "cpu "); if (pif != NULL) { ni = pif + 3; while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); *nf++ = 0; // get the user mode time user_mode_time = atoll(ni); ni = nf; while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); *nf++ = 0; // get the user mode nice time user_mode_nice_time = atoll(ni); ni = nf; while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); *nf++ = 0; // get the system mode time system_mode_time = atoll(ni); ni = nf; while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); *nf++ = 0; // get the idle time idle_time = atoll(ni); } } // read the received/sent bytes, date and CPU usage stored by a previous execution sprintf(cad, "%s.%s.%d", STATE_FILE_BASE, argv[1], getuid()); fd = open(cad, O_RDWR | O_CREAT, 0664); if (fd < 0) return exitapp(6); bytes = read(fd, buffer, sizeof(buffer)-1); if (bytes < 0) { close(fd); return exitapp(7); } long long prev_recv_bytes, prev_sent_bytes, prev_nanoseconds = -1; long long prev_user_mode_time, prev_user_mode_nice_time, prev_system_mode_time, prev_idle_time = -1; if (bytes > 0) { prev_recv_bytes = atoll(buffer); prev_sent_bytes = atoll(buffer+20); prev_nanoseconds = atoll(buffer+40); prev_user_mode_time = atoll(buffer+60); prev_user_mode_nice_time = atoll(buffer+80); prev_system_mode_time = atoll(buffer+100); prev_idle_time = atoll(buffer+120); } // store in the file the current values for later use sprintf(buffer, "%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n", recv_bytes, sent_bytes, nanoseconds, user_mode_time, user_mode_nice_time, system_mode_time, idle_time); lseek(fd, 0, SEEK_SET); write(fd, buffer, 140); close(fd); // generate the result strcpy(buffer, "<txt>"); bool hasNet = networkAvailable && (prev_nanoseconds >= 0) && (recv_bytes >= prev_recv_bytes) && (sent_bytes >= prev_sent_bytes); if (!networkAvailable) { sprintf(cad, " %s is down", argv[1]); strcat(buffer, cad); } else if (!hasNet) { strcat(buffer, " ? kbps IN \n ? kbps OUT"); } else { long long elapsed = nanoseconds - prev_nanoseconds; if (elapsed < 1) elapsed = 1; double seconds = elapsed / 1000000000.0; long long sent = sent_bytes - prev_sent_bytes; long long received = recv_bytes - prev_recv_bytes; long inbps = (long) (8 * received / seconds + 999); // adding 999 ensures "1" for any rate above 0 long outbps = (long) (8 * sent / seconds + 999); if (inbps < 1000000) sprintf(cad, "%6d kbps IN \n", inbps/1000); else sprintf(cad, "%6.3f Mbps IN \n", inbps/1000000.0); strcat(buffer, cad); if (outbps < 1000000) sprintf(cad, "%6d kbps OUT", outbps/1000); else sprintf(cad, "%6.3f Mbps OUT", outbps/1000000.0); strcat(buffer, cad); } long long cpu_used = user_mode_time + user_mode_nice_time + system_mode_time - (prev_user_mode_time + prev_user_mode_nice_time + prev_system_mode_time); long long total_cpu = cpu_used + (idle_time - prev_idle_time); bool hasCPU = (prev_idle_time >= 0) && (total_cpu > 0); if (reportCPU) { if (!hasCPU) { strcat(buffer, "\n ? % CPU"); } else { sprintf(cad, "\n %5.1f%% CPU", cpu_used * 100.0 / total_cpu); strcat(buffer, cad); } } strcat(buffer, "</txt><tool>"); if (networkAvailable && hasNet) { sprintf(cad, " %s:\n %.2f MB received \n %.2f MB sent ", argv[1], recv_bytes/1000000.0, sent_bytes/1000000.0); strcat(buffer, cad); } if (reportCPU && hasCPU) { if (networkAvailable && hasNet) strcat(buffer, "\n"); long long total_used_cpu = user_mode_time + user_mode_nice_time + system_mode_time; sprintf(cad, " CPU usage:\n %5.1f%% since boot ", total_used_cpu * 100.0 / (total_used_cpu + idle_time)); strcat(buffer, cad); } strcat(buffer, "</tool>"); write(1, buffer, strlen(buffer)); return 0; }
수정본
파일 열기
/* opyright (C) 2010 Ciriaco Garcia de Celis * * 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 (GPL) for more details. * * You should have received a copy of the GNU GPL along with this * program. If not, see <http://www.gnu.org/licenses/>. */ // compile with "g++ -O3 -lrt netmon.cpp -o netmon" #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <cstdio> #include <cstring> #include <cstdlib> #include <ctime> #include <climits> #include <cctype> #define STATE_FILE_BASE "/dev/shm/netmon" int exitapp(int exitcode) { char errmsg[64]; sprintf(errmsg, "ERROR code %d", exitcode); write(1, errmsg, strlen(errmsg)); exit(exitcode); return exitcode; } const int BLOCK_SIZE = 512; struct disk_stat { long long read, write; double r_rate, w_rate; char name[16]; }; const int MAX_STAT = 32; class disk_stats { disk_stat stat[MAX_STAT]; int total; public: disk_stats() : total(0) {} const char* parse(const char* line, double seconds) { if(total>=MAX_STAT) exitapp(11); static char cad[256], buffer[256]; long long dummy; disk_stat &ds = stat[total]; sscanf(line,"%lld %lld %s %lld %lld %lld %lld %lld %lld %lld", &dummy,&dummy,ds.name,&dummy,&dummy,&ds.read,&dummy,&dummy,&dummy,&ds.write); int len = strlen(ds.name); if(!dummy) return 0; if(isdigit(ds.name[len-1])) return 0; long long prev_read = 0, prev_write = 0; sprintf(cad,"%s.%s.%d",STATE_FILE_BASE,ds.name,getuid()); int fd = open(cad, O_RDWR | O_CREAT, 0664); if (fd < 0) exitapp(9); int bytes = read(fd, buffer, sizeof(buffer)-1); if (bytes < 0) exitapp(10); buffer[bytes] = 0; sscanf(buffer,"%lld %lld",&prev_read,&prev_write); lseek(fd, 0, SEEK_SET); sprintf(buffer,"%lld %lld",ds.read,ds.write); write(fd, buffer, 64); close(fd); ds.r_rate = (ds.read-prev_read)/seconds*BLOCK_SIZE/1024/1024; ds.w_rate = (ds.write-prev_write)/seconds*BLOCK_SIZE/1024/1024; if(ds.r_rate>0) { if(ds.w_rate>0) sprintf(buffer," | %s: %3.0lf %3.0lf",ds.name,ds.r_rate,ds.w_rate); else sprintf(buffer," | %s: %3.0lf .",ds.name,ds.r_rate); } else { if(ds.w_rate>0) sprintf(buffer," | %s: . %3.0lf",ds.name,ds.w_rate); else sprintf(buffer," | %s: . .",ds.name); } ++total; return buffer; } }; int main(int argc, char** argv) { if (argc < 2) { printf("usage: %s <network_interface>\n", argv[0]); return 1; } char buffer[4096], cad[256], *ni, *nf; // read network information int fd = open("/proc/net/dev", O_RDONLY); if (fd < 0) return exitapp(2); int bytes = read(fd, buffer, sizeof(buffer)-1); close(fd); if (bytes < 0) return exitapp(3); buffer[bytes] = 0; timespec tp; clock_gettime(CLOCK_MONOTONIC, &tp); long long nanoseconds = tp.tv_sec * 1000000000LL + tp.tv_nsec; long long recv_bytes=LLONG_MAX, sent_bytes=LLONG_MAX; bool networkAvailable = false; // search for the proper network interface strcpy(cad, argv[1]); strcat(cad, ":"); char *pif = strstr(buffer, cad); if (pif) { networkAvailable = true; // jump to the received bytes field ni = pif + strlen(cad); while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); *nf++ = 0; // get the received bytes recv_bytes = atoll(ni); // jump to the sent bytes field for (int skip = 0; skip < 8; skip++) { ni = nf; while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); if (!*nf) break; *nf++ = 0; } // get the sent bytes sent_bytes = atoll(ni); } long long user_mode_time=0, user_mode_nice_time=0, system_mode_time=0, idle_time=0; // read CPU information fd = open("/proc/stat", O_RDONLY); if (fd < 0) return exitapp(4); bytes = read(fd, buffer, sizeof(buffer)-1); close(fd); if (bytes < 0) return exitapp(5); buffer[bytes] = 0; pif = strstr(buffer, "cpu "); if (pif) { ni = pif + 3; while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); *nf++ = 0; // get the user mode time user_mode_time = atoll(ni); ni = nf; while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); *nf++ = 0; // get the user mode nice time user_mode_nice_time = atoll(ni); ni = nf; while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); *nf++ = 0; // get the system mode time system_mode_time = atoll(ni); ni = nf; while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++; for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++); *nf++ = 0; // get the idle time idle_time = atoll(ni); } // read the received/sent bytes, date and CPU usage stored by a previous execution sprintf(cad, "%s.%s.%d", STATE_FILE_BASE, argv[1], getuid()); fd = open(cad, O_RDWR | O_CREAT, 0664); if (fd < 0) return exitapp(6); bytes = read(fd, buffer, sizeof(buffer)-1); if (bytes < 0) { close(fd); return exitapp(7); } long long prev_recv_bytes = 0, prev_sent_bytes = 0, prev_nanoseconds = -1; long long prev_user_mode_time = 0, prev_user_mode_nice_time = 0, prev_system_mode_time = 0, prev_idle_time = -1; if (bytes > 0) { prev_recv_bytes = atoll(buffer); prev_sent_bytes = atoll(buffer+20); prev_nanoseconds = atoll(buffer+40); prev_user_mode_time = atoll(buffer+60); prev_user_mode_nice_time = atoll(buffer+80); prev_system_mode_time = atoll(buffer+100); prev_idle_time = atoll(buffer+120); } // store in the file the current values for later use sprintf(buffer, "%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n", recv_bytes, sent_bytes, nanoseconds, user_mode_time, user_mode_nice_time, system_mode_time, idle_time); lseek(fd, 0, SEEK_SET); write(fd, buffer, 140); close(fd); // generate the result strcpy(buffer, "<txt>"); long long elapsed = nanoseconds - prev_nanoseconds; if (elapsed < 1) elapsed = 1; double seconds = elapsed / 1000000000.0; // NETWORK bool hasNet = networkAvailable && (prev_nanoseconds >= 0) && (recv_bytes >= prev_recv_bytes) && (sent_bytes >= prev_sent_bytes); if (!networkAvailable) { sprintf(cad, " %s is down", argv[1]); strcat(buffer, cad); } else if (!hasNet) { strcat(buffer, "D: - U: - "); } else { long long sent = sent_bytes - prev_sent_bytes; long long received = recv_bytes - prev_recv_bytes; long inbps = (long) (8 * received / seconds + 999) / 8 / 1024; // adding 999 ensures "1" for any rate above 0 long outbps = (long) (8 * sent / seconds + 999) / 8 / 1024; if (inbps < 1024) sprintf(cad, "D: %5ld KB/s ", inbps); else sprintf(cad, "D: %5.0lf MB/s ", inbps/1024.0); strcat(buffer, cad); if (outbps < 1024) sprintf(cad, " | U: %5ld KB/s ", outbps); else sprintf(cad, " | U: %5.0lf MB/s ", outbps/1024.0); strcat(buffer, cad); } long long cpu_used = user_mode_time + user_mode_nice_time + system_mode_time - (prev_user_mode_time + prev_user_mode_nice_time + prev_system_mode_time); long long total_cpu = cpu_used + (idle_time - prev_idle_time); int total_ram = 0, ram_used = 0; bool hasCPU = (prev_idle_time >= 0) && (total_cpu > 0); // CPU if (!hasCPU) sprintf(cad, " | CPU: %3lld",total_cpu); else sprintf(cad, " | CPU: %3.0lf%%", cpu_used * 100.0 / total_cpu); strcat(buffer, cad); // RAM FILE *meminfo = fopen("/proc/meminfo", "r"); if(meminfo) { char line[256]; while(fgets(line, sizeof(line), meminfo)) { if(!total_ram && sscanf(line, "MemTotal: %d kB", &total_ram)); if(sscanf(line, "Active: %d kB", &ram_used) == 1) { sprintf(cad," | RAM: %5d MB",ram_used/1024); break; } } fclose(meminfo); if(!ram_used) sprintf(cad, " RAM: %5d MB",total_ram); strcat(buffer,cad); } // DISK FILE *diskstat = fopen("/proc/diskstats","rt"); disk_stats dss; if(diskstat) { char line[512]; while(fgets(line,sizeof(line),diskstat)) { const char *cad = dss.parse(line,seconds); if(!cad) continue; strcat(buffer, cad); } fclose(diskstat); } strcat(buffer, "</txt><tool>"); // TOOLTIPS bool useNet = networkAvailable && hasNet; if (useNet) { sprintf(cad, " %s:\n %.2f MB received \n %.2f MB sent ", argv[1], recv_bytes/1024.0/1024, sent_bytes/1024.0/1024); strcat(buffer, cad); } if (hasCPU) { if (useNet) strcat(buffer, "\n"); long long total_used_cpu = user_mode_time + user_mode_nice_time + system_mode_time; sprintf(cad, " CPU usage:\n %5.1f%% since boot \n", total_used_cpu * 100.0 / (total_used_cpu + idle_time)); strcat(buffer, cad); } sprintf(cad, " RAM usage:\n %5.1f%% of %d MB", ram_used * 100.0 / total_ram, total_ram / 1024 ); strcat(buffer, cad); strcat(buffer, "</tool>"); write(1, buffer, strlen(buffer)); return 0; }
비교하기