Logging のクエリ言語

このドキュメントには、Cloud Logging データのクエリとフィルタに使用する Logging クエリ言語の概要を記載しています。

Logging のクエリ言語設計の詳細については、フィルタ用の Google API の正式な仕様をご覧ください。

使用する一般的なクエリの例については、ログ エクスプローラを使用したサンプルクエリをご覧ください。

概要

ログ エクスプローラの Logging クエリ言語は、Google Cloud コンソール、Logging API、またはコマンドライン インターフェースで使用できます。Logging のクエリ言語を使用してデータのクエリを実行すると、フィルタを作成してシンクログベースの指標を作成できます。

クエリは、選択した Google Cloud リソース(Google Cloud プロジェクトやフォルダなど)のすべてのログエントリのサブセットを指定するブール式です。

クエリは、論理演算子 ANDOR を使用して、LogEntryインデックス フィールドに基づいて作成できます。次の例で resource.type フィールドを使用すると、Logging のクエリ言語の文法は次のようになります。

  • 単純な制限: resource.type = "gae_app"

  • 連言制限: resource.type = "gae_app" AND severity = "ERROR"

  • 分離句の制限: resource.type = "gae_app" OR resource.type = "gce_instance"

    • または: resource.type = ("gae_app" OR "gce_instance")
  • 複雑な接続詞 / 分離句の式: resource.type = "gae_app" AND (severity = "ERROR" OR "error")

クエリの単純な例を次に示します。

resource.type = "gce_instance" AND
severity >= "ERROR" AND
NOT textPayload:robot

このクエリは、重大度が少なくとも ERROR で、かつ、textPayload フィールドが文字列 robot を含んでいない Compute Engine のログエントリと一致します。文字列の比較では大文字と小文字が区別されません。名前 resourceseveritytextPayload は、LogEntry 型で定義されます。

構文の表記法

以下のセクションでは、Logging のクエリ言語の構文の概要について説明し、クエリの構造と照合の実行方法について説明します。 一部の例では、コメントを使用して説明テキストを提供します。

次の点にご注意ください。

  • クエリの長さは 20,000 文字以下にする必要があります。

  • Logging のクエリ言語では、正規表現を除き、大文字と小文字が区別されません。

構文の概要

Logging のクエリ言語の構文は、クエリ比較の観点から考えることができます。

クエリは、次の式を含む文字列です。

expression = ["NOT"] comparison { ("AND" | "OR") ["NOT"] comparison }

比較は、単一の値かブール式のいずれかです。

"The cat in the hat"
resource.type = "gae_app"

最初の行は、単一の値を使用した比較の例です。このタイプの比較はグローバル制限になります。ログエントリの各フィールドが、暗黙に has 演算子を使用してその値と比較されます。この例の場合、LogEntry 内のフィールドまたはそのペイロードが "The cat in the hat" という語句を含んでいれば、比較に成功します。

2 行目は比較の例で、[FIELD_NAME] [OP] [VALUE] 形式のブール式です。この比較の要素は次のとおりです。

  • [FIELD_NAME] はログエントリのフィールドです。例: resource.type

  • [OP] は比較演算子です。例: =

  • [VALUE] は数値、文字列、関数、またはかっこで囲まれた式です。例: "gae_app"JSON が null 値の場合は、NULL_VALUE を使用します。

ブール演算子

ブール演算子 ANDOR短絡評価の演算子です。NOT 演算子の優先順位が最も高く、その後に ORAND が順に続きます。たとえば、次の 2 つの式は等価です。

"a" OR NOT "b" AND NOT "c" OR "d"
("a" OR (NOT "b")) AND ((NOT "c") OR "d")

比較の間の AND 演算子は省略できます。また、NOT 演算子の代わりに -(マイナス記号)を使用できます。たとえば、次の 2 つのクエリは同じです。

a="b" AND c="d" AND NOT e="f"
a="b" c="d" -e="f"

このドキュメントでは常に ANDNOT を使用します。

ログビューで使用されるフィルタを除くすべてのフィルタで、ANDORNOT 演算子を使用できます。ログビューでは、AND オペレーションと NOT オペレーションのみがサポートされます。

同じ式で AND ルールと OR ルールを組み合わせるには、かっこを使用してルールをネストする必要があります。括弧を使用しないと、クエリが意図したとおりに機能しない可能性があります。

ブール演算子は常に大文字にする必要があります。小文字の andornot は検索キーワードとして解析されます。

比較

比較の形式は次のとおりです。

[FIELD_NAME] [OP] [VALUE]

この比較の要素は次のとおりです。

  • [FIELD_NAME]: ログエントリ内のフィールドのパス名。フィールド名の例を次に示します。

    resource.type
    resource.labels.zone
    resource.labels.project_id
    insertId
    jsonPayload.httpRequest.protocol
    labels."compute.googleapis.com/resource_id"
    

    パス名のコンポーネントに特殊文字が含まれている場合は、パス名を二重引用符で囲む必要があります。たとえば、compute.googleapis.com/resource_id にはスラッシュ / が含まれているため、二重引用符で囲む必要があります。

    詳細は、このドキュメントのフィールドパス ID をご覧ください。

  • [OP]: 次のいずれかの比較演算子です。

    =           -- equal
    !=          -- not equal
    > < >= <=   -- numeric ordering
    :           -- "has" matches any substring in the log entry field
    =~          -- regular expression search for a pattern
    !~          -- regular expression search not for a pattern
    

