사전 Cloud Logging
구현체

Cloud Logging

gabury1고친 사람 github-actions[bot]

Cloud Logging 은 구글 클라우드에서 돌아가는 것들이 남긴 로그를 한곳에 받아 두는 서비스입니다. 서버에 들어가 파일을 뒤지지 않고 한 화면에서 찾아봅니다. 받은 로그를 어디로 보내고 얼마나 둘지도 이 서비스 안에서 정합니다.

쉽고 빠른 이해
  • 무슨 일을 하나 — 여러 서버와 서비스가 남긴 로그를 한곳에 모아 찾게 해 줍니다. Cloud Run 에서 키와 값을 담은 한 줄을 표준 출력에 찍으면, 그 줄이 심각도와 본문이 나뉜 기록 한 건이 되어 쌓입니다.
  • 왜 이렇게 하나 — 로그가 기계 안에만 있으면 컨테이너가 기계에서 쫓겨날 때 로그도 같이 사라집니다. 기계가 죽으면 그 안의 로그는 볼 수 없습니다. 기계와 따로 사는 저장소에 두어야 장애가 끝난 뒤에도 원인을 찾습니다.
  • 어떻게 도나
    1. 클라우드 서비스와 수집 프로그램이 로그를 한 건씩 보냅니다.
    2. 들어온 로그는 전부 한 관문을 지납니다. 거기 걸어 둔 규칙마다 보낼 곳을 따로 정합니다.
    3. 쌓인 로그는 조건을 걸어 찾거나, 수를 세어 경보에 씁니다.
  • 대가 — 보관 통에 쌓은 양만큼 값이 붙습니다. 정해 둔 기간이 지난 로그는 지워집니다. 로그에 적힌 시각이 그 기간보다 오래되면 처음부터 쌓이지 않습니다. 설정을 바꾼 기록 일부는 지울 수도 기간을 줄일 수도 없습니다.

상세

Cloud Logging 이 하는 일은 로그를 받아 저장하고 찾아 주는 것입니다. 로그는 프로그램이 무슨 일을 했는지 남긴 기록입니다. 구글 클라우드의 자원이 남긴 로그는 따로 설정하지 않아도 이 서비스로 모입니다. 내 애플리케이션, 회사 안의 서버, 다른 클라우드의 자원도 로그를 보낼 수 있습니다.

로그를 기계 밖에 모으는 까닭은 기계가 오래 살지 않기 때문입니다. 쿠버네티스를 예로 듭니다. 쿠버네티스에서 컨테이너를 묶어 띄우는 단위가 파드입니다. 파드가 올라가는 기계가 노드입니다.

컨테이너가 죽거나, 파드가 노드에서 쫓겨나거나, 노드가 죽어도 그 로그는 보고 싶습니다. 컨테이너가 다시 시작할 때는 종료된 컨테이너 하나가 기본으로 로그와 함께 남습니다. 그러나 파드가 쫓겨나면 그 안의 컨테이너가 로그와 함께 빠집니다. 로그가 노드·파드·컨테이너와 별개의 저장소와 수명을 가져야 하는 이유입니다.

쿠버네티스는 그 저장소를 스스로 주지 않습니다. 로그를 저장하고 분석하고 찾아볼 백엔드를 따로 두어야 합니다. Google Kubernetes Engine 에서는 서비스에 들어 있는 수집 프로그램이 컨테이너의 표준 출력과 표준 오류를 Cloud Logging 으로 보냅니다.

예전 이름은 Stackdriver Logging 입니다. 바깥 수집기 Fluent Bit 이 이 서비스로 보내는 출력 플러그인은 지금도 이름이 Stackdriver 입니다.

아래는 로그 한 건의 칸, 들어오는 길, 라우터와 싱크, 버킷, 보는 화면 순으로 따라갑니다.

로그 항목 한 건의 칸

이 서비스가 받는 단위는 파일이 아니라 로그 항목 한 건입니다. 로그 항목은 칸이 정해진 기록입니다. 텍스트 파일을 줄 단위로 읽는 대신 칸마다 값을 받습니다.

칸 담는 것
timestamp 그 일이 일어난 시각. 비워 두면 Cloud Logging 이 현재 시각을 넣습니다
receiveTimestamp Cloud Logging 이 그 항목을 받은 시각
severity 얼마나 급한가. 비워 두면 DEFAULT 입니다
resource 그 항목을 만든 자원
logName 이 항목이 속한 로그의 이름
jsonPayload · textPayload · protoPayload 본문. 셋 가운데 하나에 담습니다. 키와 값의 묶음, 글자 한 줄, 프로토콜 버퍼(구글의 이진 직렬화 형식) 메시지입니다
labels 덧붙이는 키와 값의 쌍
trace · spanId 이 항목이 속한 트레이스의 번호와 그 안의 스팬 번호
insertId 항목마다 붙는 고유 번호. 비워 두면 Cloud Logging 이 붙입니다

