# 로그 스키마 참조

이 가이드에서는 온보딩 시 YAML 기반 스키마를 빌드할 때 사용되는 일반적인 필드를 확인할 수 있습니다 [사용자 지정 로그 유형](https://docs.panther.com/data-onboarding/custom-log-types) 및 [조회 테이블](https://docs.panther.com/enrichment/lookup-tables) 스키마.

{% hint style="info" %}
이 페이지 전반의 필수 필드는 **굵게**.
{% endhint %}

## LogSchema 필드

각 로그 스키마에는 다음 필드가 포함됩니다:

* **`필드`** ([`[]FieldSchema`](#fieldschema))
  * 각 *로그 이벤트*.
* `파서` ([`ParserSpec`](#parserspec))
  * 비 JSON 로그를 JSON으로 변환하거나 사용자 지정 변환을 수행할 수 있는 파서

### CI/CD 스키마 필드

또한 CI/CD 워크플로를 사용해 정의된 스키마에는 다음 필드가 포함될 수 있습니다:

* **`schema`** (`string`)
  * 스키마의 이름
* `description` (`string`)
  * UI에 표시될 간단한 설명
* `referenceURL` (`string`)
  * 로그 구조를 지정하는 외부 문서로의 링크입니다. 종종 서드파티 문서 링크입니다.
* `fieldDiscoveryEnabled` (`boolean`)
  * 다음이 [필드 검색](https://docs.panther.com/ko/data-onboarding/custom-log-types/..#enabling-field-discovery) 이 스키마에 대해 활성화될지 여부를 나타냅니다.

{% hint style="info" %}
CI/CD 파이프라인을 통해 스키마를 관리하는 방법에 대한 정보는 사용자 지정 로그 페이지를 참조하세요. [Panther Analysis Tool(PAT)을 사용하여](https://docs.panther.com/ko/data-onboarding/custom-log-types/..#uploading-log-schemas-with-the-panther-analysis-tool)[ ](https://docs.panther.com/ko/data-onboarding/custom-log-types/..#uploading-log-schemas-with-the-panther-analysis-tool).
{% endhint %}

### 예시

아래 예제에는 위에서 언급한 CI/CD 필드가 포함되어 있습니다.

```yaml
schema: Custom.MySchema
description: (선택 사항) 이 스키마가 무엇인지 알 수 있도록 유용한 설명입니다.
referenceURL: (선택 사항) 이 스키마가 적용되는 로그에 대한 문서 링크입니다.
fieldDiscoveryEnabled: true
parser:
  csv:
    delimiter: ','
    hasHeader: true
fields:
- 이름: 동작
  type: string
  required: true
- 이름: time
  type: timestamp
  timeFormats:
    - unix
```

### ParserSpec

ParserSpec는 비 JSON 입력을 JSON으로 변환하는 데 사용할 파서를 지정합니다. 다음 필드 중 하나만 지정할 수 있습니다:

* `fastmatch` (`FastmatchParser{}`): 다음을 사용하세요 `fastmatch` 파서
  * 다음에서 자세히 알아보기 [Fastmatch 로그 파서](https://docs.panther.com/ko/data-onboarding/custom-log-types/fastmatch-parser).
* `regex` (`RegexParser{}`): 다음을 사용하세요 `regex` 파서
  * 다음에서 자세히 알아보기 [정규식 로그 파서](https://docs.panther.com/ko/data-onboarding/custom-log-types/regex-parser).
* `csv` (`CSVParser{}`): 다음을 사용하세요 `csv` 파서
  * 참고: `columns` 필드는 동일한 로그 소스에 여러 CSV 스키마가 있을 때 필요합니다.
  * 다음에서 자세히 알아보기 [CSV 로그 파서](https://docs.panther.com/ko/data-onboarding/custom-log-types/csv-parser).
* `script`: 다음을 사용하세요 `script` 파서
  * 다음에서 자세히 알아보기 [스크립트 로그 파서](https://docs.panther.com/ko/data-onboarding/custom-log-types/script-parser).

아래 탭에서 `fastmatch`, `regex`, 및 `csv` 의 필드를 확인하세요.

{% tabs %}
{% tab title="fastmatch" %}
**파서 `fastmatch` 필드**

* **`match`** (`[]string`): 로그 라인과 일치시킬 하나 이상의 패턴입니다. 이 필드는 비워둘 수 없습니다.
* `emptyValues` (`[]string`): 다음으로 간주할 값 `null`.
* `expandFields` (`map[string]string`): 텍스트 템플릿 확장을 통해 주입할 추가 필드입니다.
* `trimSpace` (`bool`): 각 값 주변의 공백을 제거합니다.
  {% endtab %}

{% tab title="regex" %}
**파서 `regex` 필드**

* **`match`** (`[]string`): 로그 라인과 일치시킬 패턴입니다(문서화를 위해 여러 부분으로 나눌 수 있습니다). 이 필드는 비워둘 수 없습니다.
* `patternDefinitions` (`map[string]string`): match 패턴에서 사용할 추가 명명된 패턴입니다.
* `emptyValues` (`[]string`): 다음으로 간주할 값 `null`.
* `expandFields` (`map[string]string`): 텍스트 템플릿 확장을 통해 주입할 추가 필드입니다.
* `trimSpace` (`bool`): 각 값 주변의 공백을 제거합니다.
  {% endtab %}

{% tab title="csv" %}
**파서 `csv` 필드**

* **`delimiter`** (`string`): 필드 구분자로 사용할 문자입니다.
* `hasHeader` (`bool`): 첫 번째 행을 사용해 열 이름을 도출합니다(다음이 설정된 경우는 제외하고, `columns` 이 설정된 경우 헤더는 단순히 건너뜁니다).
* `columns` (`[]string`, `필수(hasHeader 없음)`, `비어 있지 않음`): CSV 파일의 각 열 이름입니다. 설정되지 않은 경우 첫 번째 행이 헤더로 사용됩니다.
* `emptyValues` (`[]string`): 다음으로 간주할 값 `null`.
* `trimSpace` (`bool`): 각 값 주변의 공백을 제거합니다.
* `expandFields` (`map[string]string`): 텍스트 템플릿 확장을 통해 주입할 추가 필드입니다.
  {% endtab %}

{% tab title="script" %}
**파서 `script` 필드**

* **`function`** (`string`): [Starlark](https://bazel.build/rules/language) 이벤트마다 실행할 함수
  {% endtab %}
  {% endtabs %}

### FieldSchema

하나의 *FieldSchema* 는 필드와 그 값을 정의합니다. 필드는 다음으로 정의됩니다:

* **`name`** (`string`)
  * 필드의 이름입니다.
* `required` (`boolean`)
  * 필드가 필수인지 여부입니다.
* `description` (`string`)
  * 필드를 설명하는 텍스트입니다.
* [`copy`](https://docs.panther.com/ko/data-onboarding/transformations#copy) (`object`)
  * 존재하는 경우 필드 값은 참조된 `object`.
* [`rename`](https://docs.panther.com/ko/data-onboarding/transformations#rename) (`object`)
  * 존재하는 경우 필드 이름이 변경됩니다.
* [`concat`](https://docs.panther.com/ko/data-onboarding/transformations#concat) (`object`)
  * 존재하는 경우 필드 값은 두 개 이상의 다른 필드 값의 조합이 됩니다.
* [`split`](https://docs.panther.com/ko/data-onboarding/transformations#split) (`object`)
  * 존재하는 경우 필드 값은 구분자를 기준으로 분할하여 다른 문자열 필드에서 추출됩니다.
* [`mask`](https://docs.panther.com/ko/data-onboarding/transformations#mask) (`object`)
  * 존재하는 경우 필드 값이 마스킹됩니다.

그 값은 다음 필드를 사용해 정의됩니다. [`ValueSchema`](#valueschema).

### ValueSchema

하나의 `ValueSchema` 값과 그 처리 방법을 정의합니다. 각 `ValueSchema` 에는 `type` 필드가 있으며, 다음 값 중 하나일 수 있습니다:

<table data-header-hidden><thead><tr><th width="268">값 유형</th><th>설명</th></tr></thead><tbody><tr><td>유형 값</td><td>설명</td></tr><tr><td><code>string</code></td><td>문자열 값</td></tr><tr><td><code>int</code></td><td>범위 내의 32비트 정수 <code>-2147483648</code>, <code>2147483647</code></td></tr><tr><td><code>smallint</code></td><td>범위 내의 16비트 정수 <code>-32768</code>, <code>32767</code></td></tr><tr><td><code>bigint</code></td><td>범위 내의 64비트 정수 <code>-9223372036854775808</code>, <code>9223372036854775807</code></td></tr><tr><td><code>float</code></td><td>64비트 부동 소수점 숫자</td></tr><tr><td><code>boolean</code></td><td>불리언 값 <code>true</code> / <code>false</code></td></tr><tr><td><code>timestamp</code></td><td>타임스탬프 값</td></tr><tr><td><code>array</code></td><td>각 요소가 동일한 유형인 JSON 배열</td></tr><tr><td><code>object</code></td><td>다음 항목의 JSON 객체 <em>알려진</em> 키</td></tr><tr><td><code>json</code></td><td>유효한 모든 JSON 값(JSON 객체, 배열, 숫자, 문자열, 불리언)</td></tr></tbody></table>

다음의 필드 `ValueSchema` 은/는 다음의 값에 따라 달라집니다. `type`.

<table data-header-hidden><thead><tr><th width="171">Type</th><th width="192">필드</th><th width="162">Value</th><th>설명</th></tr></thead><tbody><tr><td>Type</td><td>필드</td><td>Value</td><td>설명</td></tr><tr><td><code>object</code></td><td><strong><code>필드</code></strong> (필수)</td><td><a href="#fieldschema"><code>[]FieldSpec</code></a></td><td>다음의 배열 <code>FieldSpec</code> 객체로, 객체의 필드를 설명합니다.</td></tr><tr><td><code>array</code></td><td><strong><code>element</code></strong> (필수)</td><td><a href="#valueschema"><code>ValueSchema</code></a></td><td>하나의 <code>ValueSchema</code> 배열의 요소를 설명합니다.</td></tr><tr><td><code>timestamp</code></td><td><strong><code>timeFormats</code></strong> (필수)</td><td><code>[]String</code></td><td>타임스탬프 파싱에 사용할 형식을 지정하는 배열입니다(참조 <a href="#timestamps">타임스탬프</a>)</td></tr><tr><td><code>timestamp</code></td><td><code>isEventTime</code></td><td><code>Boolean</code></td><td>Panther가 이 타임스탬프를 <em>로그 이벤트 타임스탬프</em>.</td></tr><tr><td><code>string</code></td><td><code>지표</code></td><td><code>[]String</code></td><td>Panther가 이 값에서 지표를 추출하도록 지시합니다(참조 <a href="#indicators">지표</a>)</td></tr><tr><td><code>string</code></td><td><code>validate</code></td><td>참조하세요 <a href="#validate">검증</a></td><td>문자열 값에 대한 검증 규칙</td></tr></tbody></table>

### 타임스탬프

타임스탬프는 `type` 필드를 `timestamp` 로 설정하고 `timeFormats` 필드에 붙여넣습니다.

Panther는 항상 `timestamp` 값을 협정 세계시(UTC)로 저장합니다. 이는 다음을 의미합니다:

* 만약 `timestamp` 필드 값이 UTC가 아닌 다른 시간대를 나타내면( [UTC 오프셋](https://en.wikipedia.org/wiki/UTC_offset)), Panther는 이를 UTC로 변환합니다.
  * 예를 들어, 들어오는 `timestamp` 필드에 다음 값이 있었다면 `2025-07-02T00:15:30-08:00` (여기서 `-08:00` 오프셋은 태평양 표준시\[PST]를 의미합니다), Panther는 이를 `2025-07-02 08:15:30.000000000` 로 저장합니다(UTC로 변환됨).
* 만약 `timestamp` 필드 값이 시간대를 나타내지 않으면 Panther는 UTC로 간주하고 그대로 저장합니다.

허용되는 `timeFormats` 값은 아래를 참조하세요:

<table><thead><tr><th width="154.00000000000003">timeFormats 값</th><th width="276">예시</th><th>설명</th></tr></thead><tbody><tr><td><code>rfc3339</code></td><td><code>2022-04-04T17:09:17Z</code></td><td>가장 일반적인 타임스탬프 형식입니다.</td></tr><tr><td><code>unix_auto</code></td><td><code>1649097448</code> (초)<br><br><code>1649097491531</code> (밀리초)<br><br><code>1649097442000000</code> (마이크로초)<br><br><code>1649097442000000000</code> (나노초)</td><td>UNIX epoch time 이후 경과한 시간으로 표현된 타임스탬프입니다. 초, 밀리초, 마이크로초, 나노초를 처리할 수 있습니다.</td></tr><tr><td><code>unix</code></td><td><code>1649097448</code></td><td>UNIX epoch time 이후 초 단위로 표현된 타임스탬프입니다. 소수점 이하의 초를 처리할 수 있습니다.</td></tr><tr><td><code>unix_ms</code></td><td><code>1649097491531</code></td><td>UNIX epoch time 이후 밀리초 단위로 표현된 타임스탬프입니다.</td></tr><tr><td><code>unix_us</code></td><td><code>1649097442000000</code></td><td>UNIX epoch time 이후 마이크로초 단위로 표현된 타임스탬프입니다.</td></tr><tr><td><code>unix_ns</code></td><td><code>1649097442000000000</code></td><td>UNIX epoch time 이후 나노초 단위로 표현된 타임스탬프입니다. 과학적 부동소수점 표기법이 지원됩니다.</td></tr></tbody></table>

{% hint style="warning" %}
그 `timeFormats` 필드는 사용자 지정 로그 스키마에서 여러 타임스탬프 형식을 지원하기 위해 Panther v1.46에 도입되었습니다. 비록 `timeFormat` 은 v1.46 이전에 설정된 로그 소스에서도 계속 지원되지만, `timeFormats` 를 모든 새 스키마에 사용하세요.
{% endhint %}

#### 사용자 지정 형식 정의하기

다음을 사용하여 사용자 지정 형식을 정의할 수도 있습니다. [strftime](https://strftime.org) 표기법을 예로 들 수 있습니다:

```yaml
# 이 필드는 "2020-09-14 14:29:21"과 같은 사용자 지정 타임스탬프 형식을 사용하는 타임스탬프입니다
- name: ts
  type: timestamp
  timeFormats:
    - "%Y-%m-%d %H:%M:%S" # 올바른 YAML 구문을 위해 따옴표가 필요합니다
```

Panther의 strftime 형식은 `%N` 코드를 사용해 나노초를 파싱하는 것을 지원합니다. 예:

`%H:%M:%S.%N` 다음을 파싱하는 데 사용할 수 있습니다 `11:12:13.123456789`

#### 여러 시간 형식 사용하기

여러 시간 형식이 정의되면, 성공적으로 파싱될 때까지 각 형식을 순차적으로 시도합니다:

```yaml
- name: ts
  type: timestamp
  timeFormats:
    - rfc3339
    - unix
```

타임스탬프 값은 `isEventTime: true` 로 표시할 수 있으며, Panther가 이 타임스탬프를 `p_event_time` 필드로 사용하도록 알립니다. 여러 필드에 `isEventTime` 를 설정할 수 있습니다. 이는 로그에 이벤트 시간 정보를 담는 선택적 필드나 상호 배타적인 필드가 있을 때 유용할 수 있습니다. 각 로그 이벤트에는 하나의 `p_event_time` 만 있을 수 있으므로, 우선순위는 스키마 내 필드 순서로 정의됩니다.

#### 다음과 함께 작업하기 `timeFormats` 스키마 테스트에서

다음을 사용해 실행할 스키마 테스트를 작성할 때 [`pantherlog test` 명령](https://docs.panther.com/ko/panther/pantherlog#test-run-tests-for-a-schema):

* 스키마 필드에 단일 `timeFormats` 값이 있으면, 이전 버전과의 호환성을 위해 설정은 동일한 형식을 유지합니다.
* 스키마 필드에 여러 `timeFormats` 값이 있으면, 타임스탬프 필드 값을 `result` 페이로드에 다음 형식으로 정의해야 합니다 `YYYY-MM-DD HH:MM:SS.fffffffff`.

단일 `timeFormats` 값의 예:

```yaml
- name: singleFormatTimestamp
  type: timestamp
  timeFormats:
    - unix
```

```yaml
input: >
  {
    "singleFormatTimestamp": "1666613239"
  }
result: >
  {
    "singleFormatTimestamp": "1666613239"
  }
```

여러 `timeFormats` 값의 예:

```yaml
- name: multipleFormatTimestamp
  type: timestamp
  timeFormats:
    - unix
    - rfc3339
```

```yaml
input: >
  {
    "multipleFormatTimestamp": "1666613239"
  }
result: >
  {
    "multipleFormatTimestamp": "2022-10-24 12:07:19.459326000"
  }
```

### 지표

다음의 값 `string` 유형은 "지표"로 사용할 수 있습니다. 필드를 지표로 표시하려면 `지표` 필드를 하나 이상의 지표 스캐너 이름 배열로 설정하세요. 그러면 Panther가 이 필드의 값을 관련 `p_any_` 필드에 붙여넣습니다.

에서 사용할 수 있는 유효한 값 목록은 `지표` 필드를 참조하세요 [표준 필드](https://docs.panther.com/ko/search/panther-fields#indicator-fields).

예:

```yaml
# 값을 IP 주소로 스캔하여 `p_any_ip_addresses`에 저장합니다
- 이름: remote_ip
  type: string
  indicators: [ ip ]

# 값을 도메인 이름 및/또는 IP 주소로 스캔합니다.
# 결과는 `p_any_domain_names` 및/또는 `p_any_ip_addresses`에 저장됩니다
- name: target_url
  type: string
  indicators: [ url ]
```

### 검증

다음 아래에서 `validate` 키에 대해, 들어오는 로그가 이 스키마와 일치하려면 충족해야 하는 필드 값 조건을 지정할 수 있습니다.

다음을 사용하는 것도 가능합니다. `validate` 다음에서 `element` 키에서( `type: string`) 배열 값의 각 요소에 대해 검증을 수행할 수 있습니다.

#### `allow` 및 `deny` 검증

다음을 선언하여 `string` 유형의 값을 허용 목록 또는 거부 목록으로 검증할 수 있습니다. 필드 값이 `allow`/`deny` 의 값과 일치하거나 일치하지 않는 로그만 이 스키마로 파싱됩니다. 즉, 공통적으로 겹치는 필드를 가지지만 해당 필드의 값이 다른 여러 로그 유형을 둘 수 있습니다.

```yaml
# 'login' 및 'logout' event_type 값만 이 로그 유형과 일치하도록 허용합니다
- 이름: event_type
  type: string
  validate:
    allow: [ "login", "logout"]
    
# 로그에 'login'과 'logout'이 아닌 event_type 값이 있으면 일치합니다
- 이름: event_type
  type: string
  validate:
    deny: [ "login", "logout"]
    
# 문자열 배열 요소와도 사용할 수 있습니다    
# 값이 'info' 또는 'low'인 severities 필드가 있는 로그와 일치합니다 
- name: severities
  type: array
  element:
    type: string
    validate:
      allow: ["info", "low"]
```

#### `allowContains` 및 `denyContains` 검증

다음을 사용하여 문자열 값에 특정 부분 문자열이 포함되거나 포함되지 않는지 검증할 수 있습니다. `allowContains` 및 `denyContains`. 이는 정확한 값이 아니라 부분 문자열 내용에 따라 로그 유형을 일치시켜야 할 때 유용합니다.

```yaml
# message 값에 'error' 또는 'fail'이 포함된 로그만 일치합니다
- name: message
  type: string
  validate:
    allowContains: ["error", "fail"]
    
# message 값에 'password' 또는 'secret'이 포함되지 않은 로그와 일치합니다
- name: message
  type: string
  validate:
    denyContains: ["password", "secret"]
    
# 문자열 배열 요소와도 사용할 수 있습니다
# 'critical' 또는 'warning'이 포함된 tags 값이 있는 로그와 일치합니다
- name: tags
  type: array
  element:
    type: string
    validate:
      allowContains: ["critical", "warning"]
```

#### `ip` 및 `cidr` 형식 검증

다음의 값 `string` type은 잘 알려진 형식에 맞도록 제한할 수 있습니다. 현재 Panther는 `ip` 및 `cidr` 형식을 지원하여 문자열 값이 유효한 IP 주소 또는 CIDR 범위인지 요구합니다.

`ip` 및 `cidr` 검증은 다음과 결합할 수 있습니다. `allow`, `deny`, `allowContains`, 또는 `denyContains` 규칙이지만, 그렇게 하는 것은 다소 중복적입니다. 예를 들어, 두 IP 주소를 허용한 경우 `ip` 검증을 추가하는 것은 목록의 IP 주소가 유효하지 않을 때 검증에 오탐이 포함되지 않도록 보장할 뿐입니다.

```yaml
# 유효한 ipv4 IP 주소를 허용합니다. 예: 100.100.100.100
- name: address
  type: string
  validate:
    ip: "ipv4"
    
# 유효한 ipv6 CIDR 범위를 허용합니다 
# 예: 2001:0db8:85a3:0000:0000:0000:0000:0000/64
- name: address
  type: string
  validate:
    cidr: "ipv6"
    
# 유효한 모든 ipv4 또는 ipv6 주소를 허용합니다
- name: address
  type: string
  validate:
    ip: "any"
    
# addresses 배열의 모든 요소는 유효한 ipv4 ID 주소여야 합니다
- name: addresses
  type: array
  element:
    type: string
    validate:
      ip: "ipv4"
```

## IDE에서 JSON Schema 사용하기

코드 편집기 또는 통합 개발 환경(IDE)이 [JSON Schema](https://json-schema.org/)를 지원한다면 [이 스키마 파일](https://panther-community-us-east-1.s3.amazonaws.com/latest/logschema/schema.json) 을 Panther 스키마에 사용하고 [이 schema-tests 파일](https://panther-community-us-east-1.s3.amazonaws.com/latest/logschema/schema-tests.json) 을 스키마 테스트에 사용하도록 구성할 수 있습니다. 이렇게 하면 Panther 스키마와 테스트를 개발하는 동안 제안과 오류 메시지를 받을 수 있습니다.

### JetBrains 사용자 지정 JSON 스키마

다음을 참조하세요. [JetBrains 문서](https://www.jetbrains.com/help/phpstorm/json.html#ws_json_schema_add_custom) 에서 JetBrains IDE를 사용자 지정 JSON Schema와 함께 사용하는 구성 방법을 확인하세요.

### VSCode 사용자 지정 JSON 스키마

다음을 참조하세요. [VSCode 문서](https://code.visualstudio.com/Docs/languages/json#_json-schemas-and-settings) 에서 VSCode를 JSON Schema와 함께 사용하는 구성 방법을 확인하세요.

## 스트림 유형

Panther 콘솔에서 다음과 같은 특정 작업을 수행할 때 [데이터 전송용 S3 버킷 구성 ](https://docs.panther.com/ko/data-onboarding/data-transports/aws/s3)또는 [원시 로그에서 사용자 지정 스키마 추론](https://docs.panther.com/ko/data-onboarding/custom-log-types/..#infer-a-schema-from-raw-data)와 같은 작업을 할 때 로그 스트림 유형을 선택해야 합니다.

아래 각 유형에 대한 예제 로그 이벤트를 확인하세요.

<table><thead><tr><th width="144">스트림 유형</th><th width="205">설명</th><th>예제 로그 이벤트</th></tr></thead><tbody><tr><td>자동</td><td>Panther가 적절한 스트림 유형을 자동으로 감지합니다.</td><td>해당 없음</td></tr><tr><td>줄</td><td>이벤트는 줄바꿈 문자로 구분됩니다.</td><td><pre class="language-json"><code class="lang-json">"10.0.0.1","user-1@example.com","France"
"10.0.0.2","user-2@example.com","France"
"10.0.0.3","user-3@example.com","France"
</code></pre></td></tr><tr><td>JSON</td><td>이벤트는 JSON 형식입니다.</td><td><pre class="language-json"><code class="lang-json">{ 
    "ip": "10.0.0.1", 
    "un": "user-1@example.com", 
    "country": "France" 
}
또는
{ "ip": "10.0.0.1", "un": "user-1@example.com", "country": "France" }{ "ip": "10.0.0.2", "un": "user-2@example.com", "country": "France" }{ "ip": "10.0.0.3", "un": "user-3@example.com", "country": "France" }
또는
{ "ip": "10.0.0.1", "un": "user-1@example.com", "country": "France" }
{ "ip": "10.0.0.2", "un": "user-2@example.com", "country": "France" }
{ "ip": "10.0.0.3", "un": "user-3@example.com", "country": "France"또는
</code></pre></td></tr><tr><td>JSON 배열</td><td><p>이벤트는 JSON 객체 배열 안에 있습니다.<br></p><p>또는<br><br>이벤트는 JSON 객체 배열 안에 있으며, 이는 최상위 객체의 키에 대한 값입니다. 이를 "봉투형 배열(enveloped array)"이라고도 합니다.</p></td><td><pre class="language-json"><code class="lang-json">[
	{ "ip": "10.0.0.1", "username": "user-1@example.com", "country": "France" },
	{ "ip": "10.0.0.2", "username": "user-2@example.com", "country": "France" },
	{ "ip": "10.0.0.3", "username": "user-3@example.com", "country": "France" }
]
또는
{ "events": [
        { "ip": "10.0.0.1", "username": "user-1@example.com", "country": "France" },
	{ "ip": "10.0.0.2", "username": "user-2@example.com", "country": "France" },
	{ "ip": "10.0.0.3", "username": "user-3@example.com", "country": "France" }
    ] 
}
</code></pre></td></tr><tr><td>CloudWatch Logs</td><td>이벤트는 CloudWatch Logs에서 왔습니다.</td><td><pre class="language-json"><code class="lang-json">{
  "owner": "111111111111",
  "logGroup": "services/foo/logs",
  "logStream": "111111111111_CloudTrail/logs_us-east-1",
  "messageType": "DATA_MESSAGE",
  "logEvents": [
      {
          "id": "31953106606966983378809025079804211143289615424298221568",
          "timestamp": 1432826855000,
          "message": "{\"ip\": \"10.0.0.1\", \"user\": \"user-1@example.com\", \"country\": \"France\"}"
      },
      {
          "id": "31953106606966983378809025079804211143289615424298221569",
          "timestamp": 1432826855000,
          "message": "{\"ip\": \"10.0.0.2\", \"user\": \"user-2@example.com\", \"country\": \"France\"}"
      },
      {
          "id": "31953106606966983378809025079804211143289615424298221570",
          "timestamp": 1432826855000,
          "message": "{\"ip\": \"10.0.0.3\", \"user\": \"user-3@example.com\", \"country\": \"France\"}"
      }
  ]
}
</code></pre></td></tr><tr><td>XML</td><td>이벤트는 XML 형식입니다. 이벤트는 최상위 수준에 있거나 <a href="#xml-root-element-support">루트 요소로 둘러싸여 있습니다</a>. XML 파싱 방식에 대해 자세히 알아보려면 <a href="#xml-stream-type">XML 스트림 유형</a>.</td><td><pre class="language-xml"><code class="lang-xml">&#x3C;log>
    &#x3C;id>1&#x3C;/id>
    &#x3C;data>first log&#x3C;/data>
&#x3C;/log>
&#x3C;log>
    &#x3C;id>2&#x3C;/id>
    &#x3C;data>second log&#x3C;/data>
&#x3C;/log>
또는
&#x3C;logs>
    &#x3C;log>
        &#x3C;id>1&#x3C;/id>
        &#x3C;data>first log&#x3C;/data>
    &#x3C;/log>
    &#x3C;log>
        &#x3C;id>2&#x3C;/id>
        &#x3C;data>second log&#x3C;/data>
    &#x3C;/log>
&#x3C;/logs>
</code></pre></td></tr></tbody></table>

### JSON 배열 스트림 유형

JSON 배열 스트림 유형에서는 이벤트 배열이 "봉투형 배열"인지, 즉 이벤트 필드의 값인지 여부를 지정할 수 있습니다.

{% hint style="warning" %}
JSON 배열의 "봉투형 배열" 옵션은 Panther 콘솔에서 로그 세트에 대해 스키마를 테스트할 때 지원되지 않습니다.
{% endhint %}

<figure><img src="https://2400888838-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2FtATi0eJ6kqV0nddRlcvd%2FScreenshot%202025-11-28%20at%201.37.02%E2%80%AFPM.png?alt=media&#x26;token=046f0643-f2e2-4faf-860f-ec037745dc05" alt="" width="563"><figcaption></figcaption></figure>

### CloudWatch Logs 스트림 유형

CloudWatch Logs 스트림 유형에서는 선택적으로 [**봉투 필드 보존**](https://docs.panther.com/ko/data-transports/aws/cloudwatch#envelope-field-retention) 을 활성화하여 최상위 봉투 메타데이터(예: `owner`, `logGroup`, 및 `logStream`)를 각 처리된 이벤트의 `p_header` 필드)를 각 처리된 이벤트에 보존할 수 있습니다.

CloudWatch Logs 구독은 다음과 같은 봉투로 이벤트를 전달합니다:

```json
{
  "owner": "111111111111",
  "logGroup": "services/foo/logs",
  "logStream": "111111111111_CloudTrail/logs_us-east-1",
  "messageType": "DATA_MESSAGE",
  "logEvents": [
    {
      "id": "31953106606966983378809025079804211143289615424298221568",
      "timestamp": 1432826855000,
      "message": "{\"ip\": \"10.0.0.1\", \"username\": \"user-1@example.com\", \"country\": \"France\"}"
    },
    {
      "id": "31953106606966983378809025079804211143289615424298221569",
      "timestamp": 1432826855000,
      "message": "{\"ip\": \"10.0.0.2\", \"username\": \"user-2@example.com\", \"country\": \"France\"}"
    }
  ]
}
```

봉투 필드 보존이 활성화되면 각 처리된 이벤트에는 봉투 메타데이터가 `p_header` 필드에 포함됩니다:

```json
{
  "ip": "10.0.0.1",
  "username": "user-1@example.com",
  "country": "France",
  "p_header": {
    "owner": "111111111111",
    "logGroup": "services/foo/logs",
    "logStream": "111111111111_CloudTrail/logs_us-east-1"
  }
}
```

참조하세요 [Envelope 필드 보존](https://docs.panther.com/ko/data-transports/aws/cloudwatch#envelope-field-retention) 이를 활성화하려면 지침을 참조하세요.

### XML 스트림 유형

XML 로그 이벤트를 파싱할 때 Panther는 XML 요소를 JSON 객체로 변환합니다. 즉, 높은 수준에서 요소 이름은 키가 되고 텍스트 콘텐츠는 값이 됩니다. [XML 로그용 사용자 지정 스키마를 만드는 방법에 대해 자세히 알아보려면 여기를 참조하세요](https://docs.panther.com/ko/data-onboarding/custom-log-types/..#writing-schemas).

#### **XML 루트 요소 지원**

Panther는 로그 이벤트가 루트 요소 내에 포함된 XML 파일을 파싱하는 것을 지원합니다(이벤트가 최상위 요소인 파일 지원과 별개로). 루트 요소를 지정하면 Panther는 그 안에 포함된 개별 이벤트를 추출하여 각 자식 요소를 별도의 로그 이벤트로 처리합니다.

루트 요소에 포함된 이벤트를 파싱하려면 Panther에서 스트림 유형을 선택할 때:

1. 스트림 유형으로 **XML**.
2. 를 설정하세요 **XML 이벤트가 루트 요소에 포함되어 있나요?** 토글을 **예**.
3. 다음 **XML 루트 요소** 필드에 루트 요소 이름을 입력합니다(예: `logs`, `events`, `data`).

   <figure><img src="https://2400888838-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-620f522780e1f5478f8727cf21fe2a2540f2233d%2FScreenshot%202025-09-15%20at%204.29.54%E2%80%AFPM.png?alt=media" alt="Various form fields are circled: A radio button labeled &#x22;XML,&#x22; a toggle set to &#x22;Yes,&#x22; a text field labeled &#x22;XML Root Element,&#x22; etc."><figcaption></figcaption></figure>

#### **XML 처리 규칙**

보다 자세히 살펴보면, Panther가 XML 파일을 처리하는 방식은 다음과 같습니다:

* 최상위 XML 요소는 각각 별도의 이벤트로 처리됩니다. 단, [루트 요소가 지정된 경우](#xml-root-element-support)에는 Panther가 해당 요소 내부에서 이벤트를 추출합니다.
  * 중첩된 요소는 중첩 객체로 감싸집니다.
* 요소 이름은 필드 이름이 됩니다.
  * 같은 중첩 수준에 있는 여러 요소가 같은 이름을 가지면, 키가 공통 요소 이름이고 값이 요소 내용(즉, 텍스트 내용, 속성, 중첩 필드 등)의 배열인 배열 필드가 생성됩니다.
* 텍스트 내용은 필드 값이 됩니다.
  * 요소에 텍스트 내용만 있고(속성이나 중첩 요소가 없는 경우), 텍스트 내용은 필드 값으로 직접 파싱됩니다.
  * 요소에 1) 텍스트 내용과 2) 하나 이상의 속성 또는 중첩 요소가 모두 있으면, 텍스트 내용은 다음의 값으로 저장됩니다: `text` 키.
  * 요소가 비어 있으면(즉, 텍스트 내용이 없으면), 값은 다음으로 지정됩니다: `null`.
  * 텍스트 내용이 하나 이상의 요소에 의해 분리되면, 각 부분 사이에 공백을 두고 이어붙입니다.
* 요소 속성(예: `<User role="admin">`)은 텍스트 내용과 함께 공유 중첩 객체의 키/값 쌍으로 추가됩니다.
  * 속성 이름이 중첩 요소 이름과 충돌하는 경우(결과 중첩 객체에서 필드 이름이 되며, 속성 이름과 같음), 속성 이름에 다음이 추가됩니다: `_attr` 접미사. 속성 이름이 `text` 이고 요소에 텍스트 내용이 있으면(이 경우 중첩 `text` 키가 생성됨), 속성 필드는 다음이 됩니다: `text_attr`.
  * 그 `xmlns` 속성(XML 네임스페이스를 선언함)은 자동으로 건너뜁니다.

예시 XML 입력:

```xml
<logs> 
    <log>
        <id>1</id>
        <data>first log</data>
        <user></user>
    </log>
    <log>
        <id>2</id>
        <data level="info">second log</data>
    </log>
    <log>
        <id>3</id>
        <data>
            요소 앞의 텍스트
            <source>app</source>
            요소 뒤의 텍스트
        </data>
    </log>
    <log>
        <data>fourth log
            <severity text="sev">high</severity>
        </data>
    </log>
    <log>
        <data id="123" name="John">
            <name>John1</name>
            <name>John2</name>
        </data>
    </log>
</logs>
```

Panther는 다음과 같이 처리합니다:

```json
{"id":"1","data":"first log","user":null}
{"id":"2","data":{"text":"second log","level":"info"}}
{"id":"3","data":{"text":"text before element text after element","source":"app"}}
{"data":{"text":"fourth log","severity":{"text_attr":"sev","text":"high"}}}
{"data":{"id":"123","name_attr":"John","name":["John1","John2"]}}
```
