高度なログフィルタ

高度なログフィルタを作成する方法を説明します。ログフィルタは、任意の数のログから特定のログエントリを指定するための式です。高度なログフィルタは、ログビューアStackdriver Logging APIコマンドライン インターフェースで使用できます。

はじめに

高度なログフィルタは、プロジェクト内のすべてのログエントリの中からサブセットを指定するブール式です。これを使用することで、次のことができます。

  • 特定のログやログサービスからログエントリを選択する。
  • 特定の時間範囲内のログエントリを選択する。
  • メタデータやユーザー定義フィールドに対する条件を満たすログエントリを選択する。
  • すべてのログエントリのサンプリング率を選択する。

ログビューアで高度なフィルタを使用するには、検索バーの端にあるメニュー(▾)を選択し、[高度なフィルタに変換] を選択します。高度なフィルタのインターフェースが次の図のように表示されます。

高度なログフィルタ

次に、高度なフィルタの簡単な例を示します。

v1 のログエントリ

metadata.serviceName = "compute.googleapis.com" AND
metadata.severity >= ERROR AND
NOT textPayload:robot

v2 のログエントリ

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

このフィルタは、Google Compute Engine からのログエントリのうち、重大度が ERROR 以上であり、textPayload フィールド内に「robot」という文字列がないエントリと一致します。文字列の比較では、大文字と小文字は区別されません。metadataserviceNameresourceseveritytextPayload の名前はいずれも LogEntry タイプと LogEntry v2 タイプで定義されています。

入力時の提案とハイライト ログビューアで高度なフィルタを入力すると、特定のログエントリ フィールドについての提案が表示される場合があります。この提案は、フィルタ言語と、ログビューアでロードされた実際のログエントリの両方から生成されます。提案を選択するには、Tab キーを押します。提案が表示されない場合は、Ctrl キーを押しながら Space キーを押してみてください。フィルタ式は部分ごとに異なる色で強調表示されます。式が明るい赤色で表示されている場合、入力済みのフィルタはエラーがあるか、不完全です。

引用符で囲まれていないテキスト: 空白文字や特定の特殊文字を含まないテキスト文字列は、前後の引用符を省略することができます。これは、引用符で囲まれていないテキストといいます。前の例では ERRORrobot がこれに該当します。文字列 "appengine.googleapis.com" にはピリオドが含まれているため、引用符で囲んでいます。文字列内で引用符を使用する場合には、引用符の前にバックスラッシュ(\)を追加します。

ベスト プラクティス: フィールド値と比較する文字列は引用符で囲むようにしてください。引用符で囲んでおくと、比較の意味が変わったり、デバッグが困難になるような誤りを防ぐことができます。文字の後に連続した文字、数字、アンダースコア(_)が続く単語の場合は、引用符を省略しても安全です。

高度なフィルタの構文

ここでは、高度なフィルタの構文と照合方法について説明します。

構文の表記法

高度なフィルタの構文は、次の表記を使用して記述されます。

  • 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 }
    
  • 比較は、名前が付いているログエントリ フィールドと値を照合します。 一般的な比較演算子をすべて使用できます。 has 演算子(コロン)を使用すると、文字列値をログエントリ フィールドの任意の部分文字列と照合できます。

    comparison = name OP value
               | value
    OP = "<=" | "<" | ">=" | ">"  | "!=" | "=" | ":"
    

    1 つの値のみで構成される比較はグローバル制限と呼ばれます。値は has 演算子を使用してログエントリのすべてのフィールドと比較されます。

  • 高度なフィルタに指定できる値は、数値、文字列、関数、またはかっこで囲まれた式です。文字列は任意のテキストや、ブール値、列挙型の値、およびバイト文字列の値を表すために使用します。

    value = number
          | string
          | function
          | "(" expression ")"
    

この後の各セクションでは、フィルタや照合について詳しく説明します。

ブール式

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

ブール演算子 AND と OR は短絡演算子です。NOT 演算子の優先順位が最も高く、その後に OR、AND の順に続きます。たとえば、次の 2 つの式は同じ内容を表します。

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

比較の間の AND 演算子は省略できます。また、NOT の代わりに -(マイナス記号)を使用できます。たとえば、次の 2 つの高度なフィルタは同じ内容を表しています。