logName 이 「로그」라는 낱말의 좁은 뜻을 정합니다. 같은 logName 을 단 항목들의 흐름이 로그 하나입니다. 이 편에서 「로그 수」·「로그 이름」이라고 할 때가 이 뜻입니다.

트레이스는 요청 하나가 여러 서비스를 지나간 흔적입니다. 스팬은 그 트레이스를 이루는 한 구간입니다. 두 번호로 로그와 트레이스를 잇는 방법은 「맞물림」 절에 있습니다.

본문을 JSON(JavaScript Object Notation) 객체로 보내면 jsonPayload 에 담깁니다. 이렇게 담긴 항목을 구조화 로그라고 부릅니다. 본문을 글자 한 줄로 보내면 textPayload 에 담깁니다. 이 항목은 비구조화 로그입니다.

이 둘의 차이가 찾기를 좌우합니다. 구조화 로그는 JSON 경로를 짚어 찾을 수 있습니다. 색인은 찾을 값을 미리 정리해 두어 전부 훑지 않고 찾게 하는 목록입니다. 구조화 로그에는 본문의 특정 필드에 색인을 걸 수도 있습니다. 늘 색인되는 칸에는 본문 칸이 없으니 이 색인은 직접 정해야 하고, 그렇게 정한 칸을 사용자 정의 색인 칸이라고 부릅니다. 비구조화 로그는 그 글자를 뒤질 수는 있지만 내용에 색인을 걸 수는 없습니다.

로그가 들어오는 길

로그가 이 서비스에 닿는 길은 누가 보내느냐로 갈립니다. API(Application Programming Interface)는 프로그램이 다른 프로그램을 부르는 창구입니다. 에이전트는 기계 안에 띄워 두고 로그를 밖으로 실어 나르는 프로그램입니다.

보내는 쪽 어떻게
구글 클라우드 자원 자원이 남기는 로그는 따로 설정하지 않아도 모입니다
Google Kubernetes Engine · App Engine flexible 환경 · Cloud Run functions 서비스 안에 든 에이전트가 표준 출력과 표준 오류에 찍은 것을 보냅니다
Compute Engine 가상 머신 Ops Agent 를 깔아 설정하기를 권합니다. 이 에이전트가 구조화 로그를 보냅니다
애플리케이션이 직접 entries.write API 를 부르거나 클라이언트 라이브러리를 씁니다
사람이 명령으로 gcloud logging write 명령으로 씁니다

자원이 남기는 로그와 그 위에서 도는 프로그램이 찍는 로그는 길이 다릅니다. 표준 출력에 찍기만 하는 프로그램이면 그 출력을 에이전트가 실어 날라야 합니다. 몇몇 서비스는 그 에이전트를 안에 갖고 있습니다. Compute Engine 가상 머신에는 Ops Agent 를 따로 깝니다.

Ops Agent 는 로그와 지표와 트레이스 수집을 프로세스 하나로 묶은 에이전트입니다. 로그 수집에는 Fluent Bit 을 씁니다. 지표와 트레이스 수집에는 OpenTelemetry Collector 를 씁니다. 그 전에 쓰던 Logging 에이전트는 지원이 끝났습니다.

표준 출력에 JSON 한 줄을 찍으면 몇몇 이름의 키는 본문에서 빠져 로그 항목의 칸으로 옮겨집니다. 어느 키가 어느 칸으로 가는지는 「예시」 절에 실물로 있습니다.

로그 라우터와 싱크

들어온 로그 항목은 곧장 저장되지 않습니다. 프로젝트마다 로그 라우터가 하나 있습니다. 모든 항목이 이 라우터를 지납니다. 폴더·조직·결제 계정에도 각각 라우터가 있습니다.

싱크는 라우터에 걸어 두는 전달 규칙입니다. 싱크 하나가 목적지 하나를 가집니다. 싱크는 들어온 항목을 저마다 따로 평가합니다. 그 결과 항목 하나가 여러 싱크를 타고 여러 곳에 갈 수 있습니다.

라우터는 항목을 잠시 붙들어 둡니다. 싱크를 지나는 중에 생기는 일시적인 장애를 버티려는 완충입니다. 이 임시 저장은 설정 실수까지 막아 주지는 않습니다. 설정이 틀린 싱크가 놓친 항목은 고친 뒤에도 다시 보내지 않습니다.

오래 두는 저장은 뒤에 나오는 로그 버킷이 맡습니다. 라우터의 임시 저장과는 다른 저장입니다.

싱크가 항목을 보낼지는 필터 두 종류가 정합니다. 포함 필터는 하나, 제외 필터는 여럿 둘 수 있습니다. 포함 필터를 비워 두면 모든 항목이 맞는 것으로 칩니다.

flowchart TD
    E1["들어온 로그 항목 하나"] --> I{"포함 필터에 맞나"}
    I -->|아니오| X["보내지 않음"]
    I -->|예| Ex{"제외 필터 하나라도 맞나"}
    Ex -->|예| X
    Ex -->|아니오| D["싱크의 목적지로 보냄"]