正規表現を使用してログエントリを検索する方法については、正規表現の使用をご覧ください。

  • [VALUE]: 数値、文字列、関数、またはかっこで囲まれた式。文字列は任意のテキスト、ブール値、列挙型の値、バイト文字列の値を表すために使用します。[VALUE] は、比較の前にフィールドの型に変換されます。JSON が null 値の場合は、NULL_VALUE を使用します。

JSON の null 値でフィルタするには、次の構文を使用します。

jsonPayload.field = NULL_VALUE      -- includes "field" with null value
NOT jsonPayload.field = NULL_VALUE  -- excludes "field" with null value

[VALUE] がかっこで囲まれた比較の組み合わせのブール値である場合、フィールド名と比較演算子が各要素に適用されます。例:

jsonPayload.cat = ("longhair" OR "shorthair")
jsonPayload.animal : ("nice" AND "pet")

最初の比較は、フィールド cat の値が「longhair」または「shorthair」であることを確認します。次の比較は、フィールド animal の値に「nice」と「pet」の両方の単語が含まれていることを確認します(順序は関係ありません)。

フィールドパス識別子

すべてのログエントリは、LogEntry 型のインスタンスです。比較の左側にある(最初の)識別子は、LogEntry 型で定義されたフィールドである必要があります。使用可能な識別子とその値の詳細については、LogEntry タイプをご覧ください。

ログエントリ フィールドの最新のリストは、次のとおりです。該当する場合は、各フィールドの後に、そのフィールドの次の階層の名前が示されています。

  • httpRequest: { cacheFillBytes, cacheHit, cacheLookup, cacheValidatedWithOriginServer, latency, protocol, referer, remoteIp, requestMethod, requestSize, requestUrl, responseSize, serverIp, status, userAgent }
  • insertId
  • jsonPayload { variable }
  • labels { variable }
  • logName
  • metadata { systemLabels, userLabels }
  • operation{ id, producer, first, last }
  • protoPayload { @type, variable }
  • receiveTimestamp
  • resource { type, labels }
  • severity
  • sourceLocation: { file, line, function }
  • spanId
  • textPayload
  • timestamp
  • trace

以下に、比較で使用できるフィールドパス識別子の例を示します。

  • resource.type: 最初のパス識別子が resource の場合、次の識別子は MonitoredResource タイプのフィールドにする必要があります。

  • httpRequest.latency: 最初のパス識別子が httpRequest の場合、次の識別子は HttpRequest タイプのフィールドにする必要があります。

  • labels.[KEY]: 最初のパス識別子が labels の場合、次の識別子 [KEY]labels フィールドにある Key-Value ペアのどちらかを指定する必要があります。

  • logName: logName フィールドは文字列のため、その後にサブフィールド名を続けることはできません。

マップ フィールドや構造体フィールドに対してクエリを実行する場合、式でラベルキーの大文字小文字と形式を保持する必要があります。

たとえば、jsonPayload は構造体フィールドであるため、jsonPayload.end_time のように jsonPayload 内にネストされているフィールド名は jsonPayload.endTime とは異なります。同様に、labels のようなマップ フィールドの場合、ラベルキー labels.env_namelabels.envName とは異なります。対照的に、標準のプロトコル バッファ フィールド protoPayload をクエリする場合は、大文字と小文字を保持する必要はありません。

LogEntry フィールド タイプについては、google.logging.v2 リファレンスをご覧ください。

特殊文字

LogEntry フィールドに特殊文字が含まれている場合は、ログ フィールドを引用符で囲む必要があります。例:

jsonPayload.":name":apple

jsonPayload."foo.bar":apple

jsonPayload."\"foo\"":apple

特殊文字のリストについては、値と変換ページの string セクションをご覧ください。

オブジェクトまたは配列を参照するフィールドパス識別子の使用に関する詳細は、このドキュメントのオブジェクトと配列の型をご覧ください。

モニタリング対象リソースタイプ

クエリを高速化するには、モニタリング対象リソースタイプを指定します。リソースタイプの一覧については、モニタリング対象リソースタイプをご覧ください。

たとえば、Compute Engine VM はリソースタイプ gce_instance を使用し、Amazon EC2 インスタンスは aws_ec2_instance を使用します。次の例では、クエリ範囲を両方の種類の VM に限定しています。

resource.type = ("gce_instance" OR "aws_ec2_instance")

ログでは、モニタリング対象リソースタイプ値がインデックス登録されています。部分文字列の一致を使用すると、クエリが遅くなります。

欠落しているフィールド

クエリでフィールド名を使用していて、そのフィールドがログエントリに表示されない場合、そのフィールドは欠落未定義デフォルトのいずれかの状態にあります。

  • フィールドがログエントリのペイロード(jsonPayloadprotoPayload)に含まれているか、ログエントリの labels セクションのラベルに含まれている場合、フィールドは欠落しています。欠落しているフィールドを使用してもエラーは表示されませんが、このフィールドを使用する比較はすべて無応答で失敗します。

    例: jsonPayload.nearest_storeprotoPayload.name.nickname

  • フィールドが LogEntry 型で定義されている場合、フィールドはデフォルトの状態になっています。フィールドが存在し、デフォルト値が設定されている場合と同様に比較が実行されます。

    例: httpRequest.remoteIptraceoperation.producer

  • それ以外の場合、フィールドは未定義です。このエラーは、クエリが使用される前に検出されます。

    例: thudoperation.thudtextPayload.thud

