아래 이미지처럼 10초마다 CPU 사용량을 계산해서 출력해주는 프로그램이 있다고 해보자.
1. 프로그램을 작성하고 (아래 파일)
2. 컴파일하고 (gcc -o printcpu printcpu.cpp)
3. 실행 시킨다. (./printcpu)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
int main() {
time_t t;
struct tm *tm;
double a[4], b[4], loadavg;
while (1) {
t = time(NULL);
tm = localtime(&t);
FILE *fp = fopen("/proc/stat","r");
fscanf(fp,"%*s %lf %lf %lf %lf",&a[0],&a[1],&a[2],&a[3]);
fclose(fp);
sleep(1);
fp = fopen("/proc/stat","r");
fscanf(fp,"%*s %lf %lf %lf %lf",&b[0],&b[1],&b[2],&b[3]);
fclose(fp);
loadavg = ((b[0]+b[1]+b[2]) - (a[0]+a[1]+a[2])) / ((b[0]+b[1]+b[2]+b[3]) - (a[0]+a[1]+a[2]+a[3]));
printf("%04d-%02d-%02d %02d:%02d:%02d CPU usage : %.2f%%\n",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec, loadavg * 100);
sleep(9);
}
return 0;
}
이제 이걸 서비스로 만들어보자.
su 권한으로 로그인해서
1. cd /etc/systemd/system으로 간다.
2. 만들고 싶은 서비스 이름을 만든다. 난,printcpu.service 라는 이름으로 간단하게 만들어봤다.
3. 위에서 만들었던 printcpu라는 binary를 /usr/sbin에 옮겨야 한다. (아래 ExecStart로 지정했으므로.)
[Unit]
Description=System CPU check
[Service]
ExecStart=/usr/sbin/printcpu
Restart=on-failure
[Install]
WantedBy=multi-user.target
이제 서비스를 시작해보자.
아래와 같이 만든 서비스 파일을 로드 하고, printcpu라는 서비스를 시작하도록 한다.
위에서 /etc/systemd/system/printcpu.service라고 만들었으니 서비스 이름은 printcpu.service나 printcpu로 입력 하면 된다.
sudo systemctl daemon-reload
sudo systemctl start printcpu.service
systemctl status printcpu로 잘 실행되고 있는지 확인해보자.
일단 서비스는 잘 시작 했으나, 10초에 한번씩 로그를 찍게 만드는 부분이 어디에 남아 있는지 보자.
systemd 로그는 기본적으로 /var/log/ 아래에 syslog에 남는다.
sudo vi /var/log/syslog 라는 명령으로 실행해보면 아래와 같이 printcpu라는 서비스가 시작 했다라는 것만 로그에 남고 실제 printf 로 찍은 로그는 남지 않는 걸 확인할 수 있다.
다시 코드를 살펴보자. printf로 찍은 걸 syslog()를 이용하도록 변경해보자.
syslog.h를 include 해주고, openlog() 함수를 사용하여 로그에 대한 설정을 합니다. 첫 번째 인자는 로그 이름을 지정하는데, 여기서는 "printcpu"라고 지정하고, 두 번째 인자는 로그 옵션을 지정하는데, LOG_PID 옵션을 사용하면 프로세스 ID가 로그에 추가된다. 마지막으로 세 번째 인자는 로그 타입을 지정하는데, LOG_DAEMON을 사용하면 로그를 시스템 로그에 기록하게 된다. 그리고 기존에 printf를 syslog() 함수로 변경한다. 첫 번째 인자에 로그 레벨을 지정할 수 있는데, LOG_INFO를 설정했다. 마지막으로 closelog() 함수를 사용하여 로그를 닫아주었다.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <syslog.h>
int main() {
time_t t;
struct tm *tm;
double a[4], b[4], loadavg;
openlog("printcpu", LOG_PID, LOG_DAEMON);
while (1) {
t = time(NULL);
tm = localtime(&t);
FILE *fp = fopen("/proc/stat","r");
fscanf(fp,"%*s %lf %lf %lf %lf",&a[0],&a[1],&a[2],&a[3]);
fclose(fp);
sleep(1);
fp = fopen("/proc/stat","r");
fscanf(fp,"%*s %lf %lf %lf %lf",&b[0],&b[1],&b[2],&b[3]);
fclose(fp);
loadavg = ((b[0]+b[1]+b[2]) - (a[0]+a[1]+a[2])) / ((b[0]+b[1]+b[2]+b[3]) - (a[0]+a[1]+a[2]+a[3]));
// printf("%04d-%02d-%02d %02d:%02d:%02d CPU usage : %.2f%%\n",
// tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
// tm->tm_hour, tm->tm_min, tm->tm_sec, loadavg * 100);
syslog(LOG_INFO, "%04d-%02d-%02d %02d:%02d:%02d CPU usage : %.2f%%\n",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec, loadavg * 100);
sleep(9);
}
closelog();
return 0;
}
다시 컴파일하고, binary를 /usr/sbin에 옮긴다. 기존에 서비스가 돌고 있으므로 정지를 시켜줘야 한다. 이땐 sudo systemctl stop printcpu를 이용하자. binary 파일 복사가 되었으면 다시 서비스를 시작해보자. 그리고 /var/log/syslog를 보면 아래와 같이 의도한대로 INFO type으로 printcpu라는 이름으로 로그가 남는 걸 확인할 수 있다.
일단 불필요한 로그가 많이 남으므로 서비스는 종료해놓도록 하자.
댓글 영역