포함 필터에 맞고 제외 필터에는 하나도 안 걸려야 목적지로 갑니다. 필터는 뒤에 나오는 Logging 질의 언어로 적습니다.

목적지는 넷입니다. 하나는 이 서비스 안의 로그 버킷입니다. 나머지 셋은 BigQuery 데이터셋, Cloud Storage 버킷, Pub/Sub 토픽입니다. 다른 프로젝트로 넘길 수도 있습니다. 셋이 무엇이고 무엇이 오가는지는 「맞물림」 절의 표에 있습니다.

처음부터 서 있는 두 싱크

프로젝트·폴더·조직·결제 계정마다 싱크 둘이 처음부터 만들어져 있습니다. 이름이 _Required 와 _Default 입니다. 두 싱크의 필터는 그 자원에서 생긴 모든 항목이 둘 중 하나를 타도록 짜여 있습니다.

_Required 싱크는 감사 로그 가운데 일부를 _Required 버킷으로 보냅니다. 감사 로그는 누가 무엇을 바꿨는지 남기는 로그입니다. Admin Activity · System Event · Access Transparency 로그가 여기 해당합니다. 이 싱크에는 제외 필터가 없습니다. 고치거나 지울 수도 없습니다.

_Default 싱크는 포함 필터가 비어 있어 모든 항목에 맞습니다. 대신 제외 필터가 _Required 싱크로 가는 감사 로그를 걸러 냅니다. 나머지는 전부 _Default 버킷으로 갑니다. 이 싱크는 고칠 수도 끌 수도 있습니다.

flowchart TD
    IN["들어온 로그 항목"] --> R["로그 라우터"]
    R -->|"Admin Activity · System Event · Access Transparency"| S1["_Required 싱크"]
    R -->|"그 밖의 모든 항목"| S2["_Default 싱크"]
    R -->|"필터에 맞는 항목"| S3["직접 만든 싱크"]
    S1 --> B1["_Required 버킷 · 400일 · 못 바꿈"]
    S2 --> B2["_Default 버킷 · 30일 · 프로젝트면 바꿀 수 있음"]
    S3 --> D["다른 버킷 · BigQuery · Cloud Storage · Pub/Sub"]

그림이 보이는 것은 저장이 수집의 결과가 아니라 싱크의 결과라는 점입니다. 버킷에 로그가 쌓이는 것도 버킷을 목적지로 둔 싱크에 걸렸기 때문입니다. 감사 로그 셋은 지울 수 없는 통으로, 나머지는 거를 수 있는 통으로 처음부터 갈립니다.

_Default 버킷의 보존 기간을 바꿀 수 있는 것은 프로젝트의 버킷뿐입니다. 폴더와 조직의 _Default 버킷은 30일로 고정입니다.

로그 버킷

로그 버킷은 이 서비스 안에서 로그를 담아 두는 통입니다. _Required 버킷과 _Default 버킷이 기본으로 있습니다. 직접 만든 버킷을 더 둘 수도 있습니다.

버킷마다 보존 기간이 있습니다. 그 기간이 지난 로그는 지워집니다. 기간 값은 「운영」 절의 표에 있습니다.

이 서비스의 화면과 분석 도구는 버킷에 있는 로그만 봅니다. 로그 탐색기는 쌓인 항목을 찾아보는 화면입니다. Error Reporting 은 로그 항목에서 오류를 찾아 묶어 보여 주는 서비스입니다. 둘 다 쓰려면 로그가 로그 버킷에 저장돼 있어야 합니다.

쌓인 로그를 보는 화면

로그 탐색기(Logs Explorer)는 항목을 한 건씩 보는 화면입니다. 관련된 항목을 찾아 함께 보여 주기도 합니다. Observability Analytics 는 로그를 SQL(Structured Query Language, 구조화 질의 언어)로 조회해 추세와 패턴을 찾는 화면입니다.

로그 탐색기의 조건은 Logging 질의 언어로 적습니다. 질의 하나는 고른 프로젝트나 폴더의 로그 항목 가운데 일부를 고르는 참·거짓 식입니다. 싱크 필터와 로그 기반 지표의 필터도 같은 언어로 적습니다.

포기한 것

안 하기로 한 것이 셋입니다.

시간 창 밖의 로그

로그 항목의 timestamp 칸은 그 항목의 나이를 재는 기준입니다. 보존 기간도 이 시각을 기준으로 적용합니다. 이 시각이 받아 주는 범위를 벗어나면 버킷에 쌓지 않습니다.

과거 쪽 경계는 그 버킷의 보존 기간입니다. 사용자 정의 버킷을 기본 보존 기간으로 두면 30일 전까지입니다. 그보다 오래된 시각을 단 항목도 API 는 받아서 싱크로 보냅니다. 다만 목적지가 로그 버킷이면 거기 저장되지 않습니다.

