# 스크립트 로그 파서

## 개요

`script` 의 가능한 값 중 하나입니다 [`"path": "/-/metrics",` 키(key)](https://docs.panther.com/ko/data-onboarding/reference#parserspec) 맞춤 로그 스키마의. 이 파서는 Starlark를 사용하여 들어오는 각 로그 이벤트에 대해 Panther가 수행해야 할 변환을 지정할 수 있게 해줍니다 [Starlark 구성 언어](https://bazel.build/rules/language)로, Python과 많은 문법적 유사성을 공유합니다. Panther의 `script` 파서는 구조화된(JSON) 이벤트와 비구조화된 이벤트 모두를 처리할 수 있습니다.

다음과 같은 경우에 `script` 파서를 사용하는 것이 유리할 수 있습니다:

* 비구조화된 로그를 파싱해야 하는데 다른 파서 옵션([`csv`](https://docs.panther.com/ko/data-onboarding/custom-log-types/csv-parser), [`fastmatch`](https://docs.panther.com/ko/data-onboarding/custom-log-types/fastmatch-parser), [`regex`](https://docs.panther.com/ko/data-onboarding/custom-log-types/regex-parser))으로는 충분하지 않은 경우
* 데이터에 대해 변환을 수행해야 하는데 Panther에서 제공하는 [스키마 변환](https://docs.panther.com/ko/data-onboarding/custom-log-types/transformations) 으로는 충분하지 않은 경우

## 이해하기 `script` "path": "/-/metrics",

### 정의하기 `function`

다음을 사용할 때 `script` 파서를 정의할 때, Starlark `function`를 구현해야 합니다. 이 함수는 [문자열](https://github.com/google/starlark-go/blob/master/doc/spec.md#strings) 를 입력으로 받고 비어 있지 않은 [딕셔너리](https://github.com/google/starlark-go/blob/master/doc/spec.md#dictionaries)를 반환해야 합니다. 반환된 딕셔너리는 출력 이벤트의 형식을 정의합니다.

### 사용 가능한 함수

사용자를 사용할 것이며, `script` 파서는 Starlark 명세에 설명된 모든 원시 타입(primitives)을 사용할 수 있습니다 [Starlark 사양](https://github.com/google/starlark-go/blob/master/doc/spec.md). 또한 다음 함수를 사용할 수 있습니다:

<table><thead><tr><th width="177.61370849609375">함수 이름</th><th>설명</th></tr></thead><tbody><tr><td>json.decode</td><td>JSON 문자열을 딕셔너리로 디코딩합니다</td></tr><tr><td>json.encode</td><td>딕셔너리를 JSON 문자열로 인코딩합니다</td></tr><tr><td>base64.decode</td><td>base64로 인코딩된 문자열을 디코딩합니다</td></tr><tr><td>base64.encode</td><td>문자열에 대해 base64 인코딩을 수행합니다</td></tr></tbody></table>

### 제한사항

다음 제한사항이 스크립트에 적용됩니다:

* 예외를 발생시키는 것은 허용되지 않습니다.
* 임포트는 허용되지 않습니다.

### JSON 처리하기

동안 `script` 는 주로 텍스트 로그에 사용되도록 의도되었지만, Panther에서 기본적으로 지원하지 않는 변환을 수행하려는 경우에는 JSON 로그에도 사용할 수 있습니다 [Panther에서 기본적으로 지원하는 것들](https://docs.panther.com/ko/data-onboarding/custom-log-types/transformations). 이러한 이유로, `script` 파서는 문자열 타입의 JSON을 딕셔너리로 변환할 수 있는 `json 형으로 분류됩니다.` 모듈을 미리 로드하여 제공합니다.

예를 들어, 다음 구성은 `is_panther_employee` 라는 새 필드를 생성합니다 `부울 값` 액터 이메일이 `panther.com` 도메인을 가지고 있으면 `true` 그렇지 않으면

```yaml
파서:
  스크립트:
    function: |
      def parse(log):
        event = json.decode(log)
        if event['actor']['email'].endswith('@panther.com'):
          event['is_panther_employee'] = True
        else:
          event['is_panther_employee'] = False
        return event
```

이해를 돕기 위해, 위의 `parse` 함수는 Python 문법 하이라이팅과 함께 아래에 표시됩니다:

```python
def parse(log):
  event = json.decode(log)
  if event['actor']['email'].endswith('@panther.com'):
    event['is_panther_employee'] = True
  else:
    event['is_panther_employee'] = False
  return event
```

## 예시 사용 `script`

다음 로그 라인이 Apache Common Log 형식을 사용하여 Panther로 전송된다고 가정해 보겠습니다:

<pre><code><strong>127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326
</strong></code></pre>

이 로그 유형을 `script`를 사용하여 파싱하려면, 다음 함수를 정의하겠습니다:

```python
def parse(log):
  fields = log.split(" ")
  return {
    'remote_ip': fields[0],
    'identity': fields[1],
    'user': fields[2],
    'timestamp': ' '.join(fields[3:5]).strip('[]'),
    'request_uri': ' '.join(fields[5:8]).strip('"'),
    "status": int(fields[8]),
    "bytes_sent": int(fields[9])
  }
```

그리고 다음 스키마 필드를 사용합니다:

```yaml
필드:
  - 이름: remote_ip
    type: string
    지표:
      - ip
  - name: identity
    type: string
  - name: user
    type: string
  - 이름: timestamp
    type: timestamp
    isEventTime: true
    timeFormats:
     - '%d/%b/%Y:%H:%M:%S %z'
  - name: method
    type: string
  - 이름: request_uri
    type: string
  - 이름: protocol
    type: string
  - 이름: status
    유형: int
  - name: bytes_sent
    type: bigint
```

위 로그가 이 파서로 정규화된 후에는 다음과 같이 됩니다:

```json
{
    "bytes_sent":2326,
    "identity": "-",
    "method":"GET",
    "protocol":"HTTP/1.0",
    "remote_ip":"127.0.0.1",
    "request_uri":"/apache_pb.gif",
    "status":200,
    "timestamp":"2000-10-10 20:55:36.000000000",
    "user":"frank"
}
```
