구조화된 로깅

Cloud Logging에서 구조화된 로그jsonPayload 필드를 사용하여 페이로드에 구조를 더하는 로그 항목을 말합니다. Cloud Logging API 또는 gcloud 명령줄 도구를 사용하는 경우 페이로드 구조를 제어할 수 있습니다. Cloud Logging 에이전트를 사용하여 로그 항목을 가져오는 경우 Logging 에이전트가 페이로드를 JSON 형식으로 변환하도록 지정할 수 있습니다.

BindPlane 서비스를 사용하여 로그를 수집하는 경우 페이로드는 JSON 형식이며 소스 시스템에 따라 구조화됩니다. BindPlane을 통해 수집된 로그를 찾고 보는 방법은 로그 데이터 찾기에 대한 BindPlane 문서를 참조하세요.

다양한 페이로드 형식에 관한 자세한 내용은 LogEntry를 참조하세요.

다음 로그 항목 예시에는 구조화된 페이로드가 굵게 표시되어 있습니다.


{
 insertId:  "1m9mtk4g3mwilhp"
 jsonPayload: {
  "code": "structured-log-code"
  "message": "This is a log from the log file at test-structured-log.log"
 }
 labels: {
  compute.googleapis.com/resource_name:  "add-structured-log-resource"
 }
 logName:  "projects/my-sample-project-12345/logs/structured-log"
 receiveTimestamp:  "2018-03-21T01:53:41.118200931Z"
 resource: {
  labels: {
   instance_id:  "5351724540900470204"
   project_id:  "my-sample-project-12345"
   zone:  "us-central1-c"
  }
  type:  "gce_instance"
 }
 timestamp:  "2018-03-21T01:53:39.071920609Z"
}

작업

Logging 에이전트 google-fluentdfluentd 로그 데이터 수집기의 수정 버전입니다. Logging 에이전트는 기본 Fluentd 구성과 함께 제공되며, Fluentd 입력 플러그인을 사용하여 디스크상의 파일과 같은 외부 소스에서 이벤트 로그를 가져오거나 수신되는 로그 레코드를 파싱할 수 있습니다.

Fluentd에는 로그를 추출하여 구조화된(JSON) 페이로드로 변환해 주는 지원 파서 목록이 있습니다.

format [PARSER_NAME]으로 로그 소스를 구성하면 Fluentd에서 기본 제공하는 파서를 활용할 수 있습니다.

다음 코드 샘플에서는 Fluentd 구성, 로그 레코드 입력, Cloud Logging 로그 항목의 일부인 구조화된 페이로드 출력을 보여줍니다.

  • Fluentd 구성:

      <source>
        @type tail
    
        format syslog # <--- This uses a predefined log format regex named
                      # `syslog`. See details at https://docs.fluentd.org/parser/syslog.
    
        path /var/log/syslog
        pos_file /var/lib/google-fluentd/pos/syslog.pos
        read_from_head true
        tag syslog
      </source>
    
  • 로그 레코드(입력):

      <6>Feb 28 12:00:00 192.168.0.1 fluentd[11111]: [error] Syslog test
    
  • 구조화된 페이로드(출력):

        jsonPayload: {
            "pri": "6",
            "host": "192.168.0.1",
            "ident": "fluentd",
            "pid": "11111",
            "message": "[error] Syslog test"
        }
    

syslog 파서 작동 방식에 관한 자세한 내용은 Fluentd 문서를 참조하세요.

기본적으로 사용 설정되는 기본 파서

아래 표에는 구조화된 로깅을 사용 설정할 때 에이전트에 포함되는 기본 파서가 나와 있습니다.

파서 이름 구성 파일
syslog /etc/google-fluentd/config.d/syslog.conf
nginx /etc/google-fluentd/config.d/nginx.conf
apache2 /etc/google-fluentd/config.d/apache.conf
apache_error /etc/google-fluentd/config.d/apache.conf

Logging 에이전트를 설치할 때 구조화된 로깅을 사용 설정하는 방법에 관한 안내는 설치 섹션을 참조하세요.