フィールドの特定の値をテストせずに、欠落フィールドまたはデフォルト設定されたフィールドが存在するかどうかをテストするには、:* 比較を使用します。たとえば、次の比較は、ログエントリに operation.id フィールドが明示的に存在する場合に成功します。

operation.id:*

次のクエリの動作に注意してください。

  • 欠落しているフィールドに対してブール値の NOT 演算子を使用すると、結果は TRUE になります。

    -- Returns TRUE
    NOT missingField=foo
    
  • 等しくない比較演算子 != を欠落しているフィールドに使用すると、結果は FALSE になります。

    -- Returns FALSE
    missingField!=foo
    

オブジェクトと配列の型

ログエントリ フィールドには、スカラー、オブジェクトまたは配列を格納できます。

  • スカラー フィールドには、174.4-1 などの単一の値が格納されます。string もスカラーとみなされます。DurationTimestamp などの文字列に変換できるフィールドや、文字列から変換できるフィールドもスカラー型になります。

  • オブジェクト型には、次の JSON 値のような名前付き値のコレクションが格納されます。

    {"age": 24, "height": 67}
    

    オブジェクト内の値は参照できます。たとえば、jsonPayload.x に前述の値が含まれている場合、jsonPayload.x.age の値は 24 になります。

  • 配列フィールドには、すべて同じ型の値のリストが格納されます。たとえば、測定値を格納するフィールドには、数値の配列が格納されます。

    {8.5, 9, 6}
    

    比較が実行されたときに、[FIELD_NAME] が配列フィールドの場合、配列の各メンバーが [VALUE] と比較され、OR 演算子を使用して結果が結合されます。たとえば、jsonPayload.shoeSize{8.5, 9, 6} を格納する配列フィールドの場合、比較は次のようになります。

    jsonPayload.shoeSize < 7
    

    これは次と同等です。

    8.5 < 7 OR 9 < 7 OR 6 < 7
    

    この例では、全体的な比較は成功と評価されます。

値と変換

比較評価では、まず最初に、右辺の値がログエントリ フィールドの型に変換されます。比較ではスカラー フィールド型が使用できます。また、この他に、値が文字列として表される DurationTimestamp の 2 つの型も使用できます。スカラータイプの一覧については、スカラー プロトコル バッファタイプのリストをご覧ください。次の表は、ログフィールド タイプに変換できる値の一覧です。

フィールドの型 使用できるクエリ値
bool

true または false(大文字と小文字は区別しません)。たとえば True、true です。

bytes

任意の連続したバイトを含む文字列。たとえば \377\377 です。

Duration

符号付き 10 進数の後に ns、us、ms、s、m、h のいずれかの単位が続いている文字列。この期間はナノ秒単位の精度です。たとえば 3.2s です。

enum

列挙型のリテラルの名前。大文字と小文字は区別されません。たとえば WARNING(LogSeverity タイプの値)です。

double

任意の数値(符号と指数はある場合もない場合もあります)、または特殊な値の文字列(NaN、-Infinity、Infinity。先頭の大文字と小文字は区別されません)。たとえば -3.2e-8、nan です。

intNN

型のサイズを超えない符号付き整数。 たとえば -3 です。

string

UTF-8 でエンコードされたテキスト、または 7 ビットの ASCII テキストを含む任意の文字列。文字列内で引用符を使用する場合には、バックスラッシュでエスケープする必要があります。

次の特殊文字をエスケープするには、文字列値を二重引用符で囲む必要があります。

  • +(プラス)、-(マイナス)、または .(ピリオド)で始まる文字列。

  • ~(チルダ)、=(等しい)、()(かっこ)、:(コロン)、>(より大きい)、<(より小さい)、,(カンマ)、.(ピリオド)、*(アスタリスク)のいずれかを含む文字列。

  • エスケープ シーケンス(例: \t)。

Timestamp

RFC 3339 形式または ISO 8601 形式の文字列。例"2014-10-02T15,コロン; 01&コロン; 23.045Z"(RFC 3339)、2014-10-02(ISO 8601)。クエリ式では、RFC 3339 形式のタイムスタンプに Z または ±hh:mm を付けてタイムゾーンを指定できます。タイムスタンプは、ナノ秒単位の精度で表されます。

uintNN

型のサイズを超えない符号なし整数。 たとえば 1234 です。

変換の試行に失敗した場合、比較も失敗します。

変換に文字列が必要な場合、スペースや演算子などの特殊文字が含まれていなければ、数字または引用符なしのテキストを使用することもできます。同様に、変換で数値が必要な場合、内容が数値の文字列を使用できます。

intNN 型と uintNN 型は、さまざまなサイズの整数型を表します(int32uint64 など)。64 ビットの整数型に変換する値を記述する場合、この値は「9223372036854775807」のように文字列として記述する必要があります。

ログフィールドのタイプ

