저 아래의 "log file 감지"에 관해서...

hekimian의 이미지

과거 질문중에 "log file 감지"에 관한 내용을 보던 중 의문이 생겨서 이렇게
질문 합니다.
http://bbs.kldp.org/viewtopic.php?t=1462&highlight=select

sunyzero님의 답변중에서 select() 함수를 호출하여 처리하면 심플하게 끝난다고 하셨는데 ... 문제는 log 화일에 새로운 내용이 추가가 될 경우에만 select() 함수의 read 식별자를 set시키고 return 하게 만드는 방법을 알고 싶습니다.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/time.h>
#include <fcntl.h>

extern int errno;

int main(int argc, char *argv[]) {


	int fd, 	running=1;
	fd_set  	fdSet;
	long    	timeout=10, fdOffset=0;
	struct  	timeval selTimeout;
	int     	maxDescriptor;


	if ((fd = open("./logd.log", O_RDONLY)) < 0) {
		fprintf(stderr, "> errno is '%d' \n", errno);
		perror("> fiel open error.\n");
		close(fd);
		exit(1);
	}

	fdOffset = lseek(fd, 0L, 2);
	
	while(running) {

		FD_ZERO(&fdSet);
		FD_SET(fd, &fdSet);
		
		selTimeout.tv_sec = timeout;
		selTimeout.tv_usec =0 ;

		if (select(fd+1, &fdSet, NULL, NULL, &selTimeout) == 0)
			printf("No echo requests for %ld secs ... Server still alive\n", timeout);
		else {
			
			if (FD_ISSET(fd, &fdSet)) {
				printf("> log file update.... \n");
				sleep(1);
			}
		}
	}
}	

위와 같은 식으로는 log 화일에 내용이 추가 되지 않아도 select() 함수가 계속하여 read 식별자를 set 시키고 return하게 됩니다.

여러분들의 고견 부탁드립니다.

jemiro의 이미지

혹시 간단한 문제라면 아래의 timeout의 값이 너무 적지 않을까요?

selTimeout.tv_sec = timeout;

hekimian의 이미지

select()함수가 timeout에 정해진 시간보다 빨리 return합니다.
고로 fd가 입력을 수행할 준비가 되었다고 보아야겠죠.

개인적인 생각으로도 정상적으로 open된 file descriptor에 대해서 read select를 걸어노면 바로 return 할것 같다는 생각은 했습니다.

문제는 log 화일에 새로운 내용이 입력 되는 것을 어떻게 알아낼까 하는 것입니다. 물론 log file의 size를 비교한다거나 하는 방법 말구 select 함수를 이용해서요.

그리고 관심 가져주신 모든 분께 감사드립니다. 꾸뻑 ~~~

나를 죽이지 않는 모든 것은 나를 강하게 할 뿐이다.

juami의 이미지

파일 하나 감시하는데 select()씩이나..
그냥 read()로 읽고 있으면 되는거 아닌가요?

읽어야 할 대상이 여러개라면 몰라도..

sunyzero의 이미지

그냥 select 에서 왜 timeout을 주죠?

제 생각엔 여러개의 로그파일을 감시하는데 사용하시는것 같은데, timeout을 NULL로 주어서 무한으로 기다리게 하면 간단할 것 같은데 굳이 timeout을 주는 이유가 뭔가요? ^^*

========================================
* The truth will set you free.

hekimian의 이미지

여러분들의 고견은 잘 보고있습니다.

timeout을 NULL로 주어도 상관은 없습니다. 문젠 NULL로 주든 어떤 값을 주든 log file에 변화가 없는데도 select() 함수가 바로 리턴이 된다는 것입니다.

이것을 log file에 어떤 새로운 입력이 있을 경우에만 select() 함수가 return 하게끔 하는게 목적입니다.

timeout을 NULL로도 주어 봤고, 10초를 주어보기도 했는데 timeout 시간과는 상관 없이 select() 함수가 바로 리턴 되었습니다.

관심 가져 주신 분들께 감사드립니다...

나를 죽이지 않는 모든 것은 나를 강하게 할 뿐이다.

xfmulder의 이미지

그렇다면 select() 로는 (tail -f 처럼) 파일감시를 구현하지 못한다는 건가요?
tail 은 어떤식으로 하고 있는지 아시는 분. 한마디 해주세요.

내 자식들도 나처럼 !!

정인철의 이미지