c=d AND NOT e=f
c=d -e=f

このドキュメントでは、AND を省略していません。また、NOT の代わりに - を使用することもありません。

比較

このセクションでは「name OP value」の形式の比較について説明します。グローバル制限である比較については、この後のセクションで説明します。

comparison = name OP value
OP = "<=" | "<" | ">=" | ">" | "!=" | "=" | ":"
name = identifier { "." identifier }
identifier = unquoted_text | string
value = number | string | unquoted_text | function | "*"
      | "(" expression ")"

比較の左辺は、名前で説明する通り、通常はスカラー ログエントリのフィールドのパス名です。右辺は通常スカラー値で、フィールドのタイプに変換されて比較されます。配列の処理などの詳細については、値と変換をご覧ください。

ログエントリのフィールドは、値の配列である場合があります。詳細についてはこの後の名前をご覧ください。

右辺の値がかっこで囲まれた比較の組み合わせのブール値である場合、フィールド名と比較演算子は各値に適用されます。たとえば、次の 2 つの高度なフィルタは同じ内容です。

v1 のログエントリ

structPayload.cat = ("siamese" OR "shorthair")

structPayload.cat = "siamese" OR
structPayload.cat = "shorthair"

v2 のログエントリ

jsonPayload.cat = ("siamese" OR "shorthair")

jsonPayload.cat = "siamese" OR
jsonPayload.cat = "shorthair"

名前

ログエントリはいずれもタイプが LogEntry または LogEntry(v2)のインスタンスです。つまり、フィールドのパスの最初の識別子は、LogEntry タイプで定義されたフィールドである必要があります。最初のパス識別子が metadata である場合、次の識別子は LogEntryMetadata タイプのフィールドである必要があります。最初のパス識別子が httpRequest である場合、次の識別子は HttpRequest タイプのフィールドである必要があります。高度なフィルタで使用できるすべての名前を以下に示します。

v1 のログエントリ

詳細については、v1 LogEntry タイプをご覧ください。

log
insertId
httpRequest.FIELD          # The value of a field in an HttpRequest object.
metadata.FIELD             # The value of a field within a LogEntryMetadata object.
metadata.labels.KEY        # The value associated with a metadata label key.
protoPayload.FIELD         # The value of a field within a protocol buffer object.
structPayload.FIELD        # The value of a field within a JSON object.
textPayload

v2 のログエントリ

詳しくは、v2 LogEntry タイプをご覧ください。

logName
insertId
severity
timestamp
resource.type              # The name of a resource type. Example: "gce_instance".
resource.labels.KEY        # The value associated with a resource label key.
httpRequest.FIELD          # the value of a field in an HttpRequest object.
labels.KEY                 # The value associated with a label key.
operation.FIELD            # The value of a field in a LogEntryOperation object.
protoPayload.FIELD         # The value of a field within a protocol buffer object.
jsonPayload.FIELD          # The value of a field within a JSON object.
textPayload

どのログエントリについても、ペイロード フィールドは textPayloadprotoPayloadstructPayload(v1)、jsonPayload(v2)のいずれか 1 つです。フィールド httpRequestoperation は、ログエントリでは省略可能です。オブジェクトまたは配列を参照する名前の使用について詳しくは、オブジェクトと配列のタイプをご覧ください。

サービス名とリソースタイプ

検索を高速化するには、ログサービス名(v1)またはモニタリング対象リソースタイプ(v2)を指定します。サービス名とリソース名の一覧は、モニタリング対象リソースタイプをご覧ください。

たとえば、Google Container Engine は v1 API では container.googleapis.com というサービス名、v2 API では 2 つのリソースタイプ containergke_cluster を使用しています。次の例は、検索範囲を Container Engine リソースに限定する方法を示しています。

v1 のログエントリ

metadata.serviceName = "container.googleapis.com"

v2 のログエントリ

resource.type = ("container" OR "gke_cluster")

サービス名とリソースタイプのインデックスが作成されます。部分文字列の一致を使用すると、クエリが遅くなります。