ここでは、ログエントリ フィールドの型を判別する方法を説明します。

  • LogEntry 型とそのコンポーネントの型で定義されたログフィールドはプロトコル バッファ フィールドです。プロトコル バッファ フィールドには明示的な型があります。

  • protoPayload オブジェクトの一部であるログフィールドもプロトコル バッファ フィールドであり、明示的な型があります。プロトコル バッファタイプの名前は、protoPayload のフィールド "@type" に格納されます。詳細については、JSON マッピングをご覧ください。

    Any メッセージ タイプに関連付けられたフィールドでフィルタすると、value フィールドが自動的に走査されます。そのため、クエリには含めないでください。詳細については、トラブルシューティングをご覧ください。

  • jsonPayload 内部にあるログフィールドの型は、ログエントリの受信時にフィールドの値から推測されます。

    • 値が引用符なしの数値であるフィールドの型は double です。
    • 値が true または false のフィールドの型は bool です。
    • 値が文字列であるフィールドの型は string です。

    長整数型(64ビット)は、double 値として正確に表現できないため、文字列フィールドに格納されます。

  • Duration 型と Timestamp 型は、プロトコル バッファ フィールドでのみ認識されます。それ以外の場合、これらの値は文字列フィールドに格納されます。

コメント

コメントは 2 つのダッシュ(--)で始まり、ダッシュに続くテキストは行の末尾まで無視されます。コメントは、フィルタの先頭、用語間、フィルタの最後に配置できます。

次のような場合は、コメントを使用できます。

  • 複雑なフィルタに、句が何を行うかに関する情報でアノテーションを付けるには、次のようにします。

     -- All of our target users are emitted by Compute Engine instances.
     resource.type = "gce_instance"
     -- Looking for logs from "alex".
     jsonPayload.targetUser = "alex"

  • コメント接頭辞を追加または削除して句をすばやく有効または無効にするには:

     resource.type = "gce_instance"
     -- jsonPayload.targetUser = "alex"
     jsonPayload.targetUser = "kiran"
     -- jsonPayload.targetUser = "sasha"

比較演算子

等式(=!=)と不等式(<<=>>=)の演算子の意味は、左辺のフィールド名のタイプによって異なります。

  • すべての数値型: 等式と不等式は通常の数値の場合での意味と同じです。
  • bool: 等式は同じブール値であることを表します。不等式は「true > false」で定義されます。
  • enum: 等式は同じ列挙値であることを表します。不等式では、列挙型リテラルの基礎となる数値を使用します。
  • Duration: 等式は同じ期間であることを表します。不等式は期間の長さに基づきます。たとえば、期間として、"1s" > "999ms" となります。
  • Timestamp: 等式は同じ時刻であることを指します。abTimestamp 値である場合、「a < b」は a の時刻が b の時刻よりも前であることを表します。
  • bytes: オペランドはバイト単位で左から順番に比較されます。
  • string: 比較では大文字と小文字は区別されません。具体的には、まず両方のオペランドが NFKC_CF Unicode 正規化により正規化され、その後に辞書式比較されます。ただし、正規表現による検索は正規化されません。正規表現を使用したログエントリの検索の詳細については、正規表現の使用をご覧ください。

部分文字列演算子(:)は stringbytes に使用でき、等式演算子と同様に扱われます。ただし、右辺のオペランドが左辺の一部とだけでも一致していれば成立します。インデックス付きフィールドでの部分文字列の照合では、ログ インデックスは利用されません。

グローバル制限

比較が単一の値で構成されている場合、この比較をグローバル制限といいます。Logging では、has:)演算子を使用して、ログエントリのフィールドまたはペイロードにグローバル制限があるか確認します。グローバル制限がある場合、比較に成功します。

グローバル制限のクエリの中で最も簡単なものが単一の値です。

"The Cat in The Hat"

AND 演算子や OR 演算子を使用してグローバル制限を組み合わせると、より複雑なクエリを作成できます。たとえば、フィールドに cat が含まれているログエントリと、フィールドに hat または bat が含まれているログエントリをすべて表示するには、クエリを次のように記述します。

("cat" AND ("hat" OR "bat"))

この場合、cathatbat の 3 つのグローバル制限があります。これらのグローバル制限が個別に適用され、かっこなしで式を作成した場合と同様に結果が結合されます。

グローバル制限を使用すると、ログで特定の値を簡単にクエリできます。たとえば、アクティビティ ログで GCE_OPERATION_DONE を含むエントリを検索する場合、次のクエリを使用します。

logName = "projects/my-project-id/logs/compute.googleapis.com%2Factivity_log" AND
"GCE_OPERATION_DONE"

グローバル制限は簡単に実行できますが、速度は遅くなる場合があります。詳細については、このドキュメントのログエントリの迅速な検索をご覧ください。

関数

組み込み関数は、クエリでグローバル制限として使用できます。

function = identifier ( [ argument { , argument } ] )

ここで、argument は値、フィールド名、またはかっこで囲まれた式です。関数はこれ以降のセクションで説明されます。

log_id

log_id 関数は、logName フィールドの指定された [LOG_ID] 引数に一致するログエントリを返します。

log_id([LOG_ID])

たとえば、次のクエリは cloudaudit.googleapis.com%2Factivity [LOG_ID] を持つすべてのログエントリを返します。

log_id("cloudaudit.googleapis.com/activity")

cast

cast 関数は 2 つのパラメータを受け入れます。キャストする LogEntry フィールドと、フィールドの変換先のデータ型。

cast([FIELD], [TYPE][, OPTION])

上記の式のパラメータは、次のように定義されます。

  • [FIELD]: ログエントリ内のフィールド名(logNamejsonPayload.a_field など)。

  • [TYPE]: データ型(STRINGINT64FLOAT64BOOL など)。

    • TIMESTAMP または DURATION: 一部のデータ型には、追加のオプション(TIMESTAMP データ型に対して IANA タイムゾーン データベース タイムゾーンを指定するなど)があります。