미래 쪽 경계는 하루입니다. 지금보다 하루 넘게 앞선 시각을 단 항목은 API 가 INVALID_ARGUMENT 오류로 거절합니다. 이 상한은 늘릴 수 없습니다.

두 경계는 막는 단계가 다릅니다. 미래 쪽은 API 입구에서 오류로 막힙니다. 과거 쪽은 버킷에 넣는 단계에서 오류 없이 빠집니다.

flowchart TD
    E["들어온 로그 항목"] --> F{"시각이 지금보다 하루 넘게 미래인가"}
    F -->|예| X["API 가 INVALID_ARGUMENT 로 거절"]
    F -->|아니오| S["API 가 받아 싱크로 보냄"]
    S --> O{"목적지가 로그 버킷이고 시각이 보존 기간보다 오래됐나"}
    O -->|예| L["오류 없이 저장 안 됨"]
    O -->|아니오| K["목적지로 감"]

이 결정으로 얻는 것은 버킷의 시간 범위가 시각 칸 하나로 닫힌다는 점입니다. 나이도 보존도 그 일이 일어난 시각으로 잽니다. 버킷에 남은 항목은 모두 보존 기간 안에 일어난 일의 기록입니다.

대가는 밀린 로그를 뒤늦게 보낼 때 드러납니다. 오래된 시각을 단 로그는 API 가 오류 없이 받지만 버킷에는 남지 않습니다.

지울 수 없는 _Required

_Required 버킷의 보존 기간은 400일입니다. 이 값은 바꿀 수 없습니다. 이 버킷을 지울 수도, 이 버킷으로 보내는 싱크를 고칠 수도 없습니다.

이 버킷으로 가는 감사 로그 가운데 Admin Activity 와 System Event 감사 로그는 늘 기록됩니다. 설정으로 끄거나 제외할 수 없습니다. Cloud Logging API 를 꺼도 Admin Activity 감사 로그는 계속 생깁니다. 감사 로그 항목은 고쳐 쓸 수 없습니다.

이 통에는 값이 붙지 않습니다. _Required 버킷에 담긴 로그에는 저장료도 보존료도 없습니다.

질의 대신 저장에 매기는 값

값은 로그를 로그 버킷에 흘려 넣어 저장하는 양에 매깁니다. 쌓은 로그를 질의하고 분석하는 데는 따로 값이 붙지 않습니다. 라우팅과 API 호출에도 값이 없습니다.

값을 줄이려면 무엇을 쌓을지를 골라야 합니다. 제외 필터에 걸려 어느 버킷에도 저장되지 않은 항목에는 값이 붙지 않습니다. 반대로 같은 항목을 한 프로젝트의 버킷 셋에 보내면 세 번 매겨집니다. 다른 프로젝트의 버킷으로 보내면 받는 프로젝트가 값을 냅니다.

제외 필터로도 안 줄어드는 것이 둘 있습니다. 하나는 entries.write 호출 수와 그 쿼터입니다. 쿼터는 정해진 시간에 쓸 수 있는 호출 한도입니다. 제외 필터는 API 가 항목을 받은 뒤에 걸리기 때문입니다.

다른 하나는 로그 기반 지표입니다. 로그 기반 지표는 로그 항목을 세거나 그 안의 값을 뽑아 만든 숫자입니다. 사용자가 직접 정의한 지표는 기본으로 제외 필터에 걸린 로그까지 셉니다. 이 지표에는 값이 붙습니다.

예시

애플리케이션이 찍는 로그 한 줄, 그 로그를 찾는 질의 둘, 로그를 다른 곳으로 보내는 싱크 명령을 봅니다.

Cloud Run 에서 표준 출력으로 찍는 한 줄

파이썬 애플리케이션이 딕셔너리 하나를 JSON 한 줄로 바꿔 표준 출력에 찍는 코드입니다.

Python
# Build structured log messages as an object.
global_log_fields = {}
trace_header = request.headers.get("X-Cloud-Trace-Context")
if trace_header and PROJECT:
    trace = trace_header.split("/")
    global_log_fields[
        "logging.googleapis.com/trace"
    ] = f"projects/{PROJECT}/traces/{trace[0]}"
# Complete a structured log entry.
entry = dict(
    severity="NOTICE",
    message="This is the default display field.",
    # Log viewer accesses 'component' as jsonPayload.component'.
    component="arbitrary-property",
    **global_log_fields,
)
print(json.dumps(entry))

애플리케이션은 Cloud Logging 을 부르지 않습니다. 찍기만 하면 Cloud Logging 이 그 줄을 읽어 jsonPayload 에 담습니다. 글자만 찍었다면 textPayload 로 갔을 것입니다.

이때 몇몇 키는 본문에서 빠져 로그 항목의 칸이 됩니다.

찍은 키 가는 곳
severity = NOTICE 본문에서 빠져 severity 칸이 됩니다
logging.googleapis.com/trace trace 칸이 됩니다
message 화면에서 이 항목의 대표 글자로 보입니다
component 본문에 남아 jsonPayload.component 가 됩니다

