fluentd / td-agent는
fluentd는
fluentd 는 ruby gem에서 제공하는 로그 전송 / 수집의 구조입니다. rsyslogd에서는 실현 될 수없는 대량 로그 수집 / 분석을위한 목적으로 사용하면 좋다고 생각합니다.
td-agent는
td-agent 는 fluentd의 래퍼 프로그램입니다. ruby, gem 등의 프로그램과 시작 스크립트 등의 편리한 파일을 설치 명령 하나로 제공 해줍니다. td-agent는 환경 변수 PATH에 존재하지 않는 디렉토리에 ruby와 gem을 설치 해주기 때문에 전체 시스템에 영향을주지 않고 fluentd를 사용할 장점이 있습니다.
fluentd의 단점 (약점)
fluentd은 만능이 아니라 비즈니스 요구에 따라 클래식 rsyslogd를 사용하는 것이 좋은 장면도 존재합니다. 다음에 fluentd의 약점을 나열합니다. fluentd 대량 로그 전송 / 수집 / 분석을 목적으로 만들어져 있기 때문에 실시간 성 및 고 가용성은 골칫거리로하는 분야입니다.
무엇이든 fluentd에 맡기는 것이 아니라 fluentd의 약점을 이해 한 다음 도구 선정이 중요합니다. 로그를 감사 및 모니터링 등의 목적으로 사용한다면 fluentd보다 뛰어난 도구는 많이 있습니다. 내가 개인적으로 fluentd의 약점이라고 느낀 것들을 아래에 열거합니다 때문에 도구 선택의 참고로 해 주시면 감사하겠습니다.
실시간 성
fluentd는 대량의 로그를 수집 할 목적으로 만들어져 있습니다. 따라서 로그를 한 번 버퍼링합니다. 버퍼에 들어갈만큼 로그 전송이 느려지므로 실시간 로그 전송을 실현하고 싶다면 rsyslogd 쪽이 우수합니다.
예를 들어, "로그를 수집하여 로그 감시"와 같은 요구 사항의 경우 모니터링 에이전트 로그 모니터링 및 rsyslogd를 사용하는 것이 훨씬 운용하기 쉽습니다.
로그 전송의 신뢰성
fluentd 대량 로그를 전송하는 것을 목적으로 만들어져 있기 때문에 기본 설정은 메모리에 로그를 버퍼링합니다. 즉, fluentd 서버에 장애가 발생하면 로그가 손실 될 수 있습니다.
운영 시즈라 함 (Non DevOps)
fluentd는 운영자 측의 요구는별로 캡처되지 않습니다. DevOps 대신 DevDev 도구입니다. 예를 들어, fluentd가 상정하지 않은 로그가 fluentd에 흘러 들어가면 대량의 스택 트레이스가 기록됩니다. 실제로 나는 10 분에서 1G의 로그 파일이 토출되는 장애를 경험하고 있습니다.
또한 fluetnd 간의 로그 송수신은 버퍼링되어 일정한 간격으로 발생하지만,이 사양은 네트워크 엔지니어의 입장에서 말하면, 스위치 장비의 큐 넘쳐을 일으키는 폐 천만 사양입니다.
fluentd 내 인생에서 비교적 상위 트라우마 미들웨어입니다. 사용법을 잘못하면 운영자 울게 심한 도구가되어 버리기 때문에 설계 사상에 따라 fluentd을 사용하는 것이 중요합니다.
예외 처리의 달콤함
현재 (2014/08/16)의 fluentd은 운영자가 요구하는 같은 예외 처리는 개발 단계입니다. 실제로 소스 코드를 읽고, 예외 처리에 TODO라고 쓰여져있는 것이 산견됩니다. thread 비정상적으로 종료 프로세스 모니터링은 감지 할 수 없기 때문에 당분간 뭔가 동작이 이상하다고 느낀다면 재시작을 운용은 あながち 잘못도 아닙니다. 또한 이론적으로 fluentd debug라는 도구를 사용하면 분석 할 수 있지만 fluentd debug를 이용한 재해 복구 운용을 할 수는 도저히 생각되지 않습니다.
예외가 握りつぶさ 된 예는 다음과 같습니다.
| def on_readable msg, addr = @io.recvfrom_nonblock(2048) #host = addr[3] #port = addr[1] #@callback.call(host, port, msg) @callback.call(msg) rescue # TODO log? end |
fluentd의 장점 (강점)
설정 준비가
fluentd 설정 파일은 매우 직관적이고 쉽게 만들 수 있습니다. rsyslog과 nxlog 같은 로그 전송 소프트웨어도 fluentd 같은 처리가 가능하지만, 구문이 매우 복잡하고 학습 비용이 높습니다.
플러그인 작성의 준비가
fluentd은 아주 쉽게 플러그인을 만들 수 있습니다. 기본 클래스를 상속하고 필요한 메서드를 재정의하는 것만으로 쉽게 fluentd 플러그인을 만들 수 있습니다.
한편, rsyslog과 nxlog도 플러그 구성되어 있지만, C와 C ++을 이용하여 플러그인을 개발해야하므로 fluentd에 비해 훨씬 진보 된 기술을 요구합니다.
동기 유지
엔지니어라면 누구나 새로운 물건이 더 의욕을내는 것입니다. COBOL보다 ruby, python 공부를하고 싶은 것은 모두가 같은 마음 일 것입니다.
fluentd는 새로운 WEB 업계에서는 매우 인기가 있습니다. 의욕을 관찰 한 고전 "피플웨어」에서도 같은 일이 쓰여져 있습니다 만, 새로운 것을 도입하는 것에 따라 직원의 동기 부여 향상 의 효과는 헤아릴 수없는 것이 있습니다. (그렇다고해도 새로운 것에 절개없이 잡으려하면 뜻밖의 기술 부채가 직원을 괴롭히는 것은 자주 있습니다 만 ...)
fluentd 걷는 방법
현재 (2014/07/27)의 fluetnd 공식 사이트는 "www.fluentd.org/"입니다. fluentd 정보 수집 목적으로이 사이트에 방문하실 것은 매우 기쁩니다 만, 엔지니어라면 공식 사이트 같은 차 정보를 수집하는 것은 필수적이라고 생각합니다.
fluentd 공식 사이트에서 가장 많이 보는 것은 문서에 대한 내용입니다. "RESOURCES" "documentation"의 순으로 누르면 문서 목록 페이지를 열람 할 수 있습니다.
fluentd 공식 사이트 - 설치 방법
공식 사이트 fluentd (td-agent) 설치 절차는 "Overview", "Installation"의 순으로 누름하면 조사 할 수 있습니다. RPM을 사용하는 방법과 Chef를 사용하는 방법 등의 다양한 단계가 소개되고 있습니다 만, 여기에서는 가장 간단한 RPM을 사용하는 방법 만 소개합니다.
fluentd 공식 사이트 - 플러그인 소개
fluentd는 입출력 동작을 플러그인에 의해 결정할 수 있습니다. 뭔가 특별한 요구 사항이 발생하면 추가 플러그인을 도입하여 요구 사항을 충족 수 없습니다. 꼭 필요한 플러그인이 존재하지 않는 경우는 직접 만들 수도 있습니다.
fluentd 플러그인은 Input, Buffer, Output의 3 종류로 분류 할 수 있습니다. 익숙해지기 전에는 공식 사이트의 플러그인을 읽게하고 익숙해 오면 GitHub를 찾거나 직접 플러그인을 개발하거나하면 좋을 것입니다. 공식 사이트에서 소개되는 플러그인의 설명서는 사이드 바 메뉴의 "Input Plugins", "Output Plugins", "Buffer Plugins"을 누르시면 것으로 볼 수 있습니다.
td-agent (fluentd) 설치
td-agent (fluentd) 버전
td-anget 설치하기 전에 td-agent 버전을 검토해야합니다. 지금 현재 (2015 년 2 월)는 td-agent version 1 td-agent version 2로 과도기입니다. TRESURE DATA는 td-agent2로의 전환을 촉구하고 있습니다 만, td-anget2를 공식 사이트에서 발표 한 것은 2014 년 9 월이며, 충분히 시들지 않은 소프트웨어입니다.
소프트웨어 수명주기의 관점에서 유리한 td-anget2를 사용하거나 결함 위험의 관점에서 유리한 td-anget을 사용하는지는 직장, 프로젝트의 요구 사항에 따라 판단해야 할 것으로 생각합니다.
td-agent2 설치
인터넷에 접속 가능한 환경에서는 td-agent 설치는 매우 간단합니다. 설치 스크립트를 다운로드하여 파이프에서 shell에 전달뿐. 단 한줄로 실행할 수 있습니다.
| # curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh |
td-agent (이전 버전) 설치
이전 버전의 td-agent를 설치하려면 다음 명령합니다.
| # curl -L http://toolbelt.treasuredata.com/sh/install-redhat.sh | sh |
td-agent (fluentd) fluent-cat을 사용하여 간단한 동작 확인
너무 설치가 너무 간단하고 실제로 사용하고 있는지 불안하게 생각하는 분도 있다고 생각합니다. 그래서 간단한 동작 확인을 해 봅시다.
우선 시작 스크립트보다 td-agent를 시작합니다.
| # /etc/init.d/td-agent start |
td-agent의 기본 설정은 debug_agent라는 Input 플러그인 tcp 24230에서 Listen하고 있습니다. fluent-cat라는 디버깅 도구를 사용하면 debug_agent에 메시지를 보낼 수 있습니다. 다음의 요령으로 debug_agent에 메시지를 보냅니다.
| # echo '{"json":"message"}' | /usr/lib64/fluent/ruby/bin/fluent-cat debug.test |
td-agent의 기본 설정은 debug *라는 태그 된 메시지를 /var/log/td-agent/td-agent.log에 출력하는 사양으로되어 있습니다. /var/log/td-agent/td-agent.log을 표시하고 실제로 메시지가 fluentd에 도착했는지 확인합니다.
| [root@locahost ~]# tail -f /var/log/td-agent/td-agent.log 2014-07-26 18:53:04 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/td-client-0.8.61/lib/td/client/api.rb:1305:in `raise_error' 2014-07-26 18:53:04 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/td-client-0.8.61/lib/td/client/api.rb:862:in `import' 2014-07-26 18:53:04 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/td-client-0.8.61/lib/td/client.rb:297:in `import' 2014-07-26 18:53:04 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluent-plugin-td-0.10.20/lib/fluent/plugin/out_tdlog.rb:298:in `upload' 2014-07-26 18:53:04 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluent-plugin-td-0.10.20/lib/fluent/plugin/out_tdlog.rb:278:in `write' 2014-07-26 18:53:04 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/buffer.rb:296:in `write_chunk' 2014-07-26 18:53:04 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/buffer.rb:276:in `pop' 2014-07-26 18:53:04 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/output.rb:310:in `try_flush' 2014-07-26 18:53:04 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/output.rb:132:in `run' 2014-07-26 18:54:16 +0900 debug.test: {"json":"message"} |
td-agent (fluentd)의 버전 업
설치 스크립트를 사용하여 td-agent를 설치 한 경우는 아주 쉽게 업그레이드 할 수 있습니다. 우선 구성을 파악하기 위해 설치 스크립트를 읽어 보자. 그러면 단순히 tresure data의 yum 저장소를 작성하고 yum install하고있을뿐임을 알 수 있습니다.
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 | # curl -L http://toolbelt.treasuredata.com/sh/install-redhat.sh echo "This script requires superuser access to install rpm packages." echo "You will be prompted for your password by sudo." # clear any previous sudo permission sudo -k # run inside sudo sudo sh <<SCRIPT # add GPG key rpm --import http://packages.treasuredata.com/GPG-KEY-td-agent # add treasure data repository to yum cat >/etc/yum.repos.d/td.repo <<'EOF'; [treasuredata] name=TreasureData baseurl=http://packages.treasuredata.com/redhat/\$basearch gpgcheck=1 gpgkey=http://packages.treasuredata.com/GPG-KEY-td-agent EOF # update your sources yes n | yum update # install the toolbelt yes | yum install -y td-agent SCRIPT |
그래서 td-agent를 업그레이드하려면 다음과 같은 yum 명령을 사용하기 만하면됩니다. 그러나 버전 업에 따라 각종 플러그인의 사양 변경의 가능성이 있으므로, 혹시 /etc/td-agent/td-agent.conf의 수정이 필요하게 될지도 모릅니다.
td-agent (fluentd) 설정
td-agent (fluentd) 부팅 옵션 설정
td-agent는 기본적으로 td-agent 사용자로 시작됩니다. td-agent 사용자는 / var / log / messages 등의 syslogd가 출력 할 파일을 읽을 수 없기 때문에, td-agent 운용이 다소 어려워집니다. 그래서 td-agent를 root 권한으로 실행시키는 것을 권장합니다.
td-agent 시작 스크립트를 읽고 / etc / sysconfig / td-agent로 시작 사용자를 설정할 수 알 수 있습니다. td-agent를 root 사용자 / root 그룹에서 시작하는 설정 예는 다음과 같습니다.
| DAEMON_ARGS="--user root" TD_AGENT_ARGS="/usr/sbin/td-agent --group root --log /var/log/td-agent/td-agent.log" |
또한 부팅 옵션으로 설정 가능한 항목 목록은 td-agent에 -h 옵션을 부여하는 것으로 확인할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | [root@localhost ~]# td-agent -h Usage: td-agent [options] -s, --setup [DIR=/etc/td-agent] install sample configuration file to the directory -c, --config PATH config file path (default: /etc/td-agent/td-agent.conf) --dry-run Check fluentd setup is correct or not -p, --plugin DIR add plugin directory -I PATH add library path -r NAME load library -d, --daemon PIDFILE daemonize fluent process --user USER change user --group GROUP change group -o, --log PATH log file path -i CONFIG_STRING, inline config which is appended to the config file on-fly --inline-config --emit-error-log-interval SECONDS suppress interval seconds of emit error logs --suppress-repeated-stacktrace suppress repeated stacktrace --use-v1-config Use v1 configuration format -v, --verbose increase verbose level (-v: debug, -vv: trace) -q, --quiet decrease verbose level (-q: warn, -qq: error) --suppress-config-dump suppress config dumping when fluentd starts -g, --gemfile GEMFILE Gemfile path -G, --gem-path GEM_INSTALL_PATH Gemfile install path (default: $(dirname $gemfile)/vendor/bundle) |
td-agent (fluentd) 설정 파일의 편집
특히 부팅 옵션에서 설정 파일을 변경하지 않은 경우 / etc / td-agent / td-agent.conf 설정을 설명합니다.
동작 확인을 위해 td-agent 설정 파일을 수정하여 봅시다. 다음은 / var / log / messages 로그를 /var/log/td-agent/td-agent.log에 전송하는 설정 예입니다.
| <source> type tail path /var/log/messages tag system.syslog.messages format none </source> <match **> type stdout </match> |
td-agent를 다시 시작하고 설정을 반영합니다. pos_file 파라미터의 설정을 권장하는 취지의 경고가 나오고 있습니다 만,이 경고의 의미는 나중에 설명합니다.
| [root@localhsot ~]# /etc/init.d/td-agent restart 2014-07-27 01:12:06 +0900 [warn]: 'pos_file PATH' parameter is not set to a 'tail' source. 2014-07-27 01:12:06 +0900 [warn]: this parameter is highly recommended to save the position to resume tailing. Shutting down td-agent: [ OK ] Starting td-agent: [ OK ] [root@localhost ~]# |
/ var / log / messages이 /etc/td-agent/td-agent.log에 전송 된 것을 확인합니다.
| [root@localhost ~]# tail -f /var/log/td-agent/td-agent.log 2014-07-27 01:18:25 +0900 system.syslog.messages: {"message":"Jul 27 01:18:25 vps096 snmpd[27524]: Received TERM or STOP signal... shutting down..."} 2014-07-27 01:18:27 +0900 system.syslog.messages: {"message":"Jul 27 01:18:27 vps096 snmpd[13519]: NET-SNMP version 5.5"} 2014-07-27 01:18:57 +0900 system.syslog.messages: {"message":"Jul 27 01:18:57 vps096 kernel: ip_tables: (C) 2000-2006 Netfilter Core Team"} 2014-07-27 01:18:57 +0900 system.syslog.messages: {"message":"Jul 27 01:18:57 vps096 kernel: nf_conntrack version 0.5.0 (16384 buckets, 65536 max)"} 2014-07-27 01:19:07 +0900 system.syslog.messages: {"message":"Jul 27 01:19:07 vps096 kernel: Kernel logging (proc) stopped."} 2014-07-27 01:19:07 +0900 system.syslog.messages: {"message":"Jul 27 01:19:07 vps096 rsyslogd: [origin software=\"rsyslogd\" swVersion=\"5.8.10\" x-pid=\"13389\" x-info=\"http://www.rsyslog.com\"] exiting on signal 15."} 2014-07-27 01:19:07 +0900 system.syslog.messages: {"message":"Jul 27 01:19:07 vps096 kernel: imklog 5.8.10, log source = /proc/kmsg started."} 2014-07-27 01:19:07 +0900 system.syslog.messages: {"message":"Jul 27 01:19:07 vps096 rsyslogd: [origin software=\"rsyslogd\" swVersion=\"5.8.10\" x-pid=\"13652\" x-info=\"http://www.rsyslog.com\"] start"} 2014-07-27 01:20:15 +0900 system.syslog.messages: {"message":"Jul 27 01:20:15 vps096 kernel: ip_tables: (C) 2000-2006 Netfilter Core Team"} 2014-07-27 01:20:15 +0900 system.syslog.messages: {"message":"Jul 27 01:20:15 vps096 kernel: nf_conntrack version 0.5.0 (16384 buckets, 65536 max)"} |
Input Plugins
Input Pluging는 fluentd 로그 수신 처리를 담당하는 프로그램입니다. 사용 빈도가 높은 Input Plugin 간단한 테스트 방법을 소개합니다.
in_tail
in_tail 로그를 끝에서 읽을 플러그인입니다. syslog 나 apache access.log처럼 파일 토출하는 로그를 fluentd로드시킬 때 사용하는 플러그인입니다.
in_tail을 테스트하는 최소한의 설정은 다음과 같습니다. /etc/td-agent/td-agent.conf을 다음과 같이 편집합니다.
| <source> type tail path /tmp/sample.log pos_file /tmp/sample.pos tag system.sample format none </source> <match **> type stdout </match> |
td-agent 다시 시작하면 설정을 반영합니다.
| # /etc/init.d/td-agent restart |
/tmp/sample.log을 읽도록 설정되어 있기 때문에 / tmp / sample.log에 적절한 메시지를 씁니다.
| # echo "test messages" >> /tmp/sample.log # echo "test messages" >> /tmp/sample.log |
/var/log/td-agent/td-agent.log에 로그가 전송되는 것을 확인합니다.
| [root@localhost ~]# tail -f /var/log/td-agent/td-agent.log </source> <match **> type stdout </match> </ROOT> 2014-08-13 00:55:49 +0900 [info]: adding source type="tail" 2014-08-13 00:55:49 +0900 [info]: adding match pattern="**" type="stdout" 2014-08-13 00:55:49 +0900 [info]: following tail of /tmp/sample.log 2014-08-13 00:56:19 +0900 system.sample: {"message":"test messages"} 2014-08-13 00:56:20 +0900 system.sample: {"message":"test messages"} |
in_http
in_http은 http 통신을 통해 로그를받을 플러그인입니다. 응용 프로그램 로그를 JSON으로하고 fluentd에 로그 쓰기 사양으로되어 있기 때문에 응용 프로그램 개발자가 로그 형식에 얽매이지 않고 처리에 따라 유연한 로그 형식을 채용 할 수 있습니다.
그러나 td-agent의 유지 보수 및 재부팅시 로그 전송이 끊어지는 위험이 있으므로 정말 중요한 로그 파일 출력 in_tail 의해 로그 전송을 고려하자.
in_http 동작 확인 최소한의 설정은 다음과 같습니다. /etc/td-agent/td-agent.conf을 다음과 같이 편집합니다.
| <source> type http port 8888 </source> <match **> type stdout </match> |
td-agent 다시 시작하면 설정을 반영합니다.
| # /etc/init.d/td-agent restart |
curl 명령에 로그를 보냅니다. 데이터 부분에 JSON 형식으로 로그를 작성하고 URL 헤더에 태그를 포함합니다.
| # curl -X POST -d 'json={"action":"login","user":2}' http://localhost:8888/test.tag.here; # curl -X POST -d 'json={"action":"login","user":2}' http://localhost:8888/test.tag.here; |
/var/log/td-agent/td-agent.log에 로그가 전송되는 것을 확인합니다.
| [root@localhost ~]# tail -f /var/log/td-agent/td-agent.log port 8888 </source> <match **> type stdout </match> </ROOT> 2014-08-13 01:00:14 +0900 [info]: adding source type="http" 2014-08-13 01:00:14 +0900 [info]: adding match pattern="**" type="stdout" 2014-08-13 01:00:33 +0900 test.tag.here: {"action":"login","user":2} 2014-08-13 01:00:34 +0900 test.tag.here: {"action":"login","user":2} |
in_exec
in_exec 정기적으로 명령을 실행하고 표준 출력을 fluentd에 쓰기 플러그인입니다.
in_exec 동작 확인 최소한의 설정은 다음과 같습니다. /etc/td-agent/td-agent.conf을 다음과 같이 편집합니다. 또한, 다음의 설정은 재부팅 한 번만 명령이 실행되는 설정 예입니다. 정기적으로 명령을 실행하려면 run_interval 매개 변수를 지정하십시오.
| <source> type exec command vmstat | tail -n1 tag system.vmstat keys k1 </source> <match **> type stdout </match> |
td-agent 다시 시작하면 설정을 반영합니다.
| # /etc/init.d/td-agent restart |
/var/log/td-agent/td-agent.log에 로그가 전송되는 것을 확인합니다.
| [root@localhost ~]# tail /var/log/td-agent/td-agent.log tag system.vmstat keys k1 </source> <match **> type stdout </match> </ROOT> 2014-08-14 00:06:21 +0900 [info]: adding source type="exec" 2014-08-14 00:06:21 +0900 [info]: adding match pattern="**" type="stdout" 2014-08-14 00:06:21 +0900 system.vmstat: {"k1":" 1 1 158280 140752 67212 162336 0 0 3 62 5 0 4 1 95 0 0"} |
in_syslog
in_syslog는 syslog 메시지를 fluentd에 쓰기 플러그인입니다.
in_syslog 동작 확인 최소한의 설정은 다음과 같습니다. /etc/td-agent/td-agent.conf을 다음과 같이 편집합니다.
| <source> type syslog port 5140 tag system </source> <match **> type stdout </match> |
td-agent 다시 시작하면 설정을 반영합니다.
| # /etc/init.d/td-agent restart |
/etc/rsyslog.conf을 다음과 같이 편집하여 syslog를 fluentd에 전송하도록 설정합니다.
| diff --git a/rsyslog.conf b/rsyslog.conf index 37acb7b..15c1017 100644 --- a/rsyslog.conf +++ b/rsyslog.conf @@ -79,6 +79,7 #$ActionResumeRetryCount -1 # infinite retries if host is down # remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional #*.* @@remote-host:514 +*.info @127.0.0.1:5140 # ### end of the forwarding rule ### |
rsyslogd를 다시 시작하고 설정을 반영합니다.
| # /etc/init.d/rsyslog restart |
/var/log/td-agent/td-agent.log에 syslog가 전송되는 것을 확인합니다.
| [root@localhost ~]# tail /var/log/td-agent/td-agent.log type stdout </match> </ROOT> 2014-08-14 14:08:17 +0900 [info]: fluent/engine.rb:102:block in configure: adding source type="syslog" 2014-08-14 14:08:17 +0900 [info]: fluent/engine.rb:118:block in configure: adding match pattern="**" type="stdout" 2014-08-14 14:08:17 +0900 [debug]: plugin/in_syslog.rb:183:listen: listening syslog socket on 0.0.0.0:5140 with udp 2014-08-14 14:08:17 +0900 system.authpriv.info: {"host":"localhost","ident":"runuser","message":"pam_unix(runuser:session): session closed for user root"} 2014-08-14 14:08:30 +0900 system.authpriv.info: {"host":"localhost","ident":"sshd","pid":"21658","message":"Received signal 15; terminating."} 2014-08-14 14:08:30 +0900 system.authpriv.info: {"host":"localhost","ident":"sshd","pid":"17715","message":"Server listening on 0.0.0.0 port 22."} 2014-08-14 14:08:30 +0900 system.authpriv.info: {"host":"localhost","ident":"sshd","pid":"17715","message":"Server listening on :: port 22."} |
in_forward
in_forward는 message pack 따라 로그를 수신하는 플러그인입니다. 로그를 보낼 out_forward와 세트로 사용 플러그인이므로 아래의 out_forward과 함께 동작 확인을 실시합니다.
Output Plugins
Output Pluging는 fluentd 로그 전송 처리를 담당하는 프로그램입니다. 사용 빈도가 높은 Output Plugin 간단한 테스트 방법을 소개합니다.
또한 Output Plugin 로그를 출력하는 시점에 따라 Non-Buffered, Bufferd, Time Sliced의 3 종류로 분류 할 수 있습니다. fluentd 공식 문서를 인용이지만, 3 종류의 차이는 아래 표와 그림으로 설명되어 있습니다.
OUTPUT PLUGIN의 분류 | 설명 |
---|
Non-Buffered | 데이터를 버퍼링없이 즉시 결과를 내 보냅니다. |
Buffered | 청크 (chunk는 이벤트의 집합입니다) 큐를 유지하고 그 행동은 "chunk limit"와 "queue limit"매개 변수에 의해 조정할 수 있습니다 (아래 그림 참조). |
Time Sliced | 사실상 Bufferred 플러그인이지만, 청크는 시간에 따라 키됩니다 (아래 그림 참조). |
out_stdout (Non-Buffered)
out_stdout 로그를 표준 출력 또는 로그 파일에 기록 플러그인입니다. 기본 설정의 경우 / var / log / td-agent / td-agent.log에 로그가 출력됩니다. 다른 플러그인과 달리 Non-Buffered이기 때문에 "즉시"로그가 출력됩니다. 따라서 fluentd 설정의 디버깅을 할 때 매우 유용한 플러그인입니다.
out_stdout의 동작 확인을 위해 / etc / td-agent / td-agent.conf을 다음과 같이 편집합니다.
| <source> type exec command echo "the sky is falling in 100 seconds!" tag system.test keys message run_interval 10s </source> <match **> type stdout </match> |
td-agent 다시 시작하면 설정을 반영합니다.
| # /etc/init.d/td-agent restart |
/var/log/td-agent/td-agent.log에 로그가 전송되는 것을 확인합니다.
| [root@localhost ~]# tail /var/log/td-agent/td-agent.log run_interval 10s </source> <match **> type stdout </match> </ROOT> 2014-08-15 00:48:56 +0900 [info]: fluent/engine.rb:102:block in configure: adding source type="exec" 2014-08-15 00:48:56 +0900 [info]: fluent/engine.rb:118:block in configure: adding match pattern="**" type="stdout" 2014-08-15 00:49:06 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} 2014-08-15 00:49:16 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} [root@localhost ~]# |
out_file (Time Sliced)
out_file는 로그를 파일로 내보내기 플러그인입니다. Time Sliced 플러그인이므로 Time Sliced 시간이 경과 할 때까지 로그 파일이 생성되지 않는다는 점에주의하십시오.
out_file의 동작 확인을 위해 / etc / td-agent / td-agent.conf을 다음과 같이 편집합니다. 기본 설정은 시간으로 0시 10 분에 로그 파일이 생성되지만, 기본적으로 테스트에 많은 시간이 걸리므로, 분당에서 로그 파일을 생성하도록 time_slice_format, time_slice_wait을 정의하고 있습니다.
또한 root로 td-agent를 시작하는 경우 디렉토리 생성 할 필요가 없습니다. out_file 플러그인에서 디렉토리를 생성하는 과정이 설명되어 있습니다.
| <source> type exec command echo "the sky is falling in 100 seconds!" tag system.test keys message run_interval 10s </source> <match **> type file path /var/log/fluent/myapp time_slice_format %Y%m%d%H%M time_slice_wait 10s </match> |
td-agent 다시 시작하면 설정을 반영합니다.
| # /etc/init.d/td-agent restart |
로그가 생성되는 디렉토리를 볼 수 있습니다. td-agent 다시 시작한 후 30 초 정도 기다리면 다음과 같은 파일이 생성되어있는 것을 확인할 수 있습니다. 이 시간과 난수에 의해 생성 된 파일은 fluentd가 버퍼 된 로그입니다. 버퍼 된 로그는 time_slice_format에서 지정된 시간에서 time_slice_wait 경과 후 로그 파일에 출력됩니다.
| [root@localhost ~]# ls -l /var/log/fluent/ total 4 -rw-r--r-- 1 root root 328 Aug 15 21:45 myapp.201408152145.b500aa64c735d9d55 [root@localhost ~]# |
잠시 기다리면 로그 파일이 분당 생성되는 것을 확인할 수 있습니다.
| [root@localhost ~]# ls -l /var/log/fluent/ total 16 -rw-r--r-- 1 root root 410 Aug 15 21:46 myapp.201408152145_0.log -rw-r--r-- 1 root root 492 Aug 15 21:47 myapp.201408152146_0.log -rw-r--r-- 1 root root 492 Aug 15 21:48 myapp.201408152147_0.log -rw-r--r-- 1 root root 492 Aug 15 21:48 myapp.201408152148.b500aa6eeaf390608 [root@localhost ~]# |
out_forward (Buffered)
out_forward 로그를 MessagePack 의해 다른 서버에 전송하는 플러그인입니다. 내 개인적인 의견이지만, out_forward는 신뢰성과 에너지 자원의 밸런스, 확장 전략, 데이터 흐름 등 보람있는 설계가 가장 재미있는 플러그인이라고 생각합니다.
이 페이지에서는 out_forward을 가장 쉽게 테스트 할 수있는 설정 예를 소개합니다. 로그를 전송하는 측의 /etc/td-agent/td-agent.conf을 다음과 같이 편집하십시오.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <source> type exec command echo "the sky is falling in 100 seconds!" tag system.test keys message run_interval 10s </source> <match **> type forward buffer_type file buffer_path /var/log/fluent/myapp.*.buffer flush_interval 30s <server> name reciever.fluentd.example.com host XXX.XXX.XXX.XXX port 24224 </server> </match> |
로그를 수신하는 측의 /etc/td-agent/td-agent.conf을 다음과 같이 편집합니다.
| <source> type forward port 24224 </source> <match **> type stdout </match> |
td-agent 다시 시작하면 설정을 반영합니다.
| # /etc/init.d/td-agent restart |
out_forward 플러그인 로그 전송에 TCP를 사용하여 하트 비트 UDP를 사용합니다. TCP24224, UDP24224 모두 口開け하십시오. iptables의 설정 예는 다음과 같습니다.
| --- iptables.bak 2014-08-15 22:17:31.482946383 +0900 +++ iptables 2014-08-15 22:16:36.680931862 +0900 @@ -11,6 +11,8 @@ -A INPUT -p tcp --dport 22 -j LOG --log-prefix "dos detect ssh : " --log-level=info -A INPUT -p tcp --dport 22 -j DROP -A INPUT -p tcp --dport 80 -j ACCEPT +-A INPUT -p tcp --dport 24224 -j ACCEPT +-A INPUT -p udp --dport 24224 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT |
out_forward에 저장된 로그는 한 번 버퍼링됩니다. 기본 설정은 메모리에 버퍼링되지만 이번에는 작동 확인하기 쉽도록 파일에 버퍼하고 있습니다. 버퍼가 작성되는 디렉토리를 ls에서 관찰하면 버퍼링 된 로그를 확인할 수 있습니다.
| [root@localhost ~]# watch ls -l /var/log/fluent/ Every 2.0s: ls -l /var/log/fluent/ Fri Aug 15 22:33:44 2014 total 4 -rw-r--r-- 1 root root 104 Aug 15 22:33 myapp.system.test.b500ab1108f5f65dd.buffer |
로그를 수신하는 측의 /var/log/td-agent/td-agent.log을 표시하고 실제로 로그가 전송되는 것을 확인합니다.
| [root@locahost ~]# tail /var/log/td-agent/td-agent.log 2014-08-15 22:34:18 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} 2014-08-15 22:34:28 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} 2014-08-15 22:34:38 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} 2014-08-15 22:34:48 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} 2014-08-15 22:34:58 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} 2014-08-15 22:35:08 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} 2014-08-15 22:35:18 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} 2014-08-15 22:35:28 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} 2014-08-15 22:35:38 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} 2014-08-15 22:35:48 +0900 system.test: {"message":"the sky is falling in 100 seconds!"} |
로그 포맷
fluentd는 JSON 형식의 데이터 전송을하고, 결국 데이터 분석에 연결할 것을 목적으로하고 있습니다. 그러나 / var / log / messages 나 /var/log/httpd/access.log 같은 로그 파일은 JSON 형식으로되어 있지 않습니다.
fluentd는 in_tail과 in_exec 등의 Input 플러그인 로그를 읽을 때 JSON 형식으로 변환 할 수 있습니다.
로그 형식 - 정규식
in_tail 플러그인은 다음과 같이 format 매개 변수로 정규 표현식을 제공하여 로그를 JSON 형식으로 변환 할 수 있습니다. 또한 JSON으로 time이라는 key를 포함한 경우 time_format에서 지정한 시간 형식에 따라 로그를 시간순으로 정렬 기능이 존재합니다.
| <source> type tail path /var/log/httpd/access_log pos_file /var/log/td-agent/httpd-access.log.pos tag apache.access format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/ time_format %d/%b/%Y:%H:%M:%S %z </source> |
자주 사용하는 로그 파일에 대해서는 format 지정에 대한 alias가 정의되어 있습니다. 예를 들어, / var / log / messages에 대한 format 지정은 다음과 같이 "format syslog"로 표기 할 수 있습니다.
| <source> type tail path /var/log/messages pos_file /var/log/td-agent/syslog-messages.log.pos tag syslog.messages format syslog </source> |
format 지정으로 사용 가능한 alias는 fluentd 공식 문서를 참조해도 좋지만, 거동이 아무래도 이상하다고 느꼈을 때는 소스 코드를 쫓아 보자. 지정 가능한 alias는 /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/parser.rb에 기재되어 있습니다.
| TEMPLATE_REGISTRY = Registry.new(:config_type, 'fluent/plugin/parser_') { 'apache' => Proc.new { RegexpParser.new(/^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/, {'time_format'=>"%d/%b/%Y:%H:%M:%S %z"}) }, 'apache2' => Proc.new { ApacheParser.new }, 'syslog' => Proc.new { RegexpParser.new(/^(?<time>[^ ]*\s*[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?[^\:]*\: *(?<message>.*)$/, {'time_format'=>"%b %d %H:%M:%S"}) }, 'json' => Proc.new { JSONParser.new }, 'tsv' => Proc.new { TSVParser.new }, 'ltsv' => Proc.new { LabeledTSVParser.new }, 'csv' => Proc.new { CSVParser.new }, 'nginx' => Proc.new { RegexpParser.new(/^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/, {'time_format'=>"%d/%b/%Y:%H:%M:%S %z"}) }, 'none' => Proc.new { NoneParser.new }, 'multiline' => Proc.new { MultilineParser.new }, }.each { |name, factory| TEMPLATE_REGISTRY.register(name, factory) } |
그러면 실제로 format 지정에 의한 JSON 화의 동작 확인을 해 봅시다. 설정 예는 다음과 같습니다. 또한 다음의 설정 예제가 작동하는 것은 apache 로그 형식이 기본 설정의 경우입니다. 로그 포맷을 변경하는 경우 정규식을 적절히 변경해야합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <source> type tail path /var/log/httpd/access_log pos_file /var/log/td-agent/httpd-access.log.pos tag apache.access format apache2 </source> <source> type tail path /var/log/messages pos_file /var/log/td-agent/syslog-messages.log.pos tag syslog.messages format syslog </source> <match **> type stdout </match> |
td-agent 다시 시작하면 설정을 반영합니다.
| # /etc/init.d/td-agent restart |
/var/log/td-agent/td-agent.log를 표시하고 로그를 JSON 형식으로 변환 된 것을 확인합니다.
| [root@localhost ~]# tail /var/log/td-agent/td-agent.log | grep apache\.access 2014-08-16 00:50:09 +0900 apache.access: {"host":"localhost","user":null,"method":"GET","path":"/server-status?auto","code":200,"size":437,"referer":null,"agent":"munin/2.0.21 (libwww-perl/5.833)"} 2014-08-16 00:50:17 +0900 apache.access: {"host":"localhost","user":null,"method":"GET","path":"/server-status?auto","code":200,"size":432,"referer":null,"agent":"munin/2.0.21 (libwww-perl/5.833)"} 2014-08-16 00:51:38 +0900 apache.access: {"host":"133.242.169.96","user":null,"method":"GET","path":"/posts/cisco_routing_ospf_lsa_multi_area/topology.net","code":404,"size":8759,"referer":null,"agent":"Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"} 2014-08-16 00:53:56 +0900 apache.access: {"host":"133.242.169.96","user":null,"method":"GET","path":"/wp-content/uploads/2014/07/cacti_linux_server_002.png","code":200,"size":57363,"referer":null,"agent":"Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"} 2014-08-16 00:55:02 +0900 apache.access: {"host":"localhost","user":null,"method":"GET","path":"/server-status?auto","code":200,"size":435,"referer":null,"agent":"munin/2.0.21 (libwww-perl/5.833)"} 2014-08-16 00:55:08 +0900 apache.access: {"host":"localhost","user":null,"method":"GET","path":"/server-status?auto","code":200,"size":437,"referer":null,"agent":"munin/2.0.21 (libwww-perl/5.833)"} [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# tail /var/log/td-agent/td-agent.log | grep syslog\.messages 2014-08-16 00:56:31 +0900 syslog.messages: {"host":"localhost","ident":"kernel","message":"ip_tables: (C) 2000-2006 Netfilter Core Team"} 2014-08-16 00:56:31 +0900 syslog.messages: {"host":"localhost","ident":"kernel","message":"nf_conntrack version 0.5.0 (16384 buckets, 65536 max)"} 2014-08-16 00:56:31 +0900 syslog.messages: {"host":"localhost","ident":"kernel","message":"dos detect ssh : IN=eth0 OUT= MAC=52:54:0a:00:93:22:00:24:38:9b:18:00:08:00 SRC=106.130.93.7 DST=133.242.169.96 LEN=40 TOS=0x00 PREC=0x00 TTL=114 ID=21069 DF PROTO=TCP SPT=50000 DPT=22 WINDOW=3884 RES=0x00 ACK URGP=0 "} [root@localhost ~]# |
로그 포맷 - 로그 정규화 배웅 (none)
로그 출력 형식의 사양을 결정할 수없는 일도 있을지도 모릅니다. 또한 로그의 형식을 결정하기 전에 우선 로그를 축적하고 싶다는 요구가 있을지도 모릅니다.
그런 경우는 format none으로 지정하여 우선 로깅을 할 수 있습니다. 또한 / var / log / httpd / error_log처럼, PHP 등의 디버그 로그가 출력되는 같은 항상 틀에 박힌 형식이 아닌 로그를 수집 할 때는 none 지정 매우 효과적인 수단입니다.
"format none"설정 예는 다음과 같습니다. /etc/td-agent/td-agent.conf을 다음과 같이 편집합니다.
| <source> type tail path /var/log/secure pos_file /var/log/td-agent/syslog-secure.log.pos tag syslog.secure format none </source> <match **> type stdout </match> |
td-agent 다시 시작하면 설정을 반영합니다.
| # /etc/init.d/td-agent restart |
/var/log/td-agent/td-agent.log를 표시합니다. "message"라는 key에 대한 value로 로그 메시지가 저장되는 것을 확인할 수 있습니다.
| [root@localhost ~]# tail /var/log/td-agent/td-agent.log 2014-08-16 01:03:28 +0900 [info]: adding source type="tail" 2014-08-16 01:03:28 +0900 [info]: adding match pattern="**.secure" type="stdout" 2014-08-16 01:03:28 +0900 [info]: following tail of /var/log/httpd/access_log 2014-08-16 01:03:28 +0900 [info]: following tail of /var/log/messages 2014-08-16 01:03:28 +0900 [info]: following tail of /var/log/secure 2014-08-16 01:03:28 +0900 syslog.secure: {"message":"Aug 16 01:03:28 localhost runuser: pam_unix(runuser:session): session closed for user root"} 2014-08-16 01:03:34 +0900 syslog.secure: {"message":"Aug 16 01:03:34 localhost sshd[21369]: Connection closed by 133.242.169.96"} 2014-08-16 01:03:35 +0900 syslog.secure: {"message":"Aug 16 01:03:35 localhost su: pam_unix(su-l:session): session opened for user mysql by suzuki(uid=0)"} 2014-08-16 01:03:37 +0900 syslog.secure: {"message":"Aug 16 01:03:37 localhost su: pam_unix(su-l:session): session closed for user mysql"} |
로그 포맷 - tsv, csv, ltsv
로그를 미리 tsv, scv, ltsv 같은 형식으로 출력하는 것으로, 쉽게 JSON 형식으로 변환 할 수 있습니다. 가장 다루기 쉽고 추천하는 것은 콜론과 탭으로 구분 된 ltsv라는 형식입니다.
ltsv을 사용하려면 미리 애플리케이션 및 미들웨어 측 로깅을 LTSV 형식으로해야합니다. 예를 들어, nginx의 경우라면 다음과 같은 설정됩니다.
| log_format ltsv 'time:$time_local\t' 'msec:$msec\t' 'host:$remote_addr\t' 'forwardedfor:$http_x_forwarded_for\t' 'req:$request\t' 'method:$request_method\t' 'uri:$request_uri\t' 'status:$status\t' 'size:$body_bytes_sent\t' 'referer:$http_referer\t' 'ua:$http_user_agent\t' 'reqtime:$request_time\t' 'upsttime:$upstream_response_time\t' 'cache:$upstream_http_x_cache\t' 'runtime:$upstream_http_x_runtime\t' 'vhost:$host'; |
apache라면 다음과 같은 설정됩니다.
| LogFormat "time:%t\tforwardedfor:%{X-Forwarded-For}i\thost:%h\treq:%r\tstatus:%>s\tsize:%b\treferer:%{Referer}i\tua:%{User-Agent}i\treqtime_microsec:%D\tcache:%{X-Cache}o\truntime:%{X-Runtime}o\tvhost:%{Host}i" ltsv |
LTSV에 해당하는 td-agent.conf의 설정은 다음과 같습니다. LTSV 속에 time이라는 필드가 포함 된 경우 time_format의 설정이 필요하다는 점에 유의하십시오.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <source> type tail path /var/log/httpd/access_log pos_file /var/log/td-agent/apache-access.log.pos time_format [%d/%b/%Y:%H:%M:%S %z] tag apache.access format ltsv </source> <source> type tail path /var/log/nginx/access.log pos_file /var/log/td-agent/nginx-access.log.pos time_format %d/%b/%Y:%H:%M:%S %z tag nginx.access format ltsv </source> |
td-agent 다시 시작하면 설정을 반영합니다.
| # /etc/init.d/td-agent restart |
/var/log/td-agent/td-agent.log를 표시하고 로그를 JSON 형식으로 변환 된 것을 확인합니다.
| [root@localhost ~]# tail -f /var/log/td-agent/td-agent.log 2014-08-16 01:22:03 +0900 [info]: adding source type="tail" 2014-08-16 01:22:03 +0900 [info]: adding source type="tail" 2014-08-16 01:22:03 +0900 [info]: adding match pattern="nginx.access" type="stdout" 2014-08-16 01:22:03 +0900 [info]: following tail of /var/log/nginx/access.log 2014-08-16 01:22:27 +0900 nginx.access: {"msec":"1408119747.865","host":"133.242.169.96","forwardedfor":"-","req":"HEAD /munin/ HTTP/1.1","method":"HEAD","uri":"/munin/","status":"200","size":"0","referer":"-","ua":"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2","reqtime":"0.001","upsttime":"0.001","cache":"-","runtime":"-","vhost":"changineer.info"} |
fluentd (td-agent) 모니터링
프로세스 모니터링 포트 모니터링
감시의 필수품, 프로세스 모니터링 및 포트 모니터링 방법에 대해 설명합니다.
td-agent 프로세스는 다음과 같이 2 개의 상승합니다. 한쪽 부모 프로세스에서 다른 자식 프로세스입니다. "/ usr / sbin / td-agent"라는 프로세스가 2 개 존재하는 것을 확인하는 것이 좋습니다.
| [root@localhost ~]# ps aux | grep td-agent root 8240 0.0 0.9 217220 18508 ? Sl 02:13 0:00 /usr/lib64/fluent/ruby/bin/ruby /usr/sbin/td-agent --group root --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid root 8243 0.2 1.7 283368 33376 ? Sl 02:13 2:52 /usr/lib64/fluent/ruby/bin/ruby /usr/sbin/td-agent --group root --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid root 22432 0.0 0.0 103252 836 pts/1 S+ 22:26 0:00 grep td-agent |
포트 모니터는 어떤 Input Plugin을 사용하는지에 따라 감시하는 포트가 다릅니다. 많은 경우 in_http가 사용하는 TCP8888 또는 in_forward가 사용하는 TCP24224을 이용하면 좋을 것입니다. 만약 모니터링 할 수있는 포트가 존재하지 않는다면, 감시 목적을 위해 Input Plugin을 추가해도 좋을지도 모릅니다.
| [root@localhost ~]# netstat -anop | grep ruby | grep LISTEN tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN 23454/ruby off (0.00/0/0) [root@localhost ~]# |
버퍼 넘치는 (buffer_queue_limit, buffer_chunk_limit)
fluentd 로그 넘쳐하지 않도록 버퍼링하는 기능을 제공합니다. 아무리 도구 측이 신경을 듣지 구현을 가졌다해도 적절한 버퍼 설정과 버퍼 모니터링이 이루어지지 않으면 의미가 없습니다.
어느 정도의 로그 버퍼되고 있는지 조사하려면 monitor_agent라는 Input Plugin을 이용합니다. 이 감시 용 플러그인을 사용하려면 / etc / td-agent / td-agent.conf 다음을 가필 해주세요.
| <source> type monitor_agent bind 0.0.0.0 port 24220 </source> |
monitor_agent 모니터링 결과를 JSON 형식으로 반환합니다. 운용 담당자가 터미널 소프트 너머에서 JSON을 육안으로 읽을 것은 꽤 괴로운 것이 있습니다. 그래서 추천하는 것이 jq라는 명령 줄 JSON 파서입니다. 다음과 같이 yum 명령 jq를 설치합니다.
"http://127.0.0.1:24220/api/plugins.json"에 HTTP 요청을 보내면, buffer_total_queued_size, buffer_queue_length를 조사 할 수 있습니다. 이 값을 통합 모니터링 도구를 통해 취득하도록하면 버퍼 넘치는를 사전에 감지 할 수 있습니다.
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 | [root@localhost ~]# curl http://127.0.0.1:24220/api/plugins.json | jq "." % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 116 698 116 698 0 0 98k 0 --:--:-- --:--:-- --:--:-- 113k { <omitted> { "config": { "flush_interval": "30s", "buffer_chunk_limit": "8m", "buffer_queue_limit": "64", "buffer_path": "/var/log/fluent/myapp.*.buffer", "buffer_type": "file", "type": "forward" }, "retry_count": 2, "buffer_total_queued_size": 12319, "buffer_queue_length": 10, "output_plugin": true, "type": "forward", "plugin_id": "object:3f9fb8c5cc94" } ] } [root@localhost ~]# |
로그 모니터링 (로그 폭주 감시)
fluentd (td-agent)는 어떠한 에러가 발생하면 대량의 로그를 출력하는 안타까운 도구입니다. fluentd의 구조 자체가 특정 작업을 루프로 돌리는 구조로되어 있기 때문에, 이번 개선은 기대할 수없고 운용에서 커버하지 않을 수없는 문제입니다.
내가 경험 한 히아리핫토 사례는 10 분에서 1G 이상의 로그를 토해내 상태가되어 버렸습니다. 이 같은 상태가되어 버린다 디스크 용량 모니터링은 감지 할 수없는 일도 있을지도 모릅니다.
또한 어떤 예기치 않은 오류를 감지하는 의미에서 / var / log / td-agent / td-agent.log의 "[error]"문자열을 감시하면 좋을 것입니다. 덧붙여서, 오류가 대량으로 출력되는 로그 출력의 예는 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | [root@localhost ~]# tail -n 20 /var/log/td-agent/td-agent.log 2014-08-16 23:07:23 +0900 [error]: Permission denied - /var/log/messages 2014-08-16 23:07:23 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:549:in `initialize' 2014-08-16 23:07:23 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:549:in `open' 2014-08-16 23:07:23 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:549:in `on_notify' 2014-08-16 23:07:23 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:341:in `on_notify' 2014-08-16 23:07:23 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:427:in `call' 2014-08-16 23:07:23 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:427:in `on_timer' 2014-08-16 23:07:23 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/cool.io-1.1.1/lib/cool.io/loop.rb:96:in `run_once' 2014-08-16 23:07:23 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/cool.io-1.1.1/lib/cool.io/loop.rb:96:in `run' 2014-08-16 23:07:23 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:212:in `run' 2014-08-16 23:07:24 +0900 [error]: Permission denied - /var/log/messages 2014-08-16 23:07:24 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:549:in `initialize' 2014-08-16 23:07:24 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:549:in `open' 2014-08-16 23:07:24 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:549:in `on_notify' 2014-08-16 23:07:24 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:341:in `on_notify' 2014-08-16 23:07:24 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:427:in `call' 2014-08-16 23:07:24 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:427:in `on_timer' 2014-08-16 23:07:24 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/cool.io-1.1.1/lib/cool.io/loop.rb:96:in `run_once' 2014-08-16 23:07:24 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/cool.io-1.1.1/lib/cool.io/loop.rb:96:in `run' 2014-08-16 23:07:24 +0900 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/in_tail.rb:212:in `run' |
thread 중단
"thread 중단"레어 케이스이지만, 이것이 fluentd을 운용하고 있던 때의 가장 큰 고민이었습니다. fluentd는 특정 thread가 중단 버리는 일이 있습니다. 이것이 일어나 버리면, 프로세스 모니터링에 성공적으로 보여도 왠지 로그가 전송되지 않는 자체가되어 버립니다.
실제로 경험 한 실패 사례이지만, 프로세스 모니터링 정상도 in_http 통해 입력 된 로그 만 분실하는 사례가 발생했습니다.
thread 중단에 대한 방어는 지금까지 좋은 아이디어가 없습니다.
- 모니터링 로그를 정기적으로 보내 로그가 예상대로 전송되는 것을 확인한다.
- thread 중단시 로그 출력을 감시하도록한다.
같은 착상 수준의 방어라면 말할 수 있지만 정직 운영으로 도는 여부는 알 수 없습니다.
Tips
td-agent.conf 구문 검사
td-agent에 인수 -dry-run 옵션을 전달하거나 시작 스크립트에 인수 configtest를 전달하여 td-agent.conf의 구문을 검사 할 수 있습니다. td-agent.conf 설정 반영을 위해 다시 시작하기 전에 한 번 구문 검사를 실시 버릇을 붙여두면 좋을 것입니다.
| [root@localhost ~]# td-agent --dry-run 2014-07-27 01:29:43 +0900 [info]: reading config file path="/etc/td-agent/td-agent.conf" 2014-07-27 01:29:43 +0900 [error]: Dry run failed: parse error at td-agent.conf line 11 [root@localhost ~]# /etc/init.d/td-agent configtest 2014-07-27 01:32:23 +0900 [error]: Dry run failed: parse error at td-agent.conf line 11 [root@localhost ~]# |
td-agent2
fluentd (td-agent)는 ruby, gem 라이브러리의 하나로 볼 수 있습니다. 이라는 것은 불행히도 꽤 빠른 자주 ruby, gem 버전 업 대응에 직면하게 될 것입니다. td-agent의 첫 번째 버전 업 대응이 td-agent2입니다. td-agent2는 td-agent ruby, gem 등의 버전 업을 도모 한 패키지입니다. 구체적인 버전의 차이점은 다음 표를 참조하십시오.
| TD-AGENT-1.1.20 | TD-AGENT2-1.0.0 |
---|
ruby | 1.9.3p484 | 2.1.2p95 |
gem | 1.8.23 | 2.2.2 |
td-agent2는 2014/05/19에 출시 된 아직 시들지 않은 버전입니다. td-agent2을 프로덕션 환경에 넣으려면 제물이 될 각오가 필요 하겠지요.
흔히 볼 오류 메시지
argument out of range
/var/log/td-agent/td-agent.log 오류 메시지로 error = "argument out of range"가 출력되는 일이 있습니다. 이것은 "time_format"지정 누출이 원인 일 경우가 많습니다.
fluentd 로그 포맷 기능은 "time"라는 key가있는 경우 time_format의 형식에 따라 시간을 해석하고 시간순으로 로그를 정렬 기능이 있습니다. 만약 time_format의 지정이없는 경우 다음과 같은 오류 메시지가 출력되며, 로그 전송되지 않습니다.
| [root@localhost ~]# tail -f /var/log/td-agent/td-agent.log 2014-08-16 00:02:53 +0900 [info]: adding source type="tail" 2014-08-16 00:02:53 +0900 [info]: adding match pattern="**" type="stdout" 2014-08-16 00:02:53 +0900 [info]: following tail of /var/log/httpd/access_log 2014-08-16 00:03:11 +0900 [warn]: "133.242.169.96 - - [16/Aug/2014:00:03:11 +0900] \"GET /munin/ HTTP/1.0\" 200 7932 \"-\" \"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2\"" error="argument out of range" 2014-08-16 00:03:11 +0900 fluent.warn: {"error":"argument out of range","message":"\"133.242.169.96 - - [16/Aug/2014:00:03:11 +0900] \\\"GET /munin/ HTTP/1.0\\\" 200 7932 \\\"-\\\" \\\"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2\\\"\" error=\"argument out of range\""} |
/etc/td-agent/td-agent.conf 수정 예는 다음과 같습니다.
| --- td-agent.conf.bak 2014-08-16 00:10:59.735486289 +0900 +++ td-agent.conf 2014-08-16 00:03:42.342319165 +0900 @@ -4,6 +4,7 @@ pos_file /var/log/td-agent/httpd-access.log.pos tag apache.access format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/ + time_format %d/%b/%Y:%H:%M:%S %z </source> |
no nodes are available
"no nodes are available"는 로그 대상 호스트가 다운되는 것을 나타내는 로그입니다. 운영 단계에 들어가있는 경우는 로그 통합 서버 측의 장애를 의심해야하지만 초기 구축 단계에서이 로그를 볼 수있는 로그 전송하는 서버 간의 소통 불능을 나타내는 것이 많습니다.
fluentd 로그 전송로 TCP 24224을 사용하여 하트 비트로서 UDP 24224를 사용하는 것에주의가 필요합니다. 자주있는 패턴이 UDP 24224 개방 누출입니다.
실제로 "no nodes are available"이 출력되는 예는 다음과 같습니다.
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 | [root@localhost ~]# tail -f /var/log/td-agent/td-agent.log </server> <secondary> type file path /var/log/fluent/forward-failed </secondary> </match> </ROOT> 2014-08-16 01:35:05 +0900 [info]: adding source type="exec" 2014-08-16 01:35:05 +0900 [info]: adding match pattern="**" type="forward" 2014-08-16 01:35:05 +0900 [info]: adding forwarding server 'reciever.fluentd.example.com' host="133.242.152.145" port=24224 weight=60 2014-08-16 01:35:42 +0900 [warn]: detached forwarding server 'reciever.fluentd.example.com' host="133.242.152.145" port=24224 phi=16.228779167689286 2014-08-16 01:36:24 +0900 [warn]: temporarily failed to flush the buffer. next_retry=2014-08-16 01:35:06 +0900 error_class="Errno::ETIMEDOUT" error="Connection timed out - connect(2)" instance=70275415944340 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/out_forward.rb:262:in `initialize' 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/out_forward.rb:262:in `new' 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/out_forward.rb:262:in `connect' 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/out_forward.rb:224:in `send_data' 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/out_forward.rb:144:in `block in write_objects' 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/out_forward.rb:138:in `times' 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/plugin/out_forward.rb:138:in `write_objects' 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/output.rb:449:in `write' 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/buffer.rb:296:in `write_chunk' 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/buffer.rb:276:in `pop' 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/output.rb:310:in `try_flush' 2014-08-16 01:36:24 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/output.rb:132:in `run' 2014-08-16 01:36:24 +0900 [warn]: temporarily failed to flush the buffer. next_retry=2014-08-16 01:35:09 +0900 error_class="RuntimeError" error="no nodes are available" instance=70275415944340 |
no patterns matched tag
/var/log/td-agent/td-agent.log에 no patterns matched tag가 나타날 수 있습니다. 이것은 Output Plugin에 지정된 태그와 일치하지 않고 파기되어 버렸다 로그가 존재한다는 것을 의미합니다.
| [root@localhost ~]# tail -f /var/log/td-agent/td-agent.log </server> </match> </ROOT> 2014-08-16 01:51:09 +0900 [info]: adding source type="tail" 2014-08-16 01:51:09 +0900 [info]: adding match pattern="pattern" type="forward" 2014-08-16 01:51:09 +0900 [info]: adding forwarding server 'reciever.fluentd.example.com' host="133.242.152.145" port=24224 weight=60 2014-08-16 01:51:09 +0900 [info]: following tail of /var/log/messages 2014-08-16 01:51:27 +0900 [warn]: no patterns matched tag="syslog.messages" 2014-08-16 01:51:27 +0900 [warn]: no patterns matched tag="syslog.messages" 2014-08-16 01:51:29 +0900 [warn]: no patterns matched tag="syslog.messages" |
예를 들어, / etc / td-agent / td-agent.conf에서 <match **>이라고 써야 곳을 <match *>라고 써 버리면, / var / log / td-agent / td-agent.log에 no patterns matched tag로 출력되어 버립니다.
| --- /etc/td-agent/td-agent.conf 2014-08-16 01:52:46.426665110 +0900 +++ td-agent.conf 2014-08-16 01:53:01.518662987 +0900 @@ -6,7 +6,7 @@ format syslog </source> -<match *> +<match **> type forward buffer_type file buffer_path /var/log/fluent/myapp.*.buffer |
'pos_file PATH'parameter is not set to a 'tail'source
td-agent 다시 시작할 때 'pos_file PATH'parameter is not set to a 'tail'source. this parameter is highly recommended to save the position to resume tailing. 그리고 나타날 수 있습니다. 말 그대로 in_tail 플러그인 pos_file 매개 변수는 권장되고 있습니다. 이 매개 변수가 존재하지 않으면 td-agent 다시 시작할 때 로그가 2 배에서로드되어 버리는 등의 불편 함이 발생하게됩니다.
| [root@localhost ~]# /etc/init.d/td-agent restart 2014-08-16 01:48:11 +0900 [warn]: 'pos_file PATH' parameter is not set to a 'tail' source. 2014-08-16 01:48:11 +0900 [warn]: this parameter is highly recommended to save the position to resume tailing. Shutting down td-agent: [ OK ] Starting td-agent: [ OK ] [root@localhost ~]# |
/etc/td-agent/td-agent.conf 수정 예는 다음과 같습니다.
| --- td-agent.conf 2014-08-16 01:50:08.478687899 +0900 +++ /etc/td-agent/td-agent.conf 2014-08-16 01:48:24.686703405 +0900 @@ -1,6 +1,7 @@ <source> type tail path /var/log/messages + pos_file /var/log/td-agent/syslog-messages.log.pos tag syslog.messages format syslog </source> |
Fluent :: BufferQueueLimitError : queue size exceeds limit
Fluent :: BufferQueueLimitError : queue size exceeds limit는 out_forward 플러그인을 사용하는 과정에서 buffer_queue_limit에 지정된 큐에서 흘러 버린 것을 의미합니다.
일단 큐 넘치는이 발생하면 단순히 로구로스토으로 이어질뿐만 아니라, 로그 전송 자체가 멈춰 버리기 때문에 한번 td-agent를 다시 시작하는 것이 좋습니다.
| [root@vps096 ~]# tail -f /var/log/td-agent/td-agent.log 2014-08-16 02:02:56 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize' 2014-08-16 02:02:56 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/buffer.rb:168:in `emit' 2014-08-16 02:02:56 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/output.rb:426:in `emit' 2014-08-16 02:02:56 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/match.rb:36:in `emit' 2014-08-16 02:02:56 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/engine.rb:154:in `emit_stream' 2014-08-16 02:02:56 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/engine.rb:134:in `emit' 2014-08-16 02:02:56 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/engine.rb:197:in `block in log_event_loop' 2014-08-16 02:02:56 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/engine.rb:195:in `each' 2014-08-16 02:02:56 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.50/lib/fluent/engine.rb:195:in `log_event_loop' 2014-08-16 02:02:56 +0900 [error]: failed to emit fluentd's log event tag="fluent.warn" event={"error_class"=>"Fluent::BufferQueueLimitError", "error"=>"#<Fluent::BufferQueueLimitError: queue size exceeds limit>", "message"=>"emit transaction failed error_class=Fluent::BufferQueueLimitError error=#<Fluent::BufferQueueLimitError: queue size exceeds limit>"} error_class=Fluent::BufferQueueLimitError error=#<Fluent::BufferQueueLimitError: queue size exceeds limit> |
Size of the emitted data exceeds buffer_chunk_limit.
Size of the emitted data exceeds buffer_chunk_limit.는 out_forward 플러그인을 사용하는 과정에서 buffer_chunk_limit에서 지정한 chunk에서 흘러 버린 것을 의미합니다.
| 2014-08-16 02:18:30 +0900 [warn]: Size of the emitted data exceeds buffer_chunk_limit. 2014-08-16 02:18:30 +0900 [warn]: This may occur problems in the output plugins ``at this server.`` 2014-08-16 02:18:30 +0900 [warn]: To avoid problems, set a smaller number to the buffer_chunk_limit |
/etc/td-agent/td-agent.conf을 편집하고 buffer_chunk_limit을 큼직한 값으로 설정합니다. 설정 예는 다음과 같습니다.
| diff --git a/td-agent/td-agent.conf b/td-agent/td-agent.conf index 75cd49b..b125ea7 100644 --- a/td-agent/td-agent.conf +++ b/td-agent/td-agent.conf @@ -17,7 +17,7 @@ buffer_type file buffer_path /var/log/fluent/myapp.*.buffer buffer_queue_limit 64 - buffer_chunk_limit 8m + buffer_chunk_limit 32m flush_interval 30s <server> |
LTSV의 취급 방법
LTSV은 apache와 nginx의 기본 형식과 다르지만 LTSV는 익숙해지면 매우 편리합니다.
apache의 기본 설정은 구분 문자열이 비어 있기 때문에 awk에서 추출 될 때 예상치 못한 장소에서 구분되는 일이 자주 있습니다. 그러나 LTSV은 탭으로 구분되어 있기 때문에 기본 설정에 비하면 예상치 못한의 구분 방법이 될 것은 적습니다.
예를 들어, 사용자 에이전트의 추출이라면 다음과 같이합니다. 기본 설정 access_log에 비해 훨씬 쉽게 awk 할 수 있습니다.
| [root@localhost ~]# tail -f /var/log/httpd/access_log | awk -F"\t" '{print $8}' ; ua:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36 ua:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36 ua:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36 ua:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36 ua:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36 ua:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36 ua:Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) ua:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ) ua:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36 ua:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36 |
사용자 에이전트 상위 5 건 등의 집계 작업도 이렇게 간단합니다.
| [root@localhost ~]# grep -v bot /var/log/httpd/access_log | awk -F"\t" '{print $8}' | uniq -c | sort -nr | head -n 5 33 ua:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36 25 ua:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36 19 ua:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729) 16 ua:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24 16 ua:Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko |
또한 LTSV 전용 파서를 사용하면 더 쉽게 집계 할 수 있습니다. 다음은 ltsview는 ruby gem에서 제공하는 LTSV 파서의 출력 예입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [root@localhost ~]# tail -n 20 /var/log/httpd/access_log | ltsview -k req -r req:/server/ --- :req: GET /server/monitoring/monitoring_snmptrapd.html HTTP/1.0 --- :req: GET /server/server_hardware_management/server_hardware_megaraid_web_bios.html HTTP/1.0 --- :req: GET /server/monitoring/monitoring_munin.html HTTP/1.0 --- :req: GET /server/logging/fluentd-td-agent.html HTTP/1.0 --- :req: GET /server/mysql/mysql_installation_linux.html HTTP/1.0 --- :req: GET /server/mysql_client/cse_mysql.html HTTP/1.0 --- :req: GET /server/monitoring/monitoring_snmp.html HTTP/1.0 --- :req: GET /server/mysql_client/cse_mysql.html HTTP/1.0 --- :req: POST /server/mysql/mysql_installation_linux.html HTTP/1.0 |
LTSV 파서는 여러 가지가 있습니다. 아마 모든 LTSV 파서가 오랜 기간 유지되는 일은 없을 것입니다. 즉, LTSV 파서를 사용하여 집계 운용을 돌리는 것은 유지 보수 종료의 위험을 충분히 고려해야합니다 .
만약, 유지 보수 종료의 위험을 싫어한다면, 시든 언어의 한 라이너 집계를 건다는 방법도 있습니다. DQNEO 기업 일기 LTSV 로그를 해석하는 최강의 원 라이너 집 에서는 다음과 같은 perl에 의한 한 라이너 구현 예가 소개되어 있습니다. 이렇게 perl을 사용하면 ruby 버전 업 OS 버전 업마다 부들 부들하지 않아도 될 것입니다.
| cat accesslog | perl -F'\t' -nale '%h=map{split/:/,$_,2}@F;print"$h{time}\t$h{ua}"' |
테스트 환경
Linux에서 테스트 환경은 다음과 같습니다.
- 마지막 동작 확인 일 : 2014/01/19
- CentOS 6.6 (Sakura VPS), Redhat 6.5 (AWS : Amazon Web Service)
- td-agent-1.1.21-0.x86_64