たとえば、次のクエリは timestamp フィールドを STRING にキャストし、America/New_York タイムゾーンを指定します。

cast(timestamp, STRING, TIMEZONE("America/New_York")) =~ "^2023-01-02.*"

regexp_extract

regexp_extract 関数を使用して、正規表現に一致する最初の部分文字列を検索します。

REGEXP_EXTRACT([FIELD], [REGULAR_EXPRESSION])

前の式では、フィールドが次のように定義されています。

  • [FIELD]: ログエントリ内のフィールド名(logNamejsonPayload.a_field など)。
  • [REGULAR_EXPRESSION]: 1 つのキャプチャ グループ((...))を含む RE2 正規表現。正規表現に追加のグループ化が必要な場合は、キャプチャ以外のグループ (?:...) を使用する必要があります。複数のキャプチャ グループを指定するか、キャプチャ グループがない場合、エラーが発生します。

cast 関数と regexp_extract 関数を連結できます。

CAST(REGEXP_EXTRACT(CAST(timestamp, STRING), "\\d+:\\d+:\\d+\\.(\\d+)"), INT64) < 500

上記の例では、timestamp フィールドを文字列としてキャストしています。正規表現は、timestamp 文字列のミリ秒の部分をキャプチャし、それを整数にキャストして数値の比較を行います。ミリ秒フィールドが 500 未満のタイムスタンプを含むすべてのログエントリが返されます。

ソース

source 関数は、組織、フォルダ、Google Cloud プロジェクトの階層内にある特定のリソースのログエントリを照合します。

source 関数は子リソースを照合しません。たとえば、source(folders/folder_123) を使用すると、folder_123 リソースのログは照合され、folder_123 内に存在する Google Cloud プロジェクト リソースのログは照合されません。

特定のリソースレベルでログに対してクエリを行うには、次の構文を使用します。

source(RESOURCE_TYPE/RESOURCE_ID)
リソース クエリ例
組織 source(organizations/ORGANIZATION_ID)
フォルダ source(folders/FOLDER_ID)
Google Cloud プロジェクト source(projects/PROJECT_ID)

サンプル

sample 関数は、ログエントリの総数の一部を選択します。

sample([FIELD], [FRACTION])

[FIELD] はログエントリ内のフィールド名です(logNamejsonPayload.a_field など)。フィールドの値によって、ログエントリがサンプルに含まれるかどうかが決まります。フィールド タイプは文字列または数値にする必要があります。すべてのログエントリがそのフィールドに異なる値を持つため、[FIELD]insertId に設定するのも良い選択肢です。

[FRACTION] は、[FIELD] に値があるログエントリの中で対象にするエントリの割合です。0.0 より大きく 1.0 以下の数値にします。たとえば、0.01 を指定すると、[FIELD] に値があるすべてのログエントリの約 1% がサンプルに含まれます。[FRACTION] が 1 の場合、[FIELD] に値があるすべてのログエントリが選択されます。

: 次のクエリは、ログ syslog のログエントリの約 25% を返します。

logName = "projects/my-project/logs/syslog" AND sample(insertId, 0.25)

詳細: ログエントリをサンプルに追加するかどうかは、ハッシュ値に基づく決定論的アルゴリズムによって決まります。結果のサンプルの精度は、ハッシュ値の分布によって変わります。ハッシュ値が一様に分布していない場合、結果のサンプルが偏ることがあります。[FIELD] の値が常に同じである最悪のシナリオでは、結果のサンプルにすべてのログエントリの [FRACTION] が含まれるか、ログエントリがまったく含まれないかのいずれかになります。

ログエントリに [FIELD] が含まれる場合、次のように処理されます。

  • 値のハッシュが計算されます。
  • ハッシュ値(数値)が、ハッシュの最大許容値で除算されます。
  • 結果の端数が [FRACTION] 以下の場合、ログエントリはサンプルに含められます。それ以外の場合はサンプルから除外されます。

ログエントリに [FIELD] が含まれない場合、次のように処理されます。

  • [FIELD] がログエントリのペイロードまたは labels セクションの一部である場合、[FRACTION] が 1 であっても、ログエントリはサンプルに含められません。
  • それ以外の場合、ログエントリは [FIELD] を含んでいるかのように処理されます。その際に、[FIELD] の値はデフォルト値になります。デフォルト値は、LogEntry 型によって決まります。欠落フィールドとデフォルト フィールドについて詳しくは、このドキュメントの欠落しているフィールドをご覧ください。

デフォルト フィールドがあるログエントリをサンプルから除外するには、field-exists 演算子 :* を使用します。次のクエリは、field の値を明示的に指定したログエントリの 1% のサンプルを生成します。

field:* AND sample(field, 0.01)

ip_in_net

ip_in_net 関数は、ログエントリの IP アドレスがサブネットに含まれているかどうかを判別します。これを使用して、リクエストが内部ソースと外部ソースのどちらから来たものかを知ることができます。次に例を示します。

ip_in_net([FIELD], [SUBNET])

[FIELD] は、IP アドレスまたは範囲を含むログエントリ内の文字列値フィールドです。フィールドは繰り返すことができ、その場合、サブネットに含まれるアドレスまたは範囲を持つ必要があるのは、繰り返されるフィールドのうち 1 つのみです。

