레이블이 log인 게시물을 표시합니다. 모든 게시물 표시
레이블이 log인 게시물을 표시합니다. 모든 게시물 표시

observability data pipeline - vector

# kubernetes(k8s) pods stdout,stderr 는 노드의 다음에 경로에 저장된다.
/var/log/pods
/var/log/containers (pods 하위 컨테이너 로그 파일들이 이곳에 링크로 걸려 있음)

# 이런 pod 로그들을 예전에는 fluentd 에서 정재 -> es / kafka 로 보냈는데,
# 요즘에는 fluentd 대신 vector(observability data pipeline - agent & aggregator) 를 많이 사용하는것 같다.
# rust 로 만들어서인지 안정성과 성능이 좋은것 같다. 

# helm 으로 설치
helm repo add vector https://helm.vector.dev
helm repo update

# helm value 설정
# vector 는 다음 3가지 형태(role)로 배포 할 수 있다.
# agent: daemonset 으로 모든 노드의 data(stdout)를 수집
# sidecar: 파드별 pod에 사이드카로 vector 를 띄워 pod에 대해서만 수집
# aggregator: 다른 스트림으로 부터 입력(수집) 
# customConfig 로 디폴트 설정을 대신할 수 있다.
# configmap > data 설정된다.
# kubernetes_logs,host_metrics,internal_metrics(source) -> transform -> prometheus_exporter,console(sink) 로 소비하는 흐름
cat << zzz > values.yaml
role: Agent
customConfig:
  data_dir: /vector-data-dir
  api:
    enabled: true
    address: 127.0.0.1:8686
    playground: false
  sources:
    kubernetes_logs:
      type: kubernetes_logs
    host_metrics:
      filesystem:
        devices:
          excludes: [binfmt_misc]
        filesystems:
          excludes: [binfmt_misc]
        mountpoints:
          excludes: ["*/proc/sys/fs/binfmt_misc"]
      type: host_metrics
    internal_metrics:
      type: internal_metrics
  sinks:
    prom_exporter:
      type: prometheus_exporter
      inputs: [host_metrics, internal_metrics]
      address: 0.0.0.0:9090
    stdout:
      type: console
      inputs: [kubernetes_logs]
      encoding:
        codec: json
zzz

# 설치 하면 Agent 면 daemonset 으로 worker/ingress 노드들에 vector pod 가 설치된다.
helm install vector vector/vector --namespace vector --create-namespace --values values.yaml

# vector 버전업 반영시
helm repo update
helm upgrade vector vector/vector --namespace vector --values values.yaml

# vector 삭제시
helm uninstall vector --namespace vector

# vector 처리 현황 보기
kubectl -n vector exec -it daemonset/vector -- vector top --url http://127.0.0.1:8686/graphql

# k8s log -> filter -> remap -> kafka,elasticsearch,console 로 보내는 경우
# console 은 vector pod log 에서 확인
# vi values.yaml
role: Agent
customConfig:
  data_dir: /vector-data-dir
  api:
    enabled: true
    address: 127.0.0.1:8686
    playground: false
  sources:
    k8s_log:
      type: kubernetes_logs
      # namespace 가 kube_system 아닌것 중 ysoftman 인 것만
      extra_field_selector: metadata.namespace=!kube_system,metadata.namespace=ysoftman
  transforms:
    k8s_transform1:
      type: filter
      inputs:
        - k8s_log
      condition: .level != "debug"
    k8s_transform2:
      type: remap
      inputs:
        - k8s_transform1
      source: |
        # % root of the event metadata
        # . root of the event
        # set es index name
        %custom_type = "sample"
        if .message == r'.*error.*' {
          # % root of the event metadata
          %custom_type = "error"
        }
  sinks:
    kafka_log:
      type: kafka
      inputs: [k8s_transform2]
      bootstrap_servers: logis-kafka-dev.daumtools.com:9092
      topic: kave-dev-sample
      encoding:
        codec: json
    es_log:
      type: elasticsearch
      inputs:
        - k8s_transform2
      endpoints:
        - http://ysoftman.es:9200
      bulk:
        index: "ysoftman-sample-%Y-%m-%d"
    console_log:
      type: console
      inputs: [k8s_transform2]
      encoding:
        codec: json

ssh 로그인 후 바로 종료 문제

# k8s pod 내에 sshd -D 를 기동 후
# 다음과 같이 ssh 연결을 하면 바로 연결이 close 된다.
ssh root@localhost -vvv

