이 페이지에서는 Grafana 사용자 인터페이스를 사용하여 로그를 쿼리하고 시각화하여 서비스 이벤트와 활동에 대한 유용한 정보를 얻는 방법을 자세히 설명합니다.
Google Distributed Cloud (GDC) 에어 갭 어플라이언스에 배포된 워크로드와 서비스에서 로그를 수집한 후 분석을 시작할 수 있습니다. 로그를 분석하려면 유용한 Grafana 패널 또는 프로그래매틱 액세스를 위한 gRPC 호출에서 로그를 시각화하고 필터링하면 됩니다.
다음 방법으로 로그에 액세스할 수 있습니다.
- Grafana 패널: Grafana 인스턴스의 로그 패널을 통해 프로젝트의 활동 기록에 대한 유용한 정보를 얻을 수 있습니다. 이 패널을 사용하면 특정 로그를 쿼리하고 정확히 찾아낼 수 있으므로 필요에 맞게 세부적인 데이터 관측 가능성을 제공합니다. Grafana는 워크로드 데이터를 필터링하고 분석하며, 포괄적인 시각화를 위한 맞춤 대시보드와 패널을 만들 수 있는 사용자 친화적인 인터페이스를 제공합니다.
시작하기 전에
Grafana 사용자 인터페이스에서 로그를 쿼리하고 시각화하는 데 필요한 권한을 얻으려면 조직 IAM 관리자 또는 프로젝트 IAM 관리자에게 사전 정의된 조직 Grafana 뷰어 또는 프로젝트 Grafana 뷰어 역할 중 하나를 부여해 달라고 요청하세요. 필요한 액세스 수준과 권한에 따라 조직 또는 프로젝트에서 Grafana 역할을 획득할 수 있습니다.
또는 로그 쿼리 API에서 로그를 쿼리하는 데 필요한 권한을 얻으려면 프로젝트 IAM 관리자에게 프로젝트 네임스페이스에서 로그 쿼리 API 쿼리자 역할을 부여해 달라고 요청하세요.
이러한 역할에 대한 자세한 내용은 IAM 권한 준비를 참고하세요.
로그 쿼리 빌드
시스템 모니터링 인스턴스의 UI에서 로그를 쿼리하면 프로젝트에서 운영 로그를 가져올 데이터 소스를 선택하고 쿼리의 통합 보기를 확인할 수 있습니다. 결과를 필터링하려면 쿼리 언어 표현식을 사용하여 라벨별로 로그를 검색합니다. 예를 들어 쿼리에서 cluster
및 namespace
라벨을 각각 클러스터와 프로젝트 네임스페이스를 식별하는 값으로 설정할 수 있습니다.
시스템 모니터링 인스턴스 엔드포인트
애플리케이션 운영자 (AO)인 경우
다음 URL은 프로젝트의 모니터링 인스턴스의 엔드포인트입니다.
https://GDC_URL/PROJECT_NAMESPACE/grafana
다음을 바꿉니다.
- GDC_URL: GDC의 조직 URL입니다.
- PROJECT_NAMESPACE: 프로젝트의 네임스페이스입니다.
플랫폼 관리자 (PA)인 경우
다음 URL은 프로젝트의 모니터링 인스턴스의 엔드포인트입니다.
https://GDC_URL/platform-obs/grafana
GDC_URL를 GDC의 조직 URL로 바꿉니다.
로그 쿼리 및 필터링
다음 방법 중 하나를 선택하여 쿼리를 빌드하고 프로젝트 워크로드에서 로그를 필터링합니다.
이 섹션에서는 Grafana의 로그 패널을 사용하여 로그에 액세스하는 방법을 설명합니다.
Grafana 엔드포인트 식별
애플리케이션 운영자 (AO)인 경우
다음 URL은 프로젝트의 모니터링 인스턴스의 엔드포인트입니다.
https://GDC_URL/PROJECT_NAMESPACE/grafana
다음을 바꿉니다.
- GDC_URL: GDC의 조직 URL입니다.
- PROJECT_NAMESPACE: 프로젝트의 네임스페이스입니다.
플랫폼 관리자 (PA)인 경우
다음 URL은 프로젝트의 모니터링 인스턴스의 엔드포인트입니다.
https://GDC_URL/platform-obs/grafana
GDC_URL를 GDC의 조직 URL로 바꿉니다.
Grafana 사용자 인터페이스에서 로그 보기
Grafana 사용자 인터페이스에서 로그를 쿼리합니다.
- GDC 콘솔에서 프로젝트를 선택합니다.
- 탐색 메뉴에서 작업 > 로깅을 선택합니다.
- Grafana Loki에서 모두 보기를 클릭합니다.
새 페이지에 Grafana 엔드포인트가 열리고 사용자 인터페이스가 표시됩니다.
- 사용자 인터페이스의 탐색 메뉴에서 탐색 탐색을 클릭하여 탐색 페이지를 엽니다.
- 탐색 표시줄의 메뉴에서 유니버스 유형에 따라 로그를 가져올 데이터 소스를 선택합니다.
단일 영역 유니버스: 유니버스의 단일 영역에서 로깅 데이터를 표시하려면 다음 데이터 소스 중 하나를 선택합니다.
작업 로그: 작업 로그를 표시합니다.
감사 로그: 감사 로그를 표시합니다.
운영 로그 ZONE_NAME: 특정 영역의 운영 로그를 표시합니다.
감사 로그 ZONE_NAME: 특정 영역의 감사 로그를 표시합니다.
또한 단일 대시보드에서 교차 영역 데이터 시각화를 표시하고 쿼리에 여러 영역을 추가하려면 데이터 소스로 혼합을 선택합니다.
LogQL (로그 쿼리 언어) 표현식을 사용하여 로그 패널에서 로그를 검색하는 쿼리를 입력합니다. 이 단계는 다음 두 가지 방법 중 하나로 수행할 수 있습니다.
- 대화형 쿼리 빌더 인터페이스를 사용합니다. 그런 다음 쿼리 실행을 클릭합니다.
- 텍스트 필드에 직접 쿼리를 입력하고 Shift+Enter를 눌러 쿼리를 실행합니다.
페이지에 쿼리와 일치하는 로그가 표시됩니다. 로그를 쿼리한 후 내보낼 수 있습니다. 내보내기를 클릭하여 일반 텍스트 또는 CSV 형식으로 로그를 다운로드합니다. 로그의 시간 범위를 선택할 수도 있습니다.
그림 1. Grafana 사용자 인터페이스에서 감사 로그를 쿼리하는 메뉴 옵션
그림 1에서 감사 로그 옵션은 Grafana에서 감사 로그를 가져오는 쿼리를 빌드할 수 있는 인터페이스를 표시합니다.
다양한 로그를 쿼리하는 라벨 및 값의 예는 샘플 쿼리 및 라벨을 참고하세요.
로그의 기간 선택
특정 기간의 로그를 쿼리하려면 다음 단계를 따르세요.
Grafana에서
시간 선택기 메뉴를 클릭합니다.메뉴에서 다음 작업 중 하나를 수행합니다.
- 상대 시간 범위 옵션(예: 지난 30분)을 선택합니다.
- 캘린더에서 특정 날짜와 시간을 선택하고 기간 적용을 클릭하여 맞춤 절대 기간을 설정합니다.
선택적으로 시간 설정 변경을 클릭하여 시간 범위 컨트롤에서 시간대 및 회계연도 설정을 변경할 수 있습니다.
시간 설정은 대시보드별로 저장됩니다. 일정 기간에 대한 쿼리에 관한 자세한 내용은 https://grafana.com/docs/loki/latest/reference/api/#query-loki-over-a-range-of-time을 참고하세요.
쿼리 보내기
HTTP 또는 gRPC 클라이언트를 사용하여 로그 쿼리 API 엔드포인트에 쿼리를 보냅니다.
HTTP
안내에 따라 HTTP 클라이언트로 API에 직접 액세스합니다.
kubectl
를 사용하여 인증을 관리하거나 직접 인증을 처리할 수 있습니다.curl
,wget
또는 직접 만들고 관리하는 HTTP 클라이언트와 같은 HTTP 클라이언트를 사용하여 로그 쿼리 API를 쿼리합니다. 다음 예에서는curl
도구를 사용하여 API를 쿼리하며wget
명령어에도 유사한 형식을 사용할 수 있습니다.cURL 요청을 인증합니다.
- gdcloud CLI를 다운로드하고 설치합니다.
gdcloud
core/organization_console_url
속성을 설정합니다.gdcloud config set core/organization_console_url https://GDC_URL
GDC_URL
을 GDC의 조직 URL로 바꿉니다.-
gdcloud auth login
사용자와 비밀번호를 사용하여 인증하고 로그인합니다.
지정된 계정의 ID 토큰을 환경 변수로 내보냅니다.
export TOKEN="$($HOME/gdcloud auth print-identity-token --audiences=https://LOG_QUERY_API_ENDPOINT)"
LOG_QUERY_API_ENDPOINT
을 로그를 쿼리할 로그 쿼리 API 엔드포인트 및 연결할 도메인으로 바꿉니다. 따라서audiences
플래그의 값은 예를 들어https://operational-log-query-api.org-1.zone1.google.gdch.test
일 수 있습니다.로그인이 성공하면
gdcloud auth print-identity-token
명령어를 통해 cURL 요청에서 승인 헤더를 사용할 수 있습니다. 자세한 내용은 gdcloud auth print-identity-token을 참고하세요.
프로젝트의 모든 라벨을 나열하려면 다음 쿼리를 전송합니다.
curl -H "Authorization: Bearer ${TOKEN}" \ https://LOG_QUERY_API_ENDPOINT/v1/projects/PROJECT_NAMESPACE/labels \ -H "Content-Type: application/json" -v
다음을 바꿉니다.
LOG_QUERY_API_ENDPOINT
: 로그를 쿼리하려는 로그 쿼리 API 엔드포인트입니다.PROJECT_NAMESPACE
: 프로젝트 네임스페이스
프로젝트의 특정 라벨 값을 나열하려면 다음 쿼리를 전송합니다.
curl -H "Authorization: Bearer ${TOKEN}" \ https://LOG_QUERY_API_ENDPOINT/v1/projects/PROJECT_NAMESPACE/labels/labels/LABEL/values \ -H "Content-Type: application/json" -v
다음을 바꿉니다.
LOG_QUERY_API_ENDPOINT
: 로그를 쿼리하려는 로그 쿼리 API 엔드포인트입니다.PROJECT_NAMESPACE
: 프로젝트 네임스페이스LABEL
: 값을 쿼리하려는 특정 라벨입니다.
특정 프로젝트의 로그를 쿼리하려면
logs_filter
쿼리를 구성하고 요청 본문에 포함합니다.curl -X GET -H "Authorization: Bearer ${TOKEN}" \ https://LOG_QUERY_API_ENDPOINT/v1/projects/PROJECT_NAMESPACE/logs \ -H "Content-Type: application/json" -d \ '{"logs_filter": {"labels_equal": {"LABEL": "LABEL_VALUE"}}}' -v
다음을 바꿉니다.
LOG_QUERY_API_ENDPOINT
: 로그를 쿼리하려는 로그 쿼리 API 엔드포인트입니다.PROJECT_NAMESPACE
: 프로젝트 네임스페이스LABEL
: 로그를 쿼리하려는 특정 라벨입니다.LABEL_VALUE
: 로그를 쿼리할 라벨 값입니다.
logs_filter
쿼리를 구성하는 모든 옵션은 API 문서를 참고하세요.
gRPC
gRPC는 프로그래밍 언어 전반에서 널리 지원되며 HTTP 클라이언트에 비해 더 효율적인 통신 방법을 제공합니다.
gRPC를 사용하여 로그를 쿼리하려면 다음 기본 요건을 충족해야 합니다.
- Google에서 제공하는 프로토콜 버퍼를 기반으로 자체 클라이언트 라이브러리를 만듭니다.
- 클라이언트에서 인증을 구현합니다.
- 재시도를 구현합니다.
프로토콜 버퍼에 대한 자세한 내용은 API 문서를 참고하세요.
다음 예는 인증되지 않은 gRPC 클라이언트를 사용하여 Go 프로그램에서 로그를 쿼리하는 방법을 보여줍니다. 이 예에서는 코드 종속 항목을 가져오는 Bazel 빌드 파일이 포함된 golang 패키지를 만들었다고 가정합니다.
다음 코드를
client.go
이라는 Go 프로그램에 저장합니다.package main import ( "context" "crypto/tls" "flag" "fmt" "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" pb "<import path to generated log query api protos>/pkg/apis/public/logging/v1/proto" "google.golang.org/grpc" ) var serverAddr = flag.String("server", "localhost:8080", "server address") func main() { flag.Parse() tc := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true}) conn, err := grpc.Dial(*serverAddr, grpc.WithTransportCredentials(tc)) if err != nil { panic(error.Error(fmt.Errorf("create client connection failed: %v", err))) } defer conn.Close() c := pb.NewLogsClient(conn) md := metadata.Pairs("clienttest", "test") ctx := metadata.NewOutgoingContext(context.Background(), md) err = listLabels(ctx, c, "project-foo") if err != nil { panic(error.Error(err)) } if err := listLabelValues(ctx, c, "project-foo", "resource-bar"); err != nil { panic(error.Error(err)) } if err := listLogs(ctx, c, "project-foo", &pb.ListLogsFilter{ LabelsEqual: map[string]string{"resource-bar": "resource-bar-value"}, OrderAscending: true, }); err != nil { panic(error.Error(err)) } } // List all labels for a project. func listLabels(ctx context.Context, c pb.LogsClient, project string) error { lbr := &pb.ListLabelsRequest{ Parent: project, PageSize: 1000, // PageSize can be configured to limit the number of responses per page. } resp, err := c.ListLabels(ctx, lbr) if err != nil { return fmt.Errorf("list labels: %v", err) } fmt.Printf("%v", resp) return nil } // List specific label values for a project. func listLabelValues(ctx context.Context, c pb.LogsClient, project string, label string) error { lbr := &pb.ListLabelValuesRequest{ Parent: project, Label: label, PageSize: 1000, // PageSize can be configured to limit the number of responses per page. } resp, err := c.ListLabelValues(ctx, lbr) if err != nil { return fmt.Errorf("list label values: %v", err) } fmt.Printf("%v", resp) return nil } // List logs for a specific project. func listLogs(ctx context.Context, c pb.LogsClient, project string, lf *pb.ListLogsFilter) error { lbr := &pb.ListLogsRequest{ Parent: project, LogsFilter: lf, PageSize: 5, // PageSize can be configured to limit the number of responses per page. } resp, err := c.ListLogs(ctx, lbr) if err != nil { return fmt.Errorf("list logs: %v", err) } fmt.Printf("logs: %v", resp) return nil }
Go 프로그램을 실행합니다.
go run PATH_TO_API/client.go -server=LOG_QUERY_API_ENDPOINT:443
다음을 바꿉니다.
PATH_TO_API
: API 파일의 경로입니다.LOG_QUERY_API_ENDPOINT
: 로그를 쿼리하려는 로그 쿼리 API 엔드포인트입니다.
서버 플래그를 지정하지 않으면 기본 요청이
localhost
에 도달합니다.
샘플 쿼리 및 라벨
다음은 로그를 쿼리하는 데 사용할 수 있는 기본 라벨입니다.
cluster
: 클러스터의 이름입니다.namespace
: 프로젝트 네임스페이스node
: 노드 이름입니다.pod
: 포드 이름입니다.container
: 컨테이너 이름입니다.
다음 코드 샘플은 라벨과 값을 사용하여 다양한 로그를 쿼리하는 방법을 보여줍니다.
서버 로그를 선택합니다.
{cluster="admin", namespace="kube-system", resources="k8s_container", container="kube-apiserver"}
클러스터 감사 로그를 선택합니다.
{cluster="admin", resources="k8s_audit"}