[SUBNET] は、IP アドレスまたは範囲の文字列定数です。このセクションで後述するように、[SUBNET] が有効な IP アドレスまたは範囲でない場合はエラーになります。

: 次のクエリは、ログ my_log に含まれるログエントリのペイロード内にある IP アドレスをテストします。

logName = "projects/my_project/logs/my_log" AND
ip_in_net(jsonPayload.realClientIP, "10.1.2.0/24")

詳細: ログエントリ内の [FIELD] が欠落しているか、デフォルトになっているか、または有効な IP アドレスや範囲が含まれていない場合、関数は false を返します。欠落フィールドとデフォルト フィールドについて詳しくは、このドキュメントの欠落しているフィールドをご覧ください。

サポートされている IP アドレスと範囲の例を次に示します。

  • IPv4: 10.1.2.3
  • IPv4 サブネット: 10.1.2.0/24
  • CIDR IPv6: 1234:5678:90ab:cdef:1234:5678:90ab:cdef
  • CIDR IPv6 サブネット: 1:2::/48

SEARCH 関数

組み込みの SEARCH 関数を使用して、ログデータ内の文字列を検索できます。

SEARCH([query])
SEARCH([field], [query])

どちらの形式の SEARCH 関数にも query 引数が含まれています。この引数は、文字列リテラルの形式にする必要があります。最初の形式では、ログエントリ全体が検索されます。2 番目の形式では、検索するログエントリのフィールドを指定します。

query フィールドを指定する必要があります。このフィールドが指定されていない場合は、エラーが返されます。

SEARCH 関数が処理されると、query 文字列はテキスト アナライザによって処理され、文字列がトークンに分割されます。Cloud Logging では、バッククォートで囲まれたトークンであっても、常に大文字と小文字を区別せずに比較が行われます。この動作は、バッククォートで囲まれたトークンの大文字と小文字の区別を守る BigQuery の動作とは異なります。アナライザのルールについては、BigQuery ドキュメントのテキスト アナライザのルールをご覧ください。

検索を組み立てる際は、次の点を考慮してください。

  • トークンでは大文字と小文字が区別されません。次の関数も同じ結果が生まれます。

    SEARCH("world")
    SEARCH("World")
    

    上記の関数は、1 つのフィールドに「world」というトークンが含まれている場合に、ログエントリと一致します。SEARCH では部分文字列の一致ではなく完全一致を実行するため、上記の関数は値が「worldwide」のフィールドとは一致しません。

  • 検索するフィールドを指定しなければ、そのログエントリにすべてのトークンが含まれている場合に、SEARCH 関数がログエントリと一致します。ただし、トークンの順序は重要ではなく、そのトークンがログエントリの同じフィールドに存在する必要はありません。

    次の関数は同じ結果を出し、トークンの「hello」と「world」を含むログエントリと一致します。

    SEARCH("hello world")
    SEARCH("World hello")
    
  • 検索するフィールドを指定すると、SEARCH 関数はそのフィールドのみを検索します。フィールドにすべてのトークンが含まれている場合は一致しますが、トークンの順序は関係ありません。

    次の関数は、textPayload フィールドにトークンの「hello」と「world」が含まれている場合にのみ一致します。

    SEARCH(textPayload, "hello world")
    
  • フレーズの大文字と小文字を区別せずに完全一致させる場合は、フレーズをバッククォートで囲みます。たとえば、次の関数は「hello world」という文字列と一致します。

    SEARCH("`hello world`")
    SEARCH("`Hello World`")
    SEARCH("`HELLO WORLD`")
    

    次の関数ではバッククォートが使用されているため、結果が異なります。

    SEARCH("`hello world`")
    SEARCH("`world hello`")
    

Logging のクエリ言語では、ログデータを検索するさまざまな方法がサポートされています。文字列を検索する場合は、グローバル検索や部分文字列検索を行うよりも SEARCH 関数を使用するほうが効率的です。 ただし、SEARCH 関数を使用すると、テキスト以外のフィールドと一致することはありません。検索オペレーションの実行のガイダンスについては、グローバル検索と部分文字列検索の最小化をご覧ください。

時間で検索する

インターフェースでは、表示するログエントリの日時に制限を設定できます。たとえば、次の式をクエリに追加すると、プレビューには指定された 30 分間のログエントリだけが表示され、他の日時にスクロールできなくなります。

timestamp >= "2016-11-29T23:00:00Z"
timestamp <= "2016-11-29T23:30:00Z"

タイムスタンプを使用してクエリを作成する場合には、上の形式で日付と時刻を指定する必要があります。

timestamp ショートカットを使用してログエントリを検索することもできます。たとえば、比較演算子を使用して日付を入力すると、特定の日以降のすべてのログエントリを取得できます。

timestamp > "2016-11-29"

正規表現の使用

正規表現を使用してクエリを作成し、シンク、指標、ログフィルタを使用する場所のフィルタを作成できます。クエリビルダーGoogle Cloud CLI で正規表現を使用できます。

正規表現は、検索を定義する一連の文字です。Logging のクエリ言語では RE2 構文が使用されます。RE2 構文の詳細については、GitHub の RE2 Wiki をご覧ください。