... 생략 ...
Last login: Sat Apr 29 07:38:26 2023 from 127.0.0.1
debug3: receive packet: type 96
debug2: channel 0: rcvd eof
... 생략 ...
Connection to localhost closed.
debug1: Exit status 255

# receive packet : type 96(SSH_MSG_CHANNEL_EOF)으로
# 보통 연결된 ssh 에서 exit/logout 하면 받는 패킷이다.

# lastlog(/var/log/lastlog) 로 마지막 로그를 봐도 로그인 된 흔적이 있다.
Username         Port     From             Latest
root             pts/3    127.0.0.1        Sat Apr 29 07:38:28 +0000 2023
... 생략 ...

# lastb(/var/log/btmp)로 실패한 로그인 기록은 보면 없다고 나오고
# last(/var/log/wtmp) | head -2 로 성공한 로그인 기록을 보면 내역에도 기록 되어 있다.
# 그런데 로그인 후 바로 로그아웃되었다.
root     pts/3        127.0.0.1        Sat Apr 29 07:38 - 07:38  (00:00)
root     pts/3        127.0.0.1        Sat Apr 29 07:38 - 07:38  (00:00)

# 혹시 root 기본 쉘을 확인해보면 bash 정상
cat /etc/passwd | grep groot
root:x:0:0:root:/root:/bin/bash

# ssh closed 시 verbose 내용에 255 종료상태가 있는것을 보고 
# 체크1
# 로그인시 ~/.profile, ~/.bashrc 를 rename 으로 로딩을 하지 않아도 closed 된다.

# 체크2
# root/.ssh/ 에 있는 environment 파일이 다른 정상 container 와 달리 꽤 커서 살펴봤다.
# pod(container)의 파일을 로컬로 복사
kubectl cp {namespace}/{pod_name_ssh_접속정상}:/root/.ssh/environment ./environment1
kubectl cp {namespace}/{pod_name_ssh_접속문제}:/root/.ssh/environment ./environment2

# environment1 파일은 500라인인데, environment2 파일은 1000라인이다.
# 문제가 있는 container /root/.ssh/environment 의 내용을 라인을 지워가면서 접속 여부를 확인해봤다.
# 확인결과 environment 내용에 상관없이 라인수를 991로 줄이면 접속이 성공한다.
# 접속시 너무 많은 environment 설정(현재 client 와 중복도 많이 되고 있었음) 문제였음...

k8s pod log tool stern

# stern 커맨드를 사용하면 k8s 의 n 개의 pod 로그를 한번에 볼수 있다.
# ysoftman 네임스페이스의 aaa 이름(정규표현 가능) 로그 보기
stern "aaa" -n ysoftman

# 전체 네임스페이스에서 aaa 이름(정규표현 가능) 로그 보기
stern "aaa" -A

# 전체 네임스페이스에서 aaa 이름(정규표현 가능) 로그 보기
# 로그 중 json 포맷만 보기, jq 로 포맷팅해서 보면 좋다.
stern "aaa" -A -o json | jq

docker log size per line

# 도커 로깅에서 stdout 한줄의 길이가 16K 로 제한되어 있다고 한다.
# 관련해서 설정을 변경하는 PR 있었지만 진행되지 않았음.

access log - get null 400 에러

# tomcat 에러 중 다음과 같이 path 부분이 null 이 찍히는 경우가 있다.
# 참고로 로그는 apache httpd mod_log_config 를 사용한다.
https://httpd.apache.org/docs/2.4/ko/mod/mod_log_config.html

# /var/lib/tomcat8/conf/server.xml 에서 로그 포맷 설정
# %{Foobar}i - Foobar 헤더
# %h - 원격 호스트
# %l - 원격 identid가 제공한 로그인명, 기본값(-)
# %u - 원격 auth가 제공한 사용자명, 기본값(-)
# %t - 표준 영어 시간
# %r - 요청 첫번째 줄
# %s - 상태코드
# %b - http 헤더를 제외한 전송 바이트 수
# %h %l %u %t "%r" %s %b 포맷

# tomcat access log 확인
sudo tail -f /var/log/tomcat8/localhost_access_log.2019-01-31.txt

# 브라우저에서 '아이유' 요청하면 URL 인코딩 되고 다음과 같이 정상 동작(로깅)
127.0.0.1 - - [31/Jan/2019:18:15:30 +0900] "GET /%EC%95%84%EC%9D%B4%EC%9C%A0 HTTP/1.1" 404 1110