欠落しているフィールド

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

  • フィールドがログエントリのペイロード(jsonPayloadstructPayload、または protoPayload)内にあるか、ログエントリの labels セクションにある場合、フィールドは欠落しています。Stackdriver Logging は、フィールドが許可されているかどうかを判断できません。特に記載がない限り、欠落しているフィールドに関係するすべての比較は無応答で失敗します。

    例: jsonPayload.nearest_storeprotoPayload.name.nickname

  • フィールドが LogEntry タイプで定義されている、もしくはそのコンポーネント タイプ LogEntryMetadata(v1)、HttpRequestLogEntryOperation、または LogEntrySourceLocation で定義されている場合、フィールドはデフォルト設定されています。フィールドのデフォルト値がすべての比較に使用されます。

    例: httpRequest.remoteIptraceoperation.producer

  • それ以外の場合、フィールドは未定義です。Stackdriver Logging は LogEntry の固定部分に定義されているフィールドを認識しているためです。未定義のフィールドを使用するとエラーになります。

    例: thudoperation.thudtextPayload.thud

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

operation.id:*

オブジェクトと配列のタイプ

このセクションでは、Stackdriver Logging が a.b.c のような名前を処理する方法に関する用語を説明します。

このドキュメントでは、ログエントリ フィールドの説明でスカラーオブジェクト、,配列の各用語を使用しています。各ログエントリ フィールドにはタイプがあり、doublestring のようなスカラータイプか、他のフィールドが中に格納されているオブジェクト タイプのいずれかになります。オブジェクト タイプの例として、プロトコル バッファ メッセージや JSON オブジェクトがあげられます。

同様に、どのログエントリ フィールドにも、当該タイプの 1 つのインスタンス、またはインスタンスの配列を格納できます。すべて同じタイプの値の配列を格納するプロトコル バッファの繰り返しフィールドや JSON フィールドは配列フィールドの例です。

Stackdriver Logging で使用されるタイプの中には、実際にはオブジェクト タイプですが、文字列との間での変換が可能なのでスカラーとして扱われるものがあります。このようなタイプには、DurationTimestamp などがあります。

比較のパス名

比較で使用されているフィールドの名前がたとえば a.b.c の場合、このフィールドは次のように扱われます。

  • 通常、a はフィールド b があるオブジェクトで、b はフィールド c があるオブジェクトで、c はタイプがスカラーです。フィールド c の値が比較の右辺の値に対してテストされます。欠落しているフィールドの処理については欠落しているフィールドをご覧ください。

  • フィールド c が配列である場合、a.b.c に関連する比較はすべてのインスタンス(a.b.c[0]、a.b.c[1]、...)を比較します。 いずれかのインスタンスが一致する場合、この比較は成功となります。 ([0]、[1]、... のような表記は高度なフィルタでは使用できません。ここではあくまで便宜上このように表記しています)

  • フィールド b も同様に配列である場合がありますが、その場合、a.b.c に関係する比較はすべてのインスタンス(a.b[0].ca.b[1].c、...)を比較します。 いずれかのインスタンスが一致する場合、この比較は成功となります。

値と変換

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

フィールド タイプ 使用できるフィルタ値
bool 「true」または「false」(大文字と小文字は区別しません)。例: "True"true
bytes 任意の連続したバイトを含む文字列。例: "\377\377"
Duration 符号付き 10 進数の後に nsusmssmh のいずれかの単位が続いている文字列。この期間はナノ秒単位の精度です。例: "3.2s"
enum 列挙型のリテラルの名前。大文字と小文字は区別されません。例: WARNING。これは LogSeverity タイプの値です。
double 任意の数値(符号と指数はある場合もない場合もあります)、または特殊な値の文字列("NaN""-Infinity""Infinity"。先頭の大文字と小文字は区別されません)。例: -3.2e-8"nan"
intNN タイプのサイズを超えない符号付き整数。例: -3
string UTF-8 でエンコードされたテキスト、または 7 ビットの ASCII テキストを含む任意の文字列。文字列内で引用符を使用する場合には、バックスラッシュでエスケープする必要があります。
Timestamp RFC3339 形式の文字列。例: "2014-10-02T15:01:23.045Z"。フィルタ式では、タイムスタンプに Z または ±hh:mm でタイムゾーンを指定することができます。タイムスタンプは、ナノ秒単位の精度で表されます。
uintNN タイプのサイズを超えない符号なし整数。例: 1234

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

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

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