추적 번호는 들어온 요청의 X-Cloud-Trace-Context 헤더에서 꺼냅니다. 빗금 앞부분이 트레이스 번호입니다. 그 번호를 projects/프로젝트/traces/번호 형식으로 붙여 넣습니다.

Compute Engine 의 Ops Agent 는 칸으로 옮기는 키 이름이 Cloud Run 과 다릅니다. Ops Agent 는 정해 둔 키 목록에 든 것만 칸으로 옮깁니다. 나머지 키는 전부 jsonPayload 에 남습니다.

그 목록의 심각도 키는 logging.googleapis.com/severity 입니다. 맨 이름 severity 를 찍으면 Ops Agent 에서는 본문에 남습니다. logging.googleapis.com/trace 는 Cloud Run 과 같은 이름으로 trace 칸이 됩니다. logging.googleapis.com/labels 는 labels 로, logging.googleapis.com/spanId 는 spanId 로 갑니다.

자원 종류와 심각도를 겹친 질의

로그 탐색기에 넣는 질의 한 줄입니다.

resource.type = (gce_instance OR aws_ec2_instance) AND severity >= ERROR

자원 종류가 둘 중 하나인 항목을 찾습니다. Compute Engine 가상 머신, 또는 AWS(Amazon Web Services)의 EC2(Elastic Compute Cloud) 가상 머신입니다. 그 가운데 심각도가 ERROR 이상인 것만 남깁니다. 화면의 심각도 메뉴에서 ERROR 를 고른 것과 같습니다.

resource.type 과 severity 는 늘 색인되는 칸입니다. 다만 이 질의는 OR 를 씁니다. 「운영」 절에서 보듯 OR 를 쓴 질의는 느려질 수 있습니다. 색인도 못 씁니다. 괄호 안에서 한 칸의 값을 고르는 OR 도 그런지는 자료에 없습니다(미확인).

전역 검색과 색인 칸 질의

같은 낱말을 찾는 질의도 쓰는 방식에 따라 속도가 갈립니다. 아래는 값 하나만 던진 전역 검색입니다.

"Hello Kitty"

전역 검색은 항목의 모든 칸과 본문에 그 값이 들었는지를 부분 문자열로 훑습니다. 느릴 수 있는 검색입니다.

아래는 같은 값을 찾되 색인이 걸린 logName 으로 먼저 범위를 줄인 질의입니다. 본문에서는 키 하나만 비교합니다.

logName = "projects/my-project_id/logs/somelog" AND
jsonPayload.my_favorite_cat = "Hello Kitty"

로그 버킷으로 보내는 싱크

싱크 하나를 만드는 gcloud 명령입니다.

터미널
gcloud logging sinks create my-sink logging.googleapis.com/projects/myproject123/locations/global/buckets/my-bucket \
  --log-filter='logName="projects/myproject123/logs/matched"' --description="My first sink"

첫 인자 my-sink 가 싱크 이름입니다. 둘째 인자가 목적지 경로입니다. --log-filter 가 포함 필터입니다. 이 값을 안 주면 모든 항목이 맞습니다.

제외 필터는 --exclusion 으로 줍니다. 여러 번 달아 싱크당 50개까지 둘 수 있습니다.

목적지 경로는 받는 서비스마다 형식이 정해져 있습니다.

목적지 경로
로그 버킷 logging.googleapis.com/projects/DESTINATION_PROJECT_ID/locations/LOCATION/buckets/BUCKET_NAME
다른 프로젝트 logging.googleapis.com/projects/DESTINATION_PROJECT_ID
BigQuery 데이터셋 bigquery.googleapis.com/projects/DESTINATION_PROJECT_ID/datasets/DATASET_ID
Pub/Sub 토픽 pubsub.googleapis.com/projects/PROJECT_ID/topics/TOPIC_ID

싱크는 목적지에 쓰는 동작이라 쓰기 권한이 있어야 합니다. 같은 프로젝트의 로그 버킷이면 권한이 저절로 붙습니다. 그 밖의 목적지는 싱크에 서비스 계정을 붙여야 합니다. 그 계정에 목적지 쓰기 권한도 줘야 합니다. 서비스 계정은 사람 대신 프로그램이 쓰는 계정입니다.

운영

굴리면서 부딪히는 값을 다섯 갈래로 나눕니다. 보존 기간, 요금, 상한, 질의 속도, 늦게 온 항목입니다.

버킷별 보존 기간

보존 기간은 버킷 단위로 걸립니다. 버킷에 어떤 종류의 로그가 들었는지는 상관없습니다.

버킷 속한 자원 기본 보존 바꿀 수 있나
_Required 프로젝트 · 폴더 · 조직 400일 없음
_Default 폴더 · 조직 30일 없음
_Default 프로젝트 30일 있음
사용자 정의 프로젝트 30일 있음

프로젝트의 _Default 버킷과 사용자 정의 버킷은 1일에서 3650일 사이로 정합니다. 보존 기간을 줄이면 7일 동안은 만료된 로그를 지우지 않습니다. 그동안 그 로그를 질의하거나 볼 수는 없습니다.

