log

/usr/local/m2/setting.json 다음 영역에 대해 기술한다.

{
  "env": {
    "log": {
      "xxx" : {
        "enable": true,
        "rolling": {
          "size": 1,
          "time": 1440
        },
        "retention": 5,
        "compression": false
      }
    }
  }
}

모든 로그는 기록여부를 설정할 수 있으며, 공통속성을 가진다.

enable (기본: true)

로그 활성화

rolling

로그 롤링조건을 설정한다. 두 속성을 모두 지정하면 먼저 조건에 도달하는 롤링조건을 따른다.

  • time (단위: 1440분) 시간 기준으로 롤링한다.

  • size (단위: 1MB) 용량 기준으로 롤링한다.

retention (기본: 5개)

단위 로그파일을 최대 n개 유지한다.

compression (기본: false)

로그가 롤링될 때 압축을 진행한다. 예를 들어 access_20140715_0000.log 파일이 롤링되면 access_20140715_0000.log.gz 로 압축되어 저장된다.

meta

가상호스트 서비스를 제외한 솔루션 관리를 위한 로그를 기록한다.

"meta" : {
  "dir" : "m2log",
  "port": 8514
}
dir (기본: m2log)

로그 저장 디렉토리. 기본 경로는 /usr/local/m2/m2log 이다.

port (기본: 8514)

서브 컴포넌트로부터 로그를 집계할 UDP 포트

info

M2 구동상태와 설정변경에 대해 기록한다.

"info" : {
  "enable": true,
  "dir": null,
  "rolling": {
    "size": 1,
    "time": 1440
  },
  "retention": 5,
  "compression": false,
}

watch.log

서비스 형상 및 동작 현황을 기록한다.

"watch": {
  "enable": true,
  "dir": null,
  "rolling": {
    "size": 10,
    "time": 1440
  },
  "retention": 3,
  "compression": false,
  "backup": [],
  "events": {
    "setting": {
      "enable": true,
      "fullsync": 30
    }
  }
}
events

감지할 이벤트. 가동과 관련된 이벤트는 기본으로 활성화된다.

setting

설정변경 이벤트 감지

enable (기본: true)

감지 활성화

fullsync (기본: 30일)

마지막 가상호스트 설정 동기화 이후 설정 백업 주기

로그 샘플과 필드는 아래와 같다.

#Fields: date time event vhost body
2023-11-01 15:51:37 00010001 - ...
2023-11-01 16:52:24 100001 foo.com {...}
2023-11-01 16:52:24 100002 bar.com {...}
event

감지된 이벤트

event

설명

body

00010001

솔루션이 가동되었다.

hosting[] 을 제외한 전체 설정

00010002

솔루션이 종료되었다.

{}

00020001

가상호스트가 추가되었다.

hosting[] 가상호스트 전체 설정

00020002

가상호스트가 삭제되었다.

