# 스크립트 로그 파서

## 개요

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

다음의 사용을 고려하면 도움이 될 수 있습니다. `script` parser를 다음과 같이 사용하고 싶을 때:

* 비구조화된 로그를 파싱하되, 다른 파서 옵션([`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가 제공하는 [schema transformations](https://docs.panther.com/ko/data-onboarding/custom-log-types/transformations) 이 충분하지 않을 때

## 다음을 이해하기 `script` parser

### 다음을 정의하기 `함수`

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

### 사용 가능한 함수

다음 `script` parser는 [Starlark specification](https://github.com/google/starlark-go/blob/master/doc/spec.md)에 설명된 모든 primitive를 사용할 수 있습니다. 또한 다음 함수를 사용할 수 있습니다:

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

### 제한 사항

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

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

### JSON 처리

일반적으로 `script` 는 텍스트 로그에 주로 사용하도록 설계되어 있지만, 다음에서 기본적으로 지원하는 [기능 외의 변환을 수행하고 싶을 때 JSON 로그에도 사용할 수 있습니다.](https://docs.panther.com/ko/data-onboarding/custom-log-types/transformations). 이러한 이유로 `script` parser에는 JSON을 문자열 유형에서 dictionary 유형으로 변환할 수 있게 해주는 `json` 모듈이 미리 로드되어 있습니다.

예를 들어, 다음 구성은 다음이라는 새 필드를 생성합니다. `is_panther_employee` 이며 이는 다음이 될 것입니다. `true` if actor 이메일에 `panther.com` 도메인이 있으면, 그렇지 않으면 `false` 입니다.

```yaml
parser:
  script:
    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
fields:
  - name: remote_ip
    type: string
    indicators:
      - 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
  - name: request_uri
    type: string
  - 이름: protocol
    type: string
  - name: status
    type: int
  - name: bytes_sent
    유형: 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"
}
```