# curl 로 다음처럼 한글이 URL인코딩 없이 요청하는 경우 null 로 되고
# tomcat server.xml 의 protocol 기본 설정이 HTTP/1.1 로 돼있어
# HTTP/1.0 을 사용해도 로그에 HTTP/1.1 로 기록된다.
curl "http://localhost:8080/아이유" --http1.0 -s > /dev/null

# path 가 null 로 되어 처리할 수 없게 된다.
127.0.0.1 - - [31/Jan/2019:18:15:30 +0900] "GET null HTTP/1.1" 400 800

# tomcat 에러 로그를 확인을 위해 모든 로그를 확인해보자.
sudo vi /var/lib/tomcat8/conf/logging.properties
java.util.logging.ConsoleHandler.level = ALL

# tomcat 재시작
sudo service tomcat8 restart

# 에러 로그를 확인해보면
sudo tail -f /var/log/tomcat8/catalina.out

java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986

# 관련 내용을 구글링 해보니 tomcat 7.0.73, 8.0.39, 8.5.7 이상에서 발생하고
# http connector 에 relaxedQueryChars 를 설정하라고 한다.
https://stackoverflow.com/questions/41053653/tomcat-8-is-not-able-to-handle-get-request-with-in-query-parameters

# tomcat 버전 확인하면 8.5.30.0 이다.
sudo bash /usr/share/tomcat8/bin/version.sh

# 다음과 같이 특수문자를 처리해봤지만 한글 utf8코드는 처리 되지 않았다.
sudo vi /var/lib/tomcat8/conf/server.xml

<Connector port="8080" protocol="HTTP/1.1"
                connectionTimeout="20000"
                redirectPort="8443" relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;" />

# relaxedQueryChars 특수문자는 명시할 수 있지만 non-alphabet 범위의 문자코드는 어떻게 명시할 방법이 없어, client 가 URL 인코딩을 해줘야 한다.

nginx rotate log

# 방법1
https://www.cambus.net/log-rotation-directly-within-nginx-configuration-file/
# 하지만 error.log 에는 적용이 안된다.
# nginx.conf 설정
if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})") {
    set $year $1;
    set $month $2;
    set $day $3;
    set $hour $4;
    set $minutes $5;
}
access_log /var/log/nginx/$year-$month-$day-$hour-$minutes-access.log;

# 방법2
https://www.nginx.com/resources/wiki/start/topics/examples/logrotation/
http://nginx.org/en/docs/control.html#logs
# USR1 시널을 사용해 로그 파일 모두 rotate 가능하다.
# 쉘 스크립트를 작성해서 크론잡으로 등록한다.
# 1시간 전의 시간으로 파일명 변경
mv access.log `date -d '1 hour ago' '+%Y-%m-%d-%H-%M'`-access.log

# nignx 마스터 프로세스에 USR1(file reopen) 시그널 보내기
kill -USR1 `cat master.nginx.pid`
sleep 1

# 로그레벨 참고 : debug, info, notice, warn, error, crit, alert, emerg
error_log logs/error.log 로그레벨;

# 방법3
# logrotate 사용(nginx 외 일반적인 로그들에 모두 사용 가능)
https://github.com/logrotate/logrotate
# centos logrotate 설치
yum install logrotate

# ubuntu(debian) logrotate 설치
apt-get install logrotate

# logrotate 는 cron 으로 실행 주기를 관리한다.
# logrotate 기본 설정
vi /etc/logrotate.conf

# 설정 파일들 위치 포함
include /etc/logrotate.d

# nginx logrotate 설정
vi /etc/logrotate.d/ysoftman_nginx

# /var/log/nginx/*.log 파일은
/var/log/nginx/ {
    # 매일 로그를 바꾼다. 매주는 weekly, 매월은 monthly
    daily

    # 4일 분량의 로그를 남긴다. weekly 라면 4일, monthly 라면 4월
    rotate 4

    # 로그 파일이 비워있으면 로테이션 하지 않는다.
    notifempty

    # 로그파일이 유실되더라고 에러를 발생시키지 않는다.
    missingok

    # 로테이션후 빈파일을 생성
    create

    # 로테이션된 파일의 suffix 로 날짜지정 (xxx.log-YYMMDD)
    dateext

    # 압축하기
    compress

    # 모든 로그파일에 대해서 postrotate 스크립트가 한번만 실행되도록(공유) 한다.
    sharedscripts

    # postrotate ~ endscript 사이에는 로테이션 후 실행될 쉘 스크립트 명시
    postrotate
       kill -USR1 `cat /home/ysoftman/nginx/master.nginx.pid`
    endscript 
}