{name:"삭제된 가상호스트 이름}"

00020003

가상호스트가 변경되었다.

변경된 이전 설정은 _asis_ 접두어가 붙는다.

00020004

가상호스트 fullsync 시점이다.

hosting[] 가상호스트 전체 설정

00030001

백업 스케줄러가 시작되었다.

env.log 전체 설정

00030002

백업 스케줄러가 삭제되었다.

{}

00030003

백업 스케줄러가 변경되었다.

env.log 전체 설정

00030004

백업 스케줄러가 로그 백업을 시도했다.

{name, date, time, path, bytes, error}

vhost

가상호스트 (전역설정처럼 없다면 - )

body

json 형식의 데이터

error.log

서비스 에러 상황( 에러리스트 )을 기록한다.

"error": {
  "enable": true,
  "dir": null,
  "rolling": {
    "size": 1,
    "time": 1440
  },
  "retention": 10,
  "compression": false,
  "backup": []
}
#Fields: date time error vhost url x-ctx-id message
2023-01-13 15:51:37 30100005 foo.com /test-origin/test_1.gif2 aa83cfdb-1b06-4bad-a1c0-d627fdbd8977 /resize/100;123213213;1024
  • date 날짜

  • time 시간

  • error 에러리스트

  • vhost 가상호스트 (없다면 - )

  • url URL (없다면 - )

  • x-ctx-id 요청 고유ID (없다면 - )

  • message 추가정보

metrics.log

/metrics API 호출 결과를 개별파일로 기록한다. 로그 경로 env.log.meta.dir 하위에 일별 디렉토리 구조로 기록된다.

# 형식
./metrics_{yyyymmdd}/metrics_{yyyymmddhhmmss}.log

# 예제
./metrics_20230103/metrics_20230103101434.log
"metrics": {
  "enable": true,
  "dir": null,
  "schedule": "0 */5 * * * *",
  "rolling": {
    "time": 1440
  },
  "retention": 10,
  "compression": false,
  "backup": []
}
schedule (기본: 5분마다 기록)

metrics 기록 스케쥴링

rolling

일반 로그파일 형식과 달리 단일 파일이 아니기에 retention 설정과 조합해 용량 개념으로만 동작한다.

# 1일(1440분) x 10 = 10일 만큼 metrics를 저장한다.
"metrics": {
  "rolling": {
    "time": 1440
  },
  "retention": 10
}

# 1MB x 10 = 10MB 만큼 metrics를 저장한다.
"metrics": {
  "rolling": {
    "size": 1
  },
  "retention": 10
}

# 10일 또는 10MB 중 먼저 도달하는 조건까지만 metrics를 저장한다.
"metrics": {
  "rolling": {
    "size": 1,
    "time": 1440
  },
  "retention": 10
}

system deprecated

M2가 구동되는 호스트 시스템의 상태를 기록한다.

"system" : {
  "enable": false,
  "rolling": {
    "size": 1
  },
  "retention": 5,
  "compression": false
}

originError deprecated

모든 원본서버에서 발생한 장애를 기록한다.

"originError" : {
  "enable": true,
  "rolling": {
    "size": 1
  },
  "retention": 5,
  "warning": false,
  "compression": false
}
Warning (기본: false)

설정을 활성화하면 다음 예제처럼 잘못된 HTTP통신이 발생한 경우에 기록한다.

2012.11.15 07:09:03 [example.com] [WARNING] 10.10.10.10 121.189.63.219 GET /716439_SM.jpg 20110 PartialResponseOnNormalRequest Res=206,Len=2635
2012.11.15 07:09:03 [example.com] [WARNING] 10.10.10.10 121.189.63.219 GET /716439_SM.jpg 20110 ClosedWithoutResponse -

잘못된 HTTP통신의 경우는 다음과 같다.

  • ClosedWithoutResponse 원본서버에 의한 연결종료. HTTP 응답을 받지 못했다.

  • ClosedWhenDownloading 원본서버에 의한 연결종료. Content-Length 만큼 다운로드하지 못했다.

  • NotPartialResponseOnRangeRequest Range요청을 했으나 응답코드가 206이 아니다.

  • DifferentContentLengthOnRangeRequest 요청한 Range와 Content-Length가 다르다.

  • PartialResponseOnNormalRequest Range요청이 아닌데 응답코드가 206이다.

repository

로그백업 저장소를 구성한다.

Note

공통 저장소 구성 후 가상호스트 단위로 로그백업 활성화 를 진행해야 한다.

저장소는 AWS S3Google Cloud Storage 를 지원하며 아래와 같이 멀티구성이 가능하다.

{
  "env": {
    "log": {
      "repository": {
        "concurrent": 1,
        "list": [
          {
            "name": "backup",
            "type": "aws-s3",
            "rolling": "0 0",
            "path": "/edgelog/{domain}/{timestamp}/{hostname}_{logtype}.log",
            "compression": {
              "enable": false
            },
            "endpoint": {
              "bucket": "s3-backup",
              "region": "ap-northeast-2",
              "accessKey": "00000000000000000000",
              "secretKey": "000000000000000000000000000000000000000"
            }
          },
          {
            "name": "eventlog",
            "type": "aws-s3",
            "rolling": "*/5 *",
            "path": "/logs/event/year={timestamp.year}/month={timestamp.month}/day={timestamp.day}/hour={timestamp.hour}/min={timestamp.minute}/type={logtype}/domain={domain}/{hostname}_{ip}_{timestamp}.log",
            "compression": {
              "enable": true
            },
            "endpoint": {
              "bucket": "s3-backup-event",
              "region": "us-east-1",
              "accessKey": "555557S4RTTTAKKKUPB5",
              "secretKey": "ETMQQQc4KaJ6mQQQLBmj4LWKiejqcqavykf6lPM"
            }
          }
        ]
      }
    }
  }
}
concurrent (기본: 1)

로그 백업 동시 세션

Note

로그 백업 때문에 서비스 성능저하가 발생하면 안되어 스펙만 존재한다. 변경하여도 반영되지 않는다.

list

로그 저장소 목록

name

저장소 이름. 중복불가.

type

저장소 타입.

rolling

로그 업로드 시점으로 cron 스타일 표현이지만 Minute Hour 이다.

Note

개별 로그의 rolling 설정과 같은 표현을 사용하지만 동작방식이 다르다.

  • 개별로그의 rolling 은 물리적인 로컬 로그파일이 교체되는 것에 대해 정의한다.

  • 로그백업의 rolling 은 저장소에 저장될 로그파일 단위에 대해 정의한다.

예를 들어 로컬의 access.log 는 day 단위로 운영되더라도 서버 사이드 백업은 5분 단위로 백업될 수 있다. 그 반대도 가능하다.

path

로그 업로드 경로정책. 경로 정책은 다음 3요소를 고려하여 구성되어야 한다.

  • 멀티 노드 2대 이상의 불특정 멀티 노드에서 운영된다.

  • 멀티 가상호스트 2개 이상의 가상호스트가 존재하며 언제든지 추가/삭제된다.

  • 시간 로그는 시계열 데이터이다.

로그 백업시 경로충돌에 대해 보장하지 않는다.

이상을 지원하기 위해 다음 변수를 제공한다.

{변수}

상세

{group}

meta.group 설정 값

{domain}

가상호스트 이름

{hostname}

가상호스트를 서비스하는 M2의 호스트명

{ip}

M2노드의 IP

{timestamp}

yyyymmddhhmmss 형식의 시간

{logtype}

로그타입. access 또는 origin

{timestamp} 의 경우 하위 필드를 제공한다.

{timestamp}

20220116173627

{timestamp.date}

20220116

{timestamp.time}

173627

{timestamp.year}

2022

{timestamp.month}

01

{timestamp.day}

16

{timestamp.hour}

17

{timestamp.minute}

36

{timestamp.second}

27

compression

로그 gzip 압축.

endpoint

저장소 연결구성

AWS S3

AWS S3 로그 백업저장소는 다음과 같이 구성한다.

# env.log.repository.list[]

"type": "aws-s3",
"endpoint": {
  "bucket": "s3-backup",
  "region": "ap-northeast-2",
  "accessKey": "00000000000000000000",
  "secretKey": "000000000000000000000000000000000000000"
}
bucket

버킷

region

리젼

accessKey

액세스 키

secretKey

시크릿 키

Google Cloud Storage

Google Cloud Storage 로그 백업저장소는 각 설정을 일일이 명시하거나 자격 증명파일( credential ) 형태로 구성이 가능하다.

# env.log.repository.list[]

"type": "google-cloud-storage",
"endpoint": {
  "project_id": "stg-api",
  "private_key_id": "a9818f5f2000000000000000000000c5a361",
  "private_key": "-----BEGIN PRIVATE KEY-----\nFw7tRvI5MIIEvQIBA0000000000000000000AQEFAASCBKcwggSjAgEAAoIBAQDCg32k\n5IC8pq9QbGEVQKBet+mMxoRAIxud2enJ3snRkcH8r1IP27hgE5fXQSQcaJ50iTRT\nxI+b07SAkQhItOW2Apo49UA/0VxQeDz5GMd3eq8Nzmqw2srgaChtRkOE4Zu19HTe\n1iL855+KPz36PZLj7YV46/mjmvCSvp6Mqy1oRNfHvSMwOZLWwoKLiLkDk4BXatd/\nTLEZisXReKq30VDCJq9QLqjddldP/lso+Vbgui+rkufCu0nX4wxrbb8+aYTt2T5P\nWfvTYGo5DcwdfoVyChH5LazlZ2ySAJa5yY7ZBHUQ0RbDDSN+hHFI6OxYhGJ4EbzQ\n3SLL7YifAgMBAAECggEAX/njd6DNA7T69ifSgcM5Q9SGPqdJuhLDEWwuezsXeFa6\nrZnZOSfTcOvM8Pg4TGe+hz6kI8RXUycUA7U8KuZV7Q4i6UUhByLXl/0jO5oBE8+Q\nPlTEryaA064jJKqAaiPatrhxvlJXs3swY3eDggiDxwIXga76GK7tKdI9tkVQKQc5\nPOmBfp6Mcaex1rpaVXNmEkwIQyQDdnQDhDUscjHl0Tz6tQ3Y0HqtnxoQLWW77cJo\nmSLX722/fSwGZoSZ2gxX5U3nx40ZWI3WyDOPBYVE2ztnWrlC2WRMpCYiODoADswn\nWbBnoKtttbeM1cD0mR6dDjZ+4J2TdRcdHkxSMluc+QKBgQD+LcxZoHxvrx+0RjX/\n82ntYVkYthbWt+bIzBNy3hw15qnSkYGjlKQ61tfKe494VHVFRzmRcsxW6vNlHHRD\nNQ2/z7WeulVCrL8LH/PFiWEWV3rjTxaNbAmWZo7619311ZYF4Hk1VHZicgKGCEba\nZ5XKNsUyv487DOh2MCBlFIp37QKBgQDD6EHyubsA1oSYSn4NK3wFcuAtqyV62xvD\nldr5gUcO4AbzLT/ubI3ATyFfsmgfi/KstIKPLLLWOEFOTOwl5Mj7PnR8lzLhkj8O\nnjCVQ6NVXZHoQk8A0EtXkoDAfW3I97XL3lvThzz+2/oD7hFrYDsJ7VrCu36J31dV\nS0wrrkzZOwKBgBh3CAhIbjHBxWdwqpnsL/HtQMokHKamJMyG+AhCYKy/evENmFDK\nadRQAY03v2NxnagBZwUc65YiHzNIPdiKLrybnXudq78zKWBEvw3wXyvrV6SxZBZQ\no8uaK4DxbifPWxVNudzsOEjZeGy2NzumZMCF7Q0pavvgDi/yCewwwfMxAoGBAJqt\n6kwci2M4/Q5FWstJNy4SKqDETd53268Mxg1UHmfHSJV+d8jnmvBpSh+F/KJT3DKy\nf5dOIpHzbtTE9Xth7bI5+L1aoEjsMK95BUEFW5QOQiLRIBGzZJlrSg8xuZoAw2CJ\nW5VjZSyRQRETSluuak8HQi8Y3Os9FXZ58lVW1MR7AoGAF/imeSAD1BQaesenGR6n\nru6qke2F9az+7NqC/E2pDw16ER8K2w96i5gyHsYjIhV0TkYcHWvW7+VLlPMbGkJT\nheAaPg3xtqnwyrWrhM3H7uUYpCsdAiZMeApcAw956jPoQx2jnG7//9jPdZxbpF65\n29xDzij2jzKKIccnRMbKf3o=\n-----END PRIVATE KEY-----\n",
  "client_email": "stg-api@appspot.gserviceaccount.com",
  "client_id": "100000000000000000000418",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/stg-api%40appspot.gserviceaccount.com"
}
project_id

프로젝트 아이디

private_key_id

개인키 아이디

private_key

개인키

client_email

클라이언트 이메일

client_id

클라이언트 아이디

client_x509_cert_url

클라이언트 인증서 URL

다음은 자격 증명파일( credential ) 예제이다.

# env.log.repository.list[]

"type": "google-cloud-storage",
"endpoint": {
  "credential": '/usr/local/m2/stg-api-a000000000.json'
}

Note

자세한 내용은 Google Cloud 서비스 계정 키 생성 및 관리 를 참고하세요.

Kakao i cloud - Object Storage

Kakao i cloud - Object Storage 저장소는 다음과 같이 구성한다.

# env.log.repository.list[]

"type": "kakaoi-object-storage-v1",
"endpoint": {
  "bucket": "my-backup",
  "region": "objectstorage.kr-central-1",
  "account": "my-account",
  "accessKey": "00000000000000000000",
  "secretKey": "000000000000000000000000000000000000000"
}
bucket

버킷

region

리젼

account

Project ID

  • 토큰 발급 시 확인 가능 (토큰 발급 과정에서 사용/확인된 프로젝트 ID)

  • Swift API 에서 Account 값으로 사용

accessKey

액세스 키

secretKey

시크릿 키

StatsD Event

StatsD 규격을 준수하는 이벤트를 전송한다.

Note

StatsD 저장소는 아래 로그에 한정하여 지원된다.

저장소는 다음과 같이 구성한다.

# env.log.repository.list[]

"type": "statsd",
"endpoint": {
  "port": 8125,
  "exports": {
    "enable": true,
    "matchingList": ["000(.*)", "100(.*)", "200(.*)", "300(.*)"]
  }
}
port (기본: 8125)

전송 포트

exports

이벤트 전송 정책을 구성한다.

enable

  • false (기본) 모든 이벤트를 전송한다.

  • true 노출할 이벤트를 선택한다.

matchingList

전송할 이벤트 리스트. 정규식 표현을 지원한다.

Promtail agent

Grafana Promtail agent 로 로그를 전송한다.

저장소는 다음과 같이 구성한다.

# env.log.repository.list[]

"type": "promtail",
"endpoint": {
  "url": "http://loki-server:3100/loki/api/v1/push"
  "exports": {
    "enable": false,
    "matchingList": null
  }
}
url

Grafana Loki 서버 URL

exports

이벤트 전송 정책을 구성한다.

enable

  • false (기본) 모든 이벤트를 전송한다.

  • true 노출할 이벤트를 선택한다.

matchingList

전송할 이벤트 리스트. 정규식 표현을 지원한다.