전번에 로그파일 감시라는 질문을 했던 사람입니다.(http://bbs.kldp.org/viewtopic.php?t=1462&highlight=select )

저도 같은 결과를 얻었습니다.

select를 걸어봤지만, 아무로 효과를 얻지 못했었죠.

그래서 혹시나 해서, 그냥 read로만 열어놓고 기달려 봤는데.
로그파일이 업데이트가 되면, 자동으로 입력이 되더군요. 즉, 제가 원하는 결과를 얻을 수 있었습니다.

파일 입출력 동기화에 대한 개념이 아직 확실이 서지 않아서 생긴 문제 인거 같습니다.
read 같은 경우는 기본적으로 입력이 올때까지 기다리기 때문에 이런 현상이 있었던거 같구요.

select는 아직까지 해결하지 못하고 있습니다. 뭔가 이유가 있겠죠.
정말 궁금하네요

sunyzero의 이미지

hekimian wrote:
여러분들의 고견은 잘 보고있습니다.

timeout을 NULL로 주어도 상관은 없습니다. 문젠 NULL로 주든 어떤 값을 주든 log file에 변화가 없는데도 select() 함수가 바로 리턴이 된다는 것입니다.

이것을 log file에 어떤 새로운 입력이 있을 경우에만 select() 함수가 return 하게끔 하는게 목적입니다.

timeout을 NULL로도 주어 봤고, 10초를 주어보기도 했는데 timeout 시간과는 상관 없이 select() 함수가 바로 리턴 되었습니다.

관심 가져 주신 분들께 감사드립니다...

뭔가 이상하군요. NULL을 주면 입출력이 발생할때까지 기다립니다. 제가 예전에 누군가에게 tail -f 처럼 파일을 감시하는 프로그램을 짜주었는데 그때 한번에 20여개의 파일을 감시하고 있었어도 전혀 문제될 것은 없었습니다.
혹시 파라메터를 잘못주신것은 아닌지 다시한번 살펴보시기 바랍니다. 저도 시간이 짬나면 테스트해보고 올려드리겠습니다. 그나저나 날씨가 다시 꾸리해지는군요. -_-)a

========================================
* The truth will set you free.

stoneshim의 이미지

select 나 poll 은 level triggerd event notification 만을 지원하기 때문에 지금 논의되는 환경에서는 불가능하지 않을까 싶습니다.

select 하는 fd가 socket이라면 read시 read한 만큼이 socket buffer에서 없어지므로 계속해서 감시가 가능합니다.
하지만 fd가 regular file이라면 항상 readable 한 상태이므로 select 는 항상 return하게 됩니다.

가능하게 하는 방식은 logfile을 select 하여 readable 하면 다른 logfile에 append 하고 기존 logfile에서 read한 부분은 지우는 방법을 사용해야 할 것입니다.

edge triggered 를 지원하는 것으로 epoll이나 kqueue(확실하지 않음)가 있는데 현재 epoll의 경우 regular file을 지원하지 않는것으로 보입니다.( man에는 poll이 지원하는 file을 모두 지원한다고 나와있습니다.)

참고로 tail -f 의 경우는 1초간 sleep 후 fstat 하는 방식입니다.

우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자

hekimian의 이미지

stoneshim님의 글 잘 읽어 보았습니다.

쓰신 글 중에서 잘 모르는 내용도 있긴 하지만... ^^;;; 전체적으로 안돼는 이유를 이해하는데는 충분했습니다. 정말 감사드립니다.

나를 죽이지 않는 모든 것은 나를 강하게 할 뿐이다.

sunyzero의 이미지

제가 착각을 했었군요.

regular file에는 사용할 수 없고 ,항상 바로 리턴한다고 하는군요. 죄송합니다. 따라서 일반파일에서는 어떠한 방식으로도 select, poll은 사용할 수가 없게 되었습니다.

예전에 짜놓은 코드는 소켓에서 로그내용을 읽어오는군요.

========================================
* The truth will set you free.

stoneshim의 이미지

Quote:
가능하게 하는 방식은 logfile을 select 하여 readable 하면 다른 logfile에 append 하고 기존 logfile에서 read한 부분은 지우는 방법을 사용해야 할 것입니다.

테스트 해보니 이것도 안되는군요.

regular file에서는 안되는 모양입니다.

우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자

김충길의 이미지

fstat 를 써보시죠.

타임 딜레이는 select를 써도 될거 같습니다.

일단 파일에 변경사항이 생기면 struct stat 값이 변할테니..
변경되면 이전 포인터에서 파일을 계속 읽으면 될듯.

stat가 변경된걸 알려면 이전 struct stat 값도 가지고 있어야 겠죠 :-)

screen + vim + ctags 좋아요~

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.