요금이 붙는 곳

대상 값 무료 몫
버킷에 흘려 넣어 저장 GiB 당 한 번 0.50달러. 버킷 저장 30일치가 들어 있습니다 프로젝트당 매달 첫 50 GiB
30일 넘는 보존 한 달 GiB 당 0.01달러 기본 보존 기간 안은 보존료가 없습니다
_Required 버킷 없음 —
라우팅 · API 호출 · 질의와 분석 없음 —
사용자 정의 로그 기반 지표 과금. Cloud Monitoring 사용자 정의 지표로 매깁니다 시스템 정의 지표는 과금하지 않습니다

저장 단가 0.50달러는 vended network logs 라 부르는 네트워크 로그를 뺀 값입니다. 그 로그의 단가는 자료에 없습니다(미확인).

상한

자주 부딪히는 상한입니다. 「늘릴 수 있나」가 없음이면 요청해도 안 늘어납니다.

무엇 상한 늘릴 수 있나
로그 항목 한 건 256 KiB 없음
감사 로그 항목 한 건 512 KiB 없음
항목 하나의 라벨 64개 없음
질의 길이 · 싱크 필터 길이 20,000자 없음
싱크 하나의 제외 필터 50개 없음
프로젝트의 싱크 200개 4,000개까지
프로젝트의 로그 버킷 100개 2,500개까지
entries.list 호출 프로젝트당 분당 60회 없음

256 KiB 는 어림값입니다. API 요청에 실린 바이트 수가 아니라 내부 데이터 크기로 잽니다. 제외 필터가 50개보다 많이 필요하면 포함 필터를 다듬기를 권합니다. 많은 양의 로그를 읽어야 하면 entries.list 대신 BigQuery API 를 쓰는 길을 고려할 만합니다.

질의 속도

질의를 빠르게 하는 방법은 둘입니다. 색인이 걸린 칸으로 조건을 겁니다. 그리고 훑어야 할 항목 수를 줄입니다.

늘 색인되는 칸은 정해져 있습니다. resource.type · resource.labels.* · logName · severity · timestamp · insertId · operation.id · trace · httpRequest.status · labels.* · split.uid 입니다.

훑을 양은 로그 수, 항목 수, 시간 범위 셋으로 줄입니다. 로그 수는 질의가 훑는 logName 의 수입니다. 셋 다 줄이면 더 낫습니다. AND 로만 이은 질의가 색인을 더 잘 씁니다. OR 를 쓰면 느려질 수 있습니다. 색인도 쓰지 못합니다.

값 하나만 던지는 전역 검색은 느릴 수 있습니다. 이 검색 대신 색인이 걸린 칸으로 조건을 거는 것이 낫습니다.

Cloud Logging 은 전문 색인을 지원합니다. 전문 색인은 글 속 낱말로 찾게 해 주는 색인입니다. 이 색인이 textPayload 에도 걸리는지는 자료에 없습니다(미확인). 사용자 정의 색인 칸은 「상세」에서 구조화 로그의 본문 필드에 걸던 그 색인입니다. 버킷당 20개까지 만들 수 있습니다. 전문 색인이 있으므로 구글은 이 칸을 직접 정의하는 것을 권하지 않습니다.

API 로 읽을 때 결과의 기본 순서는 timestamp asc, 곧 오래된 것부터입니다. 방금 들어온 로그를 찾을 때 이 기본값을 두면 오래 걸릴 수 있습니다. 그럴 때는 timestamp desc 로 두면 새것부터 나옵니다.

늦게 온 항목과 순서

읽을 때 결과는 timestamp 순으로 나옵니다. 시각이 같으면 insertId 순입니다. 시각은 나노초 정밀도로 적힙니다.

insertId 를 직접 넣으면 같은 프로젝트에서 시각과 insertId 가 같은 항목을 중복으로 봅니다. 한 질의 결과 안에서는 하나만 남습니다. 내보낸 로그에서는 중복이 걸러진다는 보장이 없습니다.

로그 기반 지표는 1분마다 Cloud Monitoring 의 시계열을 갱신합니다. 시계열은 시간 순으로 쌓인 값의 줄입니다. 이미 처리한 구간의 시각을 단 항목이 늦게 오면 그 구간의 값을 다시 계산해 고칩니다. 미래 시각의 항목은 쌓아 뒀다가 그 시각이 현재 구간이 될 때 셉니다.

사용자 정의 지표는 만든 뒤에 들어온 항목만 셉니다. 이미 쌓인 로그로 과거를 채우지 않습니다.

싱크도 같습니다. 싱크를 만들기 전에 들어온 항목은 보내지 않습니다. 설정이 틀렸던 싱크는 고친 뒤에 들어온 것부터 보냅니다.

Cloud Storage 로 가는 새 싱크는 보내기 시작하기까지 몇 시간이 걸릴 수 있습니다. 이 싱크는 한 시간 단위로 처리됩니다.

