> For the complete documentation index, see [llms.txt](https://docs.panther.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.panther.com/ko/panther/api/graphql/alerts-and-errors.md).

# 알러트 및 오류

## 개요

Panther API는 다음 알러트 관련 작업을 지원합니다:

* 선택적 필터로 알러트와 오류를 나열하기
* 특정 알러트의 세부 정보를 가져오기
* 알러트와 관련된 로그 이벤트를 가져오기
* 하나 이상의 알러트 상태를 업데이트하기
* 알러트에 댓글을 추가하기
* 다음 정보를 제공하여 하나 이상의 알러트에 사용자를 할당하거나 할당 해제하기:
  * 사용자 ID
  * 사용자 이메일 주소

Console의 API Playground 또는 GraphQL-over-HTTP API를 사용하여 Panther의 API를 호출할 수 있습니다. 이러한 방법에 대해 자세히 알아보려면 [Panther API](/ko/panther/api.md#step-1-choose-a-method-for-invoking-the-api).

핵심 알러트 및 오류 작업에 대한 GraphQL 쿼리, 뮤테이션, 엔드투엔드 워크플로 예시는 아래 섹션을 참조하세요.

## 일반적인 알러트 및 오류 작업

아래는 Panther에서 가장 일반적인 GraphQL 알러트 및 오류 작업 중 일부입니다. 이 예시는 GraphQL 클라이언트(또는 `curl`)를 사용하여 Panther의 GraphQL API를 호출할 때 보내야 하는 문서를 보여줍니다.

#### 알러트 나열하기

해당 `알러트` 쿼리에는 다음이 필요합니다 `input` 다음을 포함하는 객체 `createdAtAfter` 및 `createdAtBefore`.

{% tabs %}
{% tab title="모든 알러트의 첫 페이지" %}

```graphql
# `FirstPageOfAll알러트들`는 해당 작업의 별칭입니다
query FirstPageOfAll알러트들 {
    알러트들(input: { 
      createdAtAfter: "2022-01-01T00:00:00.000Z"
      createdAtBefore: "2023-01-01T00:00:00.000Z"
    }) {
      edges {
        node { # 여기서 더 많은 알러트 관련 필드를 요청할 수 있습니다
          id
          title
          severity
          status
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
```

{% endtab %}

{% tab title="알러트의 다음 페이지" %}

```graphql
# `AnotherPageOfAll알러트들`는 해당 작업의 별칭입니다
query AnotherPageOfAll알러트들 {
    알러트들(input: { 
      createdAtAfter: "2022-01-01T00:00:00.000Z",
      createdAtBefore: "2023-01-01T00:00:00.000Z",
      cursor: "{\"creationTime\":{\"B\":null,\"BOOL\":null,\"BS\":null,\"L\":null,\"M\":null,\"N\":null,\"NS\":null,\"NULL\":null,\"S\":\"2022-08-11T21:16:12Z\",\"SS\":null},\"id\":{\"B\":null,\"BOOL\":null,\"BS\":null,\"L\":null,\"M\":null,\"N\":null,\"NS\":null,\"NULL\":null,\"S\":\"6472742357f3488aeb3f48a9c5da9262\",\"SS\":null},\"알러트MonthPartition\":{\"B\":null,\"BOOL\":null,\"BS\":null,\"L\":null,\"M\":null,\"N\":null,\"NS\":null,\"NULL\":null,\"S\":\"202208\",\"SS\":null}}"
    }) {
      edges {
        node { # 여기서 더 많은 알러트 관련 필드를 요청할 수 있습니다
          id
          title
          severity
          status
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
```

{% endtab %}

{% tab title="필터링된 알러트 페이지" %}

```graphql
# `FilteredPageOf알러트들`는 해당 작업의 별칭입니다
query FilteredPageOf알러트들 {
    알러트들(input: { 
      createdAtAfter: "2022-01-01T00:00:00.000Z",
      createdAtBefore: "2023-01-01T00:00:00.000Z",
      severities: [LOW], 
      statuses: [OPEN] 
    }) { 
      edges {
        node { # 여기서 더 많은 알러트 관련 필드를 요청할 수 있습니다
          id
          title
          severity
          status
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
```

{% endtab %}
{% endtabs %}

#### 알러트를 설명하기

```graphql
query 알러트Details {
    알러트(id: "FAKE_알러트_ID") {
       id
       title
       severity
       status
    }
  }
```

#### 알러트에서 디택션 또는 시스템 오류 정보를 가져오기

```graphql
query 알러트Details {
    알러트(id: "FAKE_알러트_ID") {
       id
       title
       severity
       origin {
         ... on 디택션 {
           id
           name
         }
         ... on 시스템오류 {
           관련 구성 요소
           유형
         }
       }
    }
  }
```

#### 알러트와 관련된 로그 이벤트를 가져오기

```graphql
query FirstPageOf알러트Events {
  알러트(id: "FAKE_알러트_ID") {
    id,
    events(input: {
      cursor: "",
      pageSize: 25
    }) {
      edges {
        node
      }
      pageInfo {
        endCursor
      }
    }
  }
}
```

#### 하나 이상의 알러트 상태를 업데이트하기

```graphql
mutation Update알러트Status {
    update알러트StatusById(
       input: {
          ids: ["FAKE_알러트_ID_1","FAKE_알러트_ID_2"]
          상태: CLOSED # 하드코딩되어 있을 때는 이것이 문자열이 아니라는 점에 주목하세요(이는 `enum`입니다)
       }
    ) {
       알러트 {
         id
         status
       }
    }
  }
```

#### 알러트에 댓글을 추가하기

```graphql
변이 Create알러트Comment {
    create알러트Comment(
       input: {
          알러트Id: "FAKE_AL러트_ID"
          본문: "<p>이것은 HTML입니다</p>"
          형식: HTML # 원하면 HTML 구문 분석을 비활성화할 수도 있습니다
       }
    ) {
       댓글 {
         id
       }
    }
 
```

#### 사용자 ID를 제공하여 하나 이상의 알러트에 사용자를 할당하고 할당 해제하기

```graphql
변이 Update알러트sAssigneeById {
  updateAlertsAssigneeById(
    input: {
      assigneeId: "FAKE_USER_ID"
      ids: ["FAKE_알러트_ID_1","FAKE_알러트_ID_2"]
    }
  ) {
    알러트 {
      assignee {
        email
        givenName
        familyName
        id
      }
    }
  }
}
```

#### 사용자 이메일 주소를 제공하여 하나 이상의 알림에 사용자를 할당하거나 할당 해제합니다

```graphql
mutation UpdateAlertsAssigneeByEmail {
  updateAlertsAssigneeByEmail(
    input: {
      assigneeEmail: "fake@email.com"
      ids: ["FAKE_알러트_ID_1","FAKE_알러트_ID_2"]
    }
  ) {
    알러트 {
      assignee {
        email
        givenName
        familyName
        id
      }
    }
  }
}
```

## 엔드투엔드 예시

아래에서는 다음을 기반으로 설명하겠습니다: [일반 작업](#common-operations) 엔드투엔드 흐름을 보여주는 예시.

#### 특정 알림 집합을 찾아 다음으로 표시합니다 *해결됨:*

{% tabs %}
{% tab title="NodeJS" %}

```javascript
// npm install graphql graphql-request

import { GraphQLClient, gql } from 'graphql-request';

const client = new GraphQLClient(
  'YOUR_PANTHER_API_URL', 
  { headers: { 'X-API-Key': 'YOUR_API_KEY' } 
});

// `FindAlerts`는 쿼리의 닉네임입니다. 완전히 생략할 수 있습니다.
const findAlerts = gql`
  query FindAlerts($input: AlertsInput!) {
  알러트(input: $input) {
    edges {
      node {
        id
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
`;

// `UpdateAlerts`는 쿼리의 별칭입니다. 완전히 생략할 수 있습니다.
const updateAlerts = gql`
  mutation UpdateAlerts($input: UpdateAlertStatusByIdInput!) {
    updateAlertStatusById(input: $input) {
      알러트 {
        id
      }
    }
  }
`;

(async () => {
  try {
    
    // 모든 페이지에서 가져온 모든 알림을 보관하는 누산기
    let allAlerts = [];
    // 루프를 언제 종료할지 알기 위한 헬퍼
    let hasMore = true;
    // 페이지네이션 커서
    let cursor = null;

    // 더 이상 남은 페이지가 없을 때까지 계속 가져오기
    do {
      const queryData = await client.request(findAlerts, {
        input: {
          severities: ["LOW"],
          createdAtAfter: "2022-02-01T00:00:00.000Z",
          createdAtBefore: "2022-03-01T00:00:00.000Z",
          cursor
        }
      });

      allAlerts = [
        ...allAlerts,
        ...queryData.알러트s.edges.map((edge) => edge.node)
      ];
      
      hasMore = queryData.알러트s.pageInfo.hasNextPage;
      cursor = queryData.알러트s.pageInfo.endCursor;
    } while (hasMore);

    // 이제 알러트들을 업데이트합니다
    if (!all알러트s.length) {
      console.log("해결할 알러트들을 찾을 수 없습니다");
      return;
    }
    const mutationData = await client.request(update알러트s, {
      input: {
        ids: all알러트s.map((알러트) => 알러트.id),
        상태: "RESOLVED"
      }
    });

    console.log(
      `${mutationData.update알러트StatusById.알러트.length}개의 알러트가 해결되었습니다!`
    );
  } catch (err) {
    console.error(err.response);
  }
})();

```

{% endtab %}

{% tab title="Python" %}

```python
# pip install gql aiohttp

from gql import gql, Client
from gql.transport.aiohttp import AIOHTTPTransport

transport = AIOHTTPTransport(
  url="YOUR_PANTHER_API_URL",
  headers={"X-API-Key": "YOUR_API_KEY"}
)

client = Client(transport=transport, fetch_schema_from_transport=True)

# `Find알러트`는 쿼리의 별칭입니다. 완전히 생략할 수 있습니다.
find_알러트 = gql(
    """
    query FindAlerts($input: AlertsInput!) {
      알러트(input: $input) {
        edges {
          node {
            id
          }
        }
        pageInfo {
          hasNextPage
          endCursor
        }
      }
    }
    """
)

# `Update알러트`는 쿼리의 별칭입니다. 완전히 생략할 수 있습니다.
update_알러트 = gql(
    """
    mutation UpdateAlerts($input: UpdateAlertStatusByIdInput!) {
      updateAlertStatusById(input: $input) {
        알러트 {
          id
        }
      }
    }
    """
)

# 가져오는 모든 페이지의 모든 알러트를 담는 누산기
all_알러트 = []
# 루프를 언제 종료할지 알기 위한 헬퍼
has_more = True
# 페이지네이션 커서
cursor = None

# 더 이상 남은 페이지가 없을 때까지 계속 페이지를 가져옵니다
while has_more:
    query_data = client.execute(
        find_알러트,
        variable_values={
            "input": {
                "severities": ["LOW"],
                "createdAtAfter": "2022-02-01T00:00:00.000Z",
                "createdAtBefore": "2022-03-01T00:00:00.000Z",
                "cursor": cursor
            }
        }
    )

    all_알러트.extend([edge["node"] for edge in query_data["알러트"]["edges"]])
    has_more = query_data["알러트"]["pageInfo"]["hasNextPage"]
    cursor = query_data["알러트"]["pageInfo"]["endCursor"]

# 이제 알러트를 업데이트합니다
if not len(all_알러트):
    print("해결할 알러트를 찾을 수 없습니다")
else:
    mutation_data = client.execute(
        update_알러트,
        variable_values={
            "input": {
                "ids": [알러트["id"] for 알러트 in all_알러트],
                "status": "RESOLVED"
            }
        }
    )

    print(f'{len(mutation_data["update알러트StatusById"]["알러트"])}개의 알러트가 해결되었습니다!')
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.panther.com/ko/panther/api/graphql/alerts-and-errors.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