正規表現クエリには次の特徴があります。

  • 正規表現と照合できるのは、文字列型のフィールドのみです。

  • 文字列の正規化は行われません。たとえば、kubernetesKUBERNETES と同じとは見なされません。詳細については、比較演算子をご覧ください。

  • クエリでは大文字と小文字が区別され、デフォルトではアンカーされません。

  • ブール演算子は、正規表現比較演算子 =~!~ の右側にある複数の正規表現の間で使用できます。

正規表現クエリの構造は次のとおりです。

パターンに一致する:

jsonPayload.message =~ "regular expression pattern"

パターンに一致しない:

jsonPayload.message !~ "regular expression pattern"

=~!~ は、クエリを正規表現クエリに変更します。照合するパターンは二重引用符で囲む必要があります。二重引用符を含むパターンをクエリするには、バックスラッシュを使用してエスケープします。

正規表現を使用してログをクエリする例

クエリの形式
標準クエリ sourceLocation.file =~ "foo"
大文字と小文字を区別しない検索でのクエリ labels.subnetwork_name =~ "(?i)foo"
引用符を含むクエリ jsonPayload.message =~ "field1=\"bar.*\""
ブール値 or を使用したクエリ labels.pod_name =~ "(foo|bar)"
アンカーを使用したクエリ logName =~ "/my%2Flog$"
パターンに一致しないクエリ labels.pod_name !~ "foo"
ブール演算子を使用したクエリ labels.env =~ ("^prod.*server" OR "^staging.*server")
値で始まるクエリ logName =~ "^foo"
ある値で終わるクエリ logName =~ "foo$"

ログエントリの迅速な検索

ログエントリを効率的に検索する方法は次のとおりです。

  • インデックス フィールドを使用したクエリ。
  • 検索対象のログエントリの数を最小限に抑える。

インデックス フィールドの使用

常に Logging は、次の LogEntry フィールドをインデックス登録します。

また、任意のログバケットにカスタム インデックス フィールドを追加することもできます。

次のセクションでは、これらのインデックス フィールドを使用して、検索対象のログエントリの数を最小限に抑える方法について説明します。

クエリを最適化する

検索対象のログの数、ログエントリの数、または期間を減らすと、検索が速くなります。3 つすべてを少なくするとさらに速くなります。

例: 正しいログ名を使用する

目的のログエントリがあるログを指定します。いずれかのログエントリを調べて、実際のログ名を確認してください。たとえば、プレビューには、Compute Engine セクションに「activity」という名前のログがあることが表示されます。管理アクティビティ監査ログのエントリをよく調べると、実際のログの名前は「cloudaudit.googleapis.com/activity」となっています。

次の比較は誤りです。ログ名が誤っているため、何も一致しません。

logName = "projects/my-project-id/logs/activity"   -- WRONG!

次の比較は正しい比較です。ここでは管理アクティビティ監査ログのログエントリが選択されます。ログ名は次のように URL エンコードする必要があります。

logName = "projects/my-project-id/logs/cloudaudit.googleapis.com%2Factivity"

例: 正しいログエントリを選択する

目的のログエントリが特定の VM インスタンスからのものであることが判明している場合は、これを指定します。検索対象のログエントリのいずれかを調べて、正しいラベル名を確認します。次の例では、instance_id はインデックス付きラベルの 1 つです。

resource.type = "gce_instance" AND
resource.labels.instance_id = "6731710280662790612"
logName = "projects/my-project-id/logs/cloudaudit.googleapis.com%2Factivity"

例: 正しい期間を選択する

検索する期間を指定します。RFC 3339 形式で便利なタイムスタンプを特定するには、GNU/Linux の date コマンドを使用すると簡単です。

$ date --rfc-3339=s
2016-06-27 17:39:00-04:00
$ date --rfc-3339=s --date="3 hours ago"
2016-06-27 14:40:00-04:00
$ date --rfc-3339=s --date="5 hours ago"
2016-06-27 12:40:00-04:00

これらのタイムスタンプの値を次のクエリで使用します。Logging で使用可能なタイムスタンプを作成する場合は、日付と時刻の間の空白を文字 T に置き換えます。

たとえば、直近 3 時間以内を検索するには、次のようにします。

timestamp >= "2016-06-27T14:40:00-04:00"

直近 5 時間前から 3 時間前までの範囲を検索するには、次のようにします。

timestamp >= "2016-06-27T12:40:00-04:00" AND
timestamp <= "2016-06-27T14:40:00-04:00"

グローバル検索と部分文字列検索の最小化

クエリの入力時は近道をしようとしないでください。

例: グローバル検索を使用しない

ペイロードに「Hello, Kitty」という文字列があるログエントリを検索する場合について説明します。

  • グローバル検索は使用しないでください。理由のひとつとして、それらはすべて部分文字列検索であるためです。

       "Hello Kitty"   -- THIS CAUSES A SLOW SEARCH!
       

  • 検索対象は必ず 1 つのフィールドに限定するようにしてください。これは部分文字列検索を継続する場合も同様です。

       textPayload:"Hello Kitty"
       

  • 可能であれば、等式テストを実行するようにしてください。

       textPayload = "Hello Kitty"
       

  • ログエントリに構造化ペイロードがある場合は、ペイロードの各フィールドを参照するようにしてください。

       jsonPayload.my_favorite_cat = "Hello Kitty"
       

  • インデックス フィールドで検索範囲を制限するようにしてください。

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

  • SEARCH 関数でテキスト全体を指定して、一致させることを推奨します。SEARCH 関数は、大文字と小文字を区別しない一致を実行します。

      SEARCH("Hello Kitty")
      

    SEARCH 関数で部分的なテキストを指定しないでください。たとえば、次の関数は「Hello, Kitty」とは一致しません。

      SEARCH("Hello Kit")
      

検索例

クエリに一致するログエントリが表示されます。[時間を選択] メニューに値がある場合には、画面をスクロールして、その時間まで移動できます。次に例を示します。

resource.type=gae_app

すべての App Engine ログエントリを検索します。リソースタイプの一覧については、モニタリング対象リソースのリストをご覧ください。

入力時、プレビューには、resource.type などのフィールドの入力候補が表示されます。

resource.type=gae_app AND logName:request_log

request_log を含むログ名から、App Engine アプリのログエントリを検索します。注意事項:

  • = 演算子は完全に同じであることを意味します。リソースタイプは "gae_app" でなければなりませんが、大文字と小文字は区別されません。
  • : 演算子は "has" を意味します。つまり、logName フィールドに request_log が含まれていなければなりません。ただし、大文字と小文字は区別されません。実際のログ名はずっと長いため、: を使用すると検索に時間がかかる場合があります。
  • この 2 つの比較は AND で結合されています。OR を使用することもできますが、何も指定しない場合は AND であるとみなされます。
resource.type = (gce_instance OR aws_ec2_instance) AND severity >= ERROR

リソースタイプが Compute Engine VM インスタンスまたは AWS EC2 VM インスタンスのいずれかであるログエントリを検索します。ログエントリの severity が少なくとも ERROR であることが必要です。これは、クエリ インターフェースの重大度メニューで [ERROR] を選択することと同じです。

logName = "projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"

プロジェクト [PROJECT_ID] から、管理アクティビティの監査ログエントリをすべて検索します。すべての監査ログがプロジェクト内で同じログ名を使用しますが、リソースタイプは異なります。ログ ID の cloudaudit.googleapis.com/activity は、ログ名で URL エンコードされている必要があります。比較に等価演算子を使用すると検索をスピードアップできます。詳細については、監査ログについてをご覧ください。

unicorn

unicorn を含むログエントリを任意のフィールドから検索します。大文字と小文字は区別しません。フィールド比較に含まれない検索語は、「すべてのフィールド」クエリです。

unicorn phoenix

一部のフィールドに unicorn が含まれていて、かつ、一部のフィールドに phoenix が含まれているログエントリを検索します。

textPayload:(unicorn phoenix)

順序は関係なく、textPayload フィールドに unicornphoenix の両方が含まれているログエントリを検索します。2 つのキーワードは暗黙に AND で結合されます。

textPayload:"unicorn phoenix"

textPayload フィールドに文字列 "unicorn phoenix" を含むログエントリを検索します。

NOT textPayload: "unicorn phoenix"

textPayload フィールドに文字列 "unicorn phoenix" を含まないログエントリを検索します。このタイプのクエリは、不要なログエントリを減らします。

timestamp >= "2016-11-29T23:00:00Z" timestamp <= "2016-11-29T23:30:00Z"

30 分間のログエントリを検索します。

トラブルシューティング

構文の問題

クエリの式に問題がある場合は、次の点を確認してください。

  • クエリが構文ルールに従っていて、かっこや引用符が正しく対応しているか確認します。

  • ログエントリのフィールド名が正しく入力されているか確認します。

  • ブール演算子が大文字で入力されているか確認します(ANDORNOT)。

  • JSON の null 値を表すのに NULL_VALUE を使用していることを確認します。

  • グローバル制限または比較の右辺として使用されているブール式が、かっこで囲まれ明確になっているか確認します。たとえば、次の 2 つのクエリは同じように見えますが、実際は異なります。

    insertId = "ABC-1" OR "ABC-2"  -- ERROR!?
    insertId = ("ABC-1" OR "ABC-2")
    
  • 引用符で囲まれていないテキストに特殊文字を含めることはできません。正しいかわからない場合は、二重引用符を使用してください。たとえば、次のうち最初の比較は、組み込みの部分文字列演算子(:)が使用されているため、誤りです。この比較では二重引用符を使用しなければなりません。

    insertId = abc:def  -- ILLEGAL!
    insertId = "abc:def"
    
  • Google Cloud CLI では、フィルタを二重引用符で囲む必要があります。gcloud logging コマンドで特殊文字をエスケープするために二重引用符を使用するには、フィルタ全体を単一引用符で囲みます。

    gcloud logging read 'resource.type=gce_instance AND jsonPayload.message="Stopped Unattended Upgrades Shutdown."'
    gcloud logging read 'timestamp>="2020-06-17T21:00:00Z"'
    

  • Any メッセージ タイプに関連付けられたフィールドでフィルタすると、value フィールドが自動的に走査されます。そのため、クエリには、value を含めないでください。

    たとえば、AuditLog メッセージの Status フィールドには、型が google.protobuf.Anydetails フィールドがあります。details フィールドをクエリするには、フィルタを指定するときに value フィールドを省略します。

    • 推奨事項

      protoPayload.status.details.conditionNotMet.userVisibleMessage =~ "Specified reservation.*"
      
    • してはいけないこと

      protoPayload.status.details.value.conditionNotMet.userVisibleMessage =~ "Specified reservation.*"