맞물림

로그를 받은 뒤의 일은 대개 같은 구글 클라우드의 다른 서비스가 맡습니다. 붙는 방향이 정해진 넷을 봅니다.

BigQuery · Cloud Storage · Pub/Sub

세 서비스는 싱크가 보내는 것을 받습니다. 무엇을 하려는지에 따라 받는 서비스를 고릅니다.

받는 서비스 언제 고르나 어떤 형식으로 가나
BigQuery 데이터셋 · 데이터 웨어하우스 로그를 다른 업무 데이터와 합쳐 볼 때 로그 이름마다 테이블 하나
Cloud Storage 버킷 · 객체 저장소 오래 보관할 때 JSON 파일
Pub/Sub 토픽 · 메시지 전달 서비스 구글 클라우드 밖의 도구로 내보낼 때 JSON 으로 바꾼 메시지

BigQuery 로 보내려면 쓰기가 켜진 데이터셋이어야 합니다. 싱크가 데이터를 흘려 넣는 동안에는 테이블 이름을 바꿀 수 없습니다.

로그를 버킷에 둔 채 BigQuery 에서 질의하는 길도 있습니다. 버킷에 연결된 BigQuery 데이터셋을 만듭니다. 그 데이터셋은 읽기 전용이지만 다른 데이터셋처럼 질의합니다.

Pub/Sub 토픽은 Splunk 나 Datadog 같은 바깥 도구가 받아 가는 출구입니다. 대가도 있습니다. 버킷에 두지 않고 밖으로만 보낸 로그는 로그 탐색기와 Error Reporting 이 보지 못합니다.

Cloud Monitoring

다리는 로그 기반 지표입니다. 로그 기반 지표는 로그 항목의 내용에서 뽑아낸 Cloud Monitoring 지표입니다. 필터에 맞는 항목의 수를 세거나, 로그에 적힌 지연 시간을 뽑아냅니다. 필터는 「예시」 절의 severity >= ERROR 같은 질의 언어 조건입니다.

Cloud Logging 이 메모리에서 센 값을 1분마다 넘깁니다. Cloud Monitoring 이 그 값으로 시계열을 갱신합니다. 그 지표로 차트를 그리고 경보 정책을 겁니다.

지표 이름은 시스템 정의 지표가 logging.googleapis.com/SYSTEM_METRIC_NAME, 사용자 정의 지표가 logging.googleapis.com/user/USER_METRIC_NAME 형식입니다.

세는 범위가 지표 종류마다 다릅니다. 시스템 정의 지표는 제외 필터를 통과한 로그만 셉니다. 사용자 정의 지표는 기본으로 제외된 로그까지 셉니다. 값이 붙는 것도 사용자 정의 지표뿐입니다.

Error Reporting

Error Reporting 은 로그를 읽어 가는 서비스입니다. 오류를 Error Reporting API 로 직접 받기도 합니다. 로그 항목에서 스택 트레이스와 흔한 오류 패턴을 찾아 끌어내기도 합니다. 스택 트레이스는 오류가 난 순간 호출이 어떤 함수들을 거쳐 왔는지 적은 목록입니다.

로그를 읽어 가려면 그 항목이 저장된 곳이 맞아야 합니다. 저장된 곳은 싱크의 목적지가 정합니다. 그 버킷의 암호화 설정도 봅니다. CMEK(Customer-Managed Encryption Keys, 고객 관리 암호화 키)가 켜진 버킷의 항목은 분석하지 않습니다. 아래 그림은 목적지에 따라 Error Reporting 이 그 항목을 분석할 수 있는지를 가릅니다.

flowchart TD
    E["오류가 든 로그 항목"] --> Q1{"싱크가 어디로 보냈나"}
    Q1 -->|"생긴 프로젝트의 로그 버킷"| Q2{"그 항목을 담은 버킷 모두 CMEK 가 꺼져 있나"}
    Q1 -->|"다른 프로젝트 · 목적지가 프로젝트"| P["받은 프로젝트가 자기 로그 버킷에 저장"]
    P --> Q2
    Q1 -->|"다른 프로젝트 · 목적지가 로그 버킷"| N["Error Reporting 이 분석하지 않음"]
    Q1 -->|"BigQuery · Cloud Storage · Pub/Sub 로만"| N
    Q2 -->|예| Y["분석할 수 있음"]
    Q2 -->|아니오| N

생긴 프로젝트의 로그 버킷에 둔 항목은 분석할 수 있습니다. 다른 프로젝트로 보낼 때는 목적지의 형식이 결과를 가릅니다. 목적지가 그 프로젝트(logging.googleapis.com/projects/DESTINATION_PROJECT_ID)면 받은 프로젝트가 자기 버킷에 저장한 뒤 분석 대상이 됩니다. 목적지가 다른 프로젝트의 로그 버킷이면 Error Reporting 이 분석하지 않습니다.