설치

구조화된 로깅을 사용 설정하려면 설치 또는 재설치할 때 Logging 에이전트의 기본 구성을 변경해야 합니다. 구조화된 로깅을 사용 설정하면 이전에 나열된 구성 파일이 대체됩니다. 에이전트 자체 작업에는 변화가 없습니다.

구조화된 로깅을 사용 설정하면 나열된 로그가 구조화된 로그를 사용 설정하기 전보다 다양한 형식의 로그 항목으로 변환됩니다. Cloud Logging 외부로 로그를 내보내는 중이면 이 변경사항이 후속 처리 애플리케이션에 영향을 미칠 수 있습니다. BigQuery Export의 경우 BigQuery는 남은 시간 동안 새로운 로그 항목을 잘못된 스키마가 포함된 것으로 인식해 거부합니다.

Logging 에이전트 설치 및 구조화된 로깅 사용 설정에 대한 안내는 Logging 에이전트 설치를 참조하세요.

이제 /etc/google-fluentd/config.d/의 Logging 에이전트 구성 파일에 기본적으로 사용 설정된 표준 파서가 포함된 것을 확인할 수 있습니다.

Apache 액세스 로그 형식 구성

기본적으로 Logging 에이전트는 Apache 액세스 로그 데이터를 jsonPayload 필드에 저장합니다. 예를 들면 다음과 같습니다.

{
  "logName": ...,
  "resource": ...,
  "httpRequest": ...,
  "jsonPayload": {
    "user"   : "some-user",
    "method" : "GET",
    "code"   : 200,
    "size"   : 777,
    "host"   : "192.168.0.1",
    "path"   : "/some-path",
    "referer": "some-referer",
    "agent"  : "Opera/12.0"
  },
  ...
}

또는 특정 필드를 httpRequest 필드로 추출하도록 Logging 에이전트를 구성할 수도 있습니다. 예를 들면 다음과 같습니다.

{
  "logName": ...,
  "resource": ...,
  "httpRequest": {
    "requestMethod": "GET",
    "requestUrl": "/some-path",
    "requestSize": "777",
    "status": "200",
    "userAgent": "Opera/12.0",
    "serverIp": "192.168.0.1",
    "referrer":"some-referrer",
  },
  "jsonPayload": {
    "user":"some-user"
  },
  ...
}

위와 같이 httpRequest 필드를 구성하면 추적에 도움이 됩니다. Cloud Console에서 특정 HTTP 요청의 모든 로그를 상위-하위 계층 구조로 표현합니다.

추출을 구성하려면 /etc/google-fluentd/config.d/apache.conf 끝에 다음을 추가합니다.

  <filter apache-access>
    @type record_transformer
    enable_ruby true
    <record>
      httpRequest ${ {"requestMethod" => record['method'], "requestUrl" => record['path'], "requestSize" => record['size'], "status" => record['code'], "userAgent" => record['agent'], "serverIp" => record['host'],
      "referer" => record['referer']} }
    </record>
    remove_keys method, path, size, code, agent, host, referer
  </filter>

로그 항목을 구성하는 방법에 대한 자세한 내용은 로그 레코드 수정을 참조하세요.

nginx 액세스 로그 형식 구성

기본적으로 Logging 에이전트는 nginx 액세스 로그 데이터를 jsonPayload 필드에 저장합니다. 예를 들면 다음과 같습니다.

  {
    "logName": ...,
    "resource": ...,
    "httpRequest": ...,
    "jsonPayload": {
      "remote":"127.0.0.1",
      "host":"192.168.0.1",
      "user":"some-user",
      "method":"GET",
      "path":"/some-path",
      "code":"200",
      "size":"777",
      "referrer":"some-referrer",
      "agent":"Opera/12.0",
      "http_x_forwarded_for":"192.168.3.3"
    },
    ...
  }