ログフィールドのタイプ

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

  • LogEntry(v1)LogEntry(v2)の各タイプ、そのコンポーネント タイプで定義されたログフィールドはプロトコル バッファ フィールドです。 プロトコル バッファ フィールドには明示的なタイプがあります。

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

  • structPayload(v1)または jsonPayload(v2)の内部のログフィールドには、ログエントリの受信時にフィールドの値から推測されるタイプがあります。

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

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

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

比較演算子

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

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

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

グローバル制限

    comparison = name OP value
               | value

比較構文の 2 番目の形式は、1 つだけの値で構成され、グローバル制限と呼ばれています。次の例では、最初の 2 つの高度なフィルタのそれぞれに 1 つのグローバル制限があります。3 番目のフィルタは複数のグローバル制限を組み合わせたブール式です。

3.14159
"The Cat in The Hat"
(cat AND (hat OR bat))

グローバル制限では、値がログエントリ内のすべてのフィールドと比較されます。この比較では has:)演算子が使用されます。値は比較の前に各フィールドのタイプに変換されます。この変換が失敗した場合、そのフィールドでの照合も失敗します。値がいずれかのフィールドと一致すると、このグローバル制限は成功となります。

上の例の 3 番目のフィルタでは、グローバル制限がそれぞれの値に個別に適用されてから、式にかっこがない場合と同様に組み合わされます。つまり、ログエントリのフィールドのいずれかに、cat と、hat または bat がある必要がありますが、同一のフィールドである必要はありません。

グローバル制限を使用すると、ログで特定の値を簡単に検索できます。たとえば、アクティビティ ログで GCE_OPERATION_DONE について言及しているエントリを検索する場合、次のようなフィルタを使用できます。

v1 のログエントリ

log = "compute.googleapis.com/activity_log" AND
"GCE_OPERATION_DONE"

v2 のログエントリ

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

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

関数

高度なフィルタでは、組み込み関数をグローバル制限として使用できます。

function = identifier "(" [ argument { "," argument } ] ")"
argument = value | name | "(" expression ")"

関数はこれ以降のセクションで説明されます。

sample

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

sample([FIELD], [FRACTION])

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

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

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

v1 のログエントリ

log = syslog AND sample(insertId, 0.25)

v2 のログエントリ

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

詳細: サンプルのログエントリの選択にランダム性はありません。[FIELD] の値はハッシュされ、指定されたハッシュ値の割合がサンプルに対して選択されます。

ハッシュ値が一様に分布していない場合、結果のサンプルは偏ることがあります。最悪の場合、[FIELD] の値が常に同じである場合、結果のサンプルは、すべてのログエントリが含まれるか、ログエントリが全く含まれないかのいずれかになります。

[FIELD] にログエントリの値が指定されていない場合は、次のように扱われます。

  • [FIELD] がログエントリのペイロードまたは labels セクションの一部である場合、[FRACTION] が 1 であっても、ログエントリはサンプルに対して選択されません。
  • [FIELD] がペイロードの一部でない場合は、LogEntry タイプに定義を持ちます。フィールドは、デフォルト値が指定されているかのように扱われます。サンプルに対してログエントリが選択されるかどうかは、フィールドのデフォルト値のハッシュ方法と [FRACTION] の値によって決まります。

欠落フィールドとデフォルト設定されたフィールドについて詳しくは、欠落しているフィールドをご覧ください。

デフォルト設定されたフィールドがあるログエントリをサンプルから除外するには、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 アドレスをテストします。

v1 のログエントリ

log = "my_log" AND
ip_in_net(structPayload.realClientIP, "10.1.2.0/24")

v2 のログエントリ

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

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

ログエントリのフィルタリングや照会では、次のようにします。

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

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

インデックス フィールドには正確な値を指定します。部分文字列一致は使用しないでください。次のログエントリ フィールドがインデックス登録されています。

v1 のログエントリ

次のフィールドがインデックス登録されています。

v2 のログエントリ

次のフィールドがインデックス登録されています。

一時的なフィールド インデックス