분석되는 두 경로 모두 그 항목을 담은 버킷에 CMEK 가 꺼져 있어야 합니다. 버킷에 두지 않고 BigQuery · Cloud Storage · Pub/Sub 로만 보낸 항목은 분석 대상이 아닙니다.

오류가 많으면 시간당 1,000건까지 표본을 뜹니다. 그보다 많으면 수를 어림합니다.

Cloud Trace 와 잇는 trace 칸

로그와 트레이스를 잇는 것은 trace 칸 하나입니다. 같은 트레이스에 속한 항목들이 같은 trace 값을 가지면, 로그 탐색기가 요청 로그 항목 밑에 자식 항목을 접어 보여 줍니다. 묶이려면 항목마다 trace 칸이 있어야 합니다.

flowchart TD
    P["부모 · 요청 로그 항목 · trace TRACE_ID · logName A"]
    P --> C1["자식 항목 · trace TRACE_ID · logName B"]
    P --> C2["자식 항목 · trace TRACE_ID · logName C"]

그림에서 묶는 열쇠는 trace 값 하나입니다. 묶인 항목들은 trace 값이 같습니다. logName 은 저마다 다릅니다. 부모 항목의 시각은 어느 자식보다도 늦지 않습니다.

trace 값은 TRACE_ID 또는 projects/PROJECT_ID/traces/TRACE_ID 형식입니다.

애플리케이션을 OpenTelemetry 로 계측하면 트레이스 번호와 스팬 번호가 요청의 추적 맥락에서 뽑혀 로그에 실립니다. 이 로그는 OTLP(OpenTelemetry Protocol) 로그 데이터로 프로젝트에 갑니다.

OpenTelemetry 로그 데이터 모델에도 짝이 되는 칸이 있습니다. 여러 로그 형식을 한 모델로 옮겨 담는 이 모델은 trace 를 TraceId 로, spanId 를 SpanId 로 옮깁니다. 본문 칸 셋은 Body 하나로 옮겨집니다. 짝이 없는 칸은 gcp. 로 시작하는 속성이 됩니다.

바깥 수집기도 같은 칸을 맞춥니다. Fluent Bit 의 Stackdriver 출력 플러그인은 Cloud Logging API 의 /v2/entries:write 로 항목을 보냅니다. 이 플러그인에서 autoformat_stackdriver_trace 를 켜면 트레이스 번호만 찍어도 됩니다. 플러그인이 trace 칸에 프로젝트 ID 를 넣어 Cloud Trace 가 쓰는 형식으로 고쳐 씁니다.

관련 항목

Cloud Logging 이 담고 다루는 기록의 종류

로그 · 감사 로그 · 접근 로그 · 구조화 로그 · 애플리케이션 로그 · 시스템 로그 · 스택 트레이스 · Access Transparency

Cloud Logging 을 이루는 구성 요소

로그 항목 · 로그 라우터 · 싱크 · 로그 버킷 · 포함 필터 · 제외 필터 · 보존 기간 · 로그 기반 지표 · 로그 탐색기 · Observability Analytics · Logging 질의 언어 · 라이브 테일

Cloud Logging 이 로그를 넘겨 주는 저장소

Cloud Storage · Google Cloud Storage · BigQuery · 메시지 큐 · 오브젝트 스토리지 · 데이터 웨어하우스

Cloud Logging 으로 로그를 보내는 수집 도구

에이전트 · Ops Agent · Fluent Bit · Fluentd · OpenTelemetry · OpenTelemetry Collector · OTLP · BindPlane · Logstash · syslog

Cloud Logging 과 같은 역할을 두고 겨루는 로그 서비스

CloudWatch · OpenSearch · Elasticsearch · Loki · Splunk · Datadog

Cloud Logging 의 로그를 받아 이어 쓰는 구글 클라우드 서비스

Cloud Monitoring · Error Reporting · Cloud Trace · Grafana

Cloud Logging 이 로그를 넘겨 이어 가는 관측 기능

모니터링 · 경보 · 분산 추적 · 트레이스 · 스팬 · 대시보드 · 에러 리포팅

Cloud Logging 이 로그를 받아 오는 실행 환경

가상 머신 · 컨테이너 · 쿠버네티스 · 파드 · 노드 · Compute Engine · Google Kubernetes Engine · App Engine · Cloud Run · 서버리스 · 부하 분산기

Cloud Logging 질의가 기대는 검색 장치

색인 · 전문 검색 · 부분 문자열 검색 · SQL · JSON

Cloud Logging 이 속하는 상위 분류

관측성 · 로그 관리 · 관리형 서비스 · 클라우드 · Google Cloud

Cloud Logging 을 다룰 때 같이 정하는 운영 규칙

로그 수준 · 로그 회전 · 샘플링 · 민감 정보 마스킹 · 접근 제어 · 서비스 계정 · CMEK · 쿼터

다른 이름: 클라우드 로깅 · Stackdriver Logging · 스택드라이버 로깅 · Google Cloud Logging