또는 특정 필드를 httpRequest 필드로 추출하도록 Logging 에이전트를 구성할 수도 있습니다. 예를 들면 다음과 같습니다.

  {
    "logName": ...,
    "resource": ...,
    "httpRequest": {
      "requestMethod": "GET",
      "requestUrl": "/some-path",
      "requestSize": "777",
      "status": "200",
      "userAgent": "Opera/12.0",
      "remoteIp": "127.0.0.1",
      "serverIp": "192.168.0.1",
      "referrer":"some-referrer",
    },
    "jsonPayload": {
      "user":"some-user",
      "http_x_forwarded_for":"192.168.3.3"
    },
    ...
  }

위와 같이 httpRequest 필드를 구성하면 추적에 도움이 됩니다. Cloud Console에서 특정 HTTP 요청의 모든 로그를 상위-하위 계층 구조로 표현합니다.

추출을 구성하려면 /etc/google-fluentd/config.d/nginx.conf 끝에 다음을 추가합니다.

<filter nginx-access>
  @type record_transformer
  enable_ruby true
  <record>
    httpRequest ${ {"requestMethod" => record['method'], "requestUrl" => record['path'], "requestSize" => record['size'], "status" => record['code'], "userAgent" => record['agent'], "remoteIp" => record['remote'], "serverIp" => record['host'], "referer" => record['referer']} }
  </record>
  remove_keys method, path, size, code, agent, remote, host, referer
</filter>

로그 항목을 구성하는 방법에 대한 자세한 내용은 로그 레코드 수정을 참조하세요.

자체 파서 제작

로그가 기본 파서에서 지원되지 않는다면 자체 파서를 제작할 수 있습니다. 파서는 로그 레코드를 일치시키고 조각에 라벨을 적용하는 데 사용되는 정규 표현식으로 구성됩니다.

다음 3개의 코드 예제에는 로그 레코드의 로그 줄, 로그 줄의 형식을 나타내는 정규식이 포함된 구성, 내부 데이터화된 로그 항목이 나와 있습니다.

  • 로그 레코드의 로그 줄:

    REPAIR CAR $500
    
  • 로그 줄의 형식을 나타내는 정규식이 포함된 구성:

    $ sudo vim /etc/google-fluentd/config.d/test-structured-log.conf
    $ cat /etc/google-fluentd/config.d/test-structured-log.conf
    <source>
      @type tail
    
      # Format indicates the log should be translated from text to
      # structured (JSON) with three fields, "action", "thing" and "cost",
      # using the following regex:
      format /(?<action>\w+) (?<thing>\w+) \$(?<cost>\d+)/
      # The path of the log file.
      path /tmp/test-structured-log.log
      # The path of the position file that records where in the log file
      # we have processed already. This is useful when the agent
      # restarts.
      pos_file /var/lib/google-fluentd/pos/test-structured-log.pos
      read_from_head true
      # The log tag for this log input.
      tag structured-log
    </source>
    
  • 결과로 만들어진 로그 항목:

     {
      insertId:  "eps2n7g1hq99qp"
      jsonPayload: {
        "action": "REPAIR"
        "thing": "CAR"
        "cost": "500"
      }
      labels: {
        compute.googleapis.com/resource_name:  "add-structured-log-resource"
      }
      logName:  "projects/my-sample-project-12345/logs/structured-log"
      receiveTimestamp:  "2018-03-21T01:47:11.475065313Z"
      resource: {
        labels: {
          instance_id:  "3914079432219560274"
          project_id:  "my-sample-project-12345"
          zone:  "us-central1-c"
        }
        type:  "gce_instance"
      }
      timestamp:  "2018-03-21T01:47:05.051902169Z"
     }
    

구조화된 로그 보기

Cloud Console 로그 뷰어를 사용하여 로그를 검색하고 로그 항목을 보려면 로그 보기를 참조하세요.

gcloud 명령줄 도구 또는 API를 사용하여 로그 항목을 읽으려면 로그 항목 읽기를 참조하세요.

문제해결

Logging 에이전트 설치 또는 상호작용 시 일반적으로 나타나는 문제를 해결하려면 에이전트 문제해결을 참조하세요.