Stackdriver Logging がログエントリを受信した後、一定時間に限り 3 つの追加ログエントリ フィールドが部分的にインデックス登録されます。システムの問題に迅速に対応する必要がある場合、これらのフィールドを検索すると便利なことがあります。Stackdriver Logging では、これらの 3 つのフィールドのインデックス登録の方法が、将来的に、通知なく変更される場合があります。

  • metadata.severity(v1)severity(v2): NOTICE(100)から EMERGENCY(900)までの重大度値がインデックス登録されます。インデックスを使用するには、これらのインデックスに登録されている範囲の値のみを検索します。

  • httpRequest.status(v1)httpRequest.status(v2): 201 から 511 までのステータス値がインデックス登録されます。インデックスを使用するには、これらのインデックスに登録されている範囲の値のみを検索します。

  • operation.id(v1)operation.id(v2): これらのフィールドの値はすべてインデックス登録されます。インデックスを使用するには、等式演算子を使用してこのフィールドを検索します。部分文字列検索は使用しないでください。

最近のログエントリでこれらのフィールドを定期的に検索する場合は、metadata.timestamp(v1)または timestamp(v2)フィールドを使用して検索対象期間を限定することも検討してください。

ログ、ログエントリ、時間の最小化

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

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

目的のログエントリがあるログを指定します。いずれかのログエントリを調べて、実際のログ名を確認してください。たとえば、ログビューアの [Compute Engine] セクションに「activity_log」というログがあります。アクティビティ ログのエントリをよく見てみると、実際のログの名前が「compute.googleapis.com/activity_log」であることがわかります。アクティビティ ログを参照する誤った方法と正しい方法を以下に示します。

v1 のログエントリ

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

log = "activity_log"   # WRONG!

次の比較は正しい比較です。この比較ではアクティビティ ログのログエントリが選択されます。

log = "compute.googleapis.com/activity_log"

v2 のログエントリ

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

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

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

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

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

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

v1 のログエントリ

log = "compute.googleapis.com/activity_log" AND
metadata.serviceName = "compute.googleapis.com" AND
metadata.labels."compute.googleapis.com/resource_id" = "6731710280662790612"

v2 のログエントリ

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

サービス名(v1)またはリソースタイプ(v2)の値を指定する必要があります。指定しない場合、resource_id の比較でインデックスは使用されません。

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

検索対象の期間を指定する必要があります。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

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

v1 のログエントリ

直近 3 時間以内を検索する場合:

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

直近 5 時間前から 3 時間前までの範囲を検索する場合

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

v2 のログエントリ

直近 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"

タイムスタンプの別の使用例を一時的なフィールド インデックスで紹介しています。

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

ロギング フィルタの入力時は近道をしようとしないでください。

例: インデックス フィールドで部分文字列を使用しない

Apache2 ウェブサーバーで v2 ログエントリを検索しようとしています。Apache ログの名前は apache-accessapache-error であることがわかっています。この場合の対応について説明します。

v1 のログエントリ

  • 入力を減らすために部分文字列一致を使用することは避けてください。

    log:apache   # THIS CAUSES A SLOW SEARCH!
    
  • インデックス付きフィールドを検索する場合は、必ず完全一致を使用してください。

    log = ("apache-access" OR "apache-error")
    

v2 のログエントリ

  • 入力を減らすために部分文字列一致を使用することは避けてください。

    logName:apache   # THIS CAUSES A SLOW SEARCH!
    
  • インデックス付きフィールドを検索する場合は、必ず完全一致を使用してください。

    logName = ("projects/my-project-id/logs/apache-access" OR
               "projects/my-project-id/logs/apache-error")
    

部分文字列検索を行うと、インデックス付きフィールドの迅速性が完全に失われます。

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

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

v1 のログエントリ

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

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

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

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

    structPayload.my_favorite_cat = "Hello, Kitty"
    
  • インデックス付きフィールドで検索範囲を制限するようにしてください。

    log = "somelog" AND
    structPayload.my_favorite_cat = "Hello, Kitty"
    

v2 のログエントリ

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

    "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"
    

トラブルシューティング

高度なフィルタに問題がある場合は、次の点を確認してください。

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

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

  • 正しいログエントリのバージョン(v1 または v2)のフィールド名を使用しているか確認します。

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

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

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

    insertId = abc:def  # ILLEGAL!
    insertId = "abc:def"
    
  • ログビューアの基本フィルタの検索式は、高度なフィルタの検索式とは異なります。詳しくは、基本フィルタと高度なフィルタの違いをご覧ください。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

ご不明な点がありましたら、Google のサポートページをご覧ください。