# 테스트 해보기
# logrotate 는 로테이션 된 내역을 다음 파일로 기록한다.
# 여기에 기록된 파일들은 로테이션 되지 않는다.
# 테스트를 위해 logrotate 필요하다면 파일명 뒤에 있는 rotate 시간을 과거로 수정한다.
# 이파일은 삭제하더라도 logrotate 실행하면 다시 이전 상태로 복구되니 시간을 수정해야 한다.
cat /var/lib/logrotate/logrotate.status

# debug(실제 rotate 는 되지 않음)모드로 테스트
# 실행 작업 순서가 출력지만 실제 rotate 할때는 에러가 발생할 수 있다.
logrotate -d /etc/logrotate.d/ysoftman_nginx

# 실제 rotate 해보기
# compress 등 rotate 후의 작업이 실행이 되지 않았다면
# -v 로 postrotate 등의 스크립트 에러 메시지를 체크해 보자.
logrotate -v /etc/logrotate.d/ysoftman_nginx

apache httpd log rotation

Apache httpd 로그파일이 시간이 갈수록 커지는데 일정 시간/사이즈로 파일을 분리하여 관리 할 수 있다.(log rotation)
apache httpd rotatelogs 설명
https://httpd.apache.org/docs/2.4/ko/programs/rotatelogs.html

apache httpd 로그 설명
https://httpd.apache.org/docs/2.4/ko/logs.html

##########

# rotatelogs 를 사용하는 경우
# Apache httpd 에서는 rotatelogs 를 제공한다.
# 이를 이용하면 특정 시간/사이즈 마다 로그 파일을 분리(백업)할 수 있다.
vim httpd.conf

# 24시간마다 로그 파일 구분
CustomLog "|bin/rotatelogs /www/logs/accesslog 86400" common

# 5M 크기가 넘어서면 로그 파일 구분
ErrorLog "|bin/rotatelogs /www/logs/error%Y%m%d%H%M.log 5M"


##########

# cronolog 를 사용하는 경우
# cronolog 는 yymmdd 등의 템플릿 설정에 따라 로그 파일을 구분한다.
# 맥에서 설치
brew install cronolog

# centos 에서 설치
sudo yum install cronolog
vim httpd.conf

# 현재 시간으로 로그 파일 구분
CustomLog "|/usr/sbin/cronolog /www/logs/access%Y%m%d%H%M.log"

# 심볼릭 링크를 추가하는 경우
ErrorLog "|/usr/sbin/cronolog -S /www/logs/error.log /www/logs/error%Y%m%d%H%M.log"

웹 액세스 로그 시각화 툴 LogStalgia

apache, nginx 와 같은 웹 서버의 accesslog 를 visualization(시각화)해주는 툴이다.
윈도우, 리눅스, 맥 모두에서 동작한다. (콘솔환경은 안됨)
다운로드 http://logstalgia.io/

# 로그파일 기준으로 플레이(실행)
logstalgia access.log

# 실시간으로 시각화 하기
tail -f /var/log/apache2/access.log | logstalgia --sync

logstash 윈도우 서비스로 등록하기

logstash 를 윈도우 서비스로 등록하기 위해서 sc 를 사용한경우 서비스가 등록되지만 시작시 에러가 발생한다.

이럴땐 nssm 이라는 서비스 매니저 유틸리티를 사용하자.

다운로드 http://nssm.cc

nssm.exe 파일만 있으면된다.



[서비스 등록]

nssm.exe install logstash c:\logstash\bin\start-logstash.bat



[서비스 삭제]

nssm.exe remove logstash





[start-logstash.bat 내용]

@rem ysoftman

@rem logstash 윈도우 서비스로 등록하기

@rem set LS_MAX_MEM=256m

cd "c:\logstash\bin"

logstash.bat agent -f sendlog.conf



Linux 로그 보기

# 리눅스 로그 파일은 보통 /var/log 에 파일로 기록된다.
# 로그 파일은 스트링과  바이너리 형식이며 바이너리인 경우 last 명령으로 세부 기록 사항을 파악 할 수 있다.
# 로그인/로그아웃 기록
last -f /var/log/wtmp.1

# 현재 시스템을 사용하고 있는 사용자 기록
last -f /var/run/utmp

# 시스템 로그
last -f /var/log/syslog.1

# 시스템 이벤트 로그
vi /var/log/messages

# 부팅시 로그(-e 이벤트 실제 날짜로 표시)
dmesg -e
# 또는
vi /var/log/dmesg