Logging のクエリ言語

このページでは、ログデータのクエリとログシンクの作成に使用されるロギングクエリ言語について説明します。

クエリは、Google Cloud Console の Cloud Logging クエリビルダー ペイン、Logging API、またはコマンドライン インターフェースで使用できます。

クエリ構文

ここでは、クエリの構文と照合方法について説明します。

クエリとは、任意の数のログから一連のログエントリを指定できる式のことです。クエリは、プロジェクトのログエントリ全体のうちの特定部分を指定するブール式です。

論理演算子 ANDOR を使用して、次の 4 つの分類項目に基づいたクエリを作成できます。

  • リソース: 詳細については、resource.type をご覧ください。
  • ログ名: 詳細については、logName をご覧ください。
  • 重大度: 詳細については、severity をご覧ください。
  • 時間範囲: 詳細については、timestamp をご覧ください。

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

構文の表記法

クエリの構文は、次の表記を使用して記述されます。

  • a = e: a は式 e の名前です。
  • a b: a の後に b が続きます。
  • a | b: 「a または b」を意味します。
  • ( e ): グループ化に使用します。
  • [ e ]: e は省略可能です。
  • { e }: e は 0 回以上繰り返すことができます。
  • "abc": 表示されるとおりに abc と記述されている必要があります。

構文の概要

このセクションでは、クエリ構文の概要を説明します。

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

   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"

以降のセクションでは、クエリと照合についてさらに詳しく説明します。

ブール演算子

ブール演算子 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 を使用します。

比較

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

[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 にはスラッシュ(/)が含まれているため、二重引用符で囲む必要があります。

    詳細は、このページのフィールドパス識別子をご覧ください。

  • [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] は、比較の前にフィールドの型に変換されます。

[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 フィールドは文字列のため、その後にサブフィールド名を続けることはできません。

特殊文字

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 マッピングをご覧ください。

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

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

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

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

比較演算子

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

  • すべての数値型: 等式と不等式は通常の数値の場合での意味と同じです。
  • 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")

sample

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

時間で検索する

インターフェースでは、表示するログエントリの日時に制限を設定できます。たとえば、次の条件をクエリに追加すると、ログ エクスプローラには指定された 30 分間のログエントリのみが表示され、対象の期間外にスクロールできなくなります。

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

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

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

  timestamp > "2016-11-29"

正規表現の使用

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

正規表現は、検索を定義する一連の文字です。クエリ言語では 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")