Contoh kueri SQL

Dokumen ini berisi contoh kueri yang dapat Anda gunakan untuk membuat kueri data log dan rekaman aktivitas.

Dukungan bahasa SQL

Kueri yang digunakan di halaman Log Analytics mendukung fungsi GoogleSQL dengan beberapa pengecualian.

Perintah SQL berikut tidak didukung untuk kueri SQL yang dikeluarkan menggunakan halaman Log Analytics:

  • Perintah DDL dan DML
  • Fungsi yang ditentukan pengguna di JavaScript
  • Fungsi BigQuery ML
  • Variabel SQL

Berikut hanya didukung saat Anda mengkueri set data tertaut menggunakan halaman BigQuery Studio dan Looker Studio, atau menggunakan alat command line bq:

  • Fungsi yang ditentukan pengguna di JavaScript
  • Fungsi BigQuery ML
  • Variabel SQL

Praktik terbaik

Untuk menetapkan rentang waktu kueri, sebaiknya Anda menggunakan pemilih rentang waktu. Misalnya, untuk melihat data selama seminggu terakhir, pilih 7 hari terakhir dari pemilih rentang waktu. Anda juga dapat menggunakan pemilih rentang waktu untuk menentukan waktu mulai dan berakhir, menentukan waktu untuk melihat-lihat, dan mengubah zona waktu.

Data log

Jika Anda menyertakan kolom timestamp dalam klausa WHERE, setelan pemilih rentang waktu tidak akan digunakan. Contoh berikut menunjukkan cara memfilter menurut stempel waktu:

-- Matches log entries whose timestamp is within the most recent 1 hour.
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

Data rekaman aktivitas

Jika Anda menyertakan kolom start_time dalam klausa WHERE, setelan pemilih rentang waktu tidak akan digunakan. Contoh berikut menunjukkan cara memfilter menurut stempel waktu:

-- Matches trace spans whose start_time is within the most recent 1 hour.
WHERE start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

Untuk mengetahui informasi selengkapnya tentang cara memfilter menurut waktu, lihat Fungsi waktu dan Fungsi stempel waktu.

Sebelum memulai

  1. Login ke akun Google Cloud Anda. Jika Anda baru menggunakan Google Cloud, buat akun untuk mengevaluasi performa produk kami dalam skenario dunia nyata. Pelanggan baru juga mendapatkan kredit gratis senilai $300 untuk menjalankan, menguji, dan men-deploy workload.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Aktifkan Observability API.

    Peran yang diperlukan untuk mengaktifkan API

    Untuk mengaktifkan API, Anda memerlukan peran IAM Service Usage Admin (roles/serviceusage.serviceUsageAdmin), yang berisi izin serviceusage.services.enable. Pelajari cara memberikan peran.

    Mengaktifkan API

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Aktifkan Observability API.

    Peran yang diperlukan untuk mengaktifkan API

    Untuk mengaktifkan API, Anda memerlukan peran IAM Service Usage Admin (roles/serviceusage.serviceUsageAdmin), yang berisi izin serviceusage.services.enable. Pelajari cara memberikan peran.

    Mengaktifkan API

  8. Untuk mendapatkan izin yang Anda perlukan untuk memuat halaman Log Analytics, menulis, menjalankan, dan menyimpan kueri pribadi pada data rekaman aktivitas Anda, minta administrator untuk memberi Anda peran IAM berikut:

    • Pengakses Tampilan Observasi (roles/observability.viewAccessor) pada tampilan observasi yang ingin Anda kueri. Peran ini mendukung kondisi IAM, yang memungkinkan Anda membatasi pemberian akses ke tampilan tertentu. Jika Anda tidak melampirkan kondisi pada pemberian peran, akun utama dapat mengakses semua tampilan kemampuan pengamatan. Tampilan kemampuan pengamatan tersedia dalam Pratinjau Publik.
    • Pengguna Analytics Observabilitas (roles/observability.analyticsUser) di project Anda. Peran ini berisi izin yang diperlukan untuk menyimpan dan menjalankan kueri pribadi, serta menjalankan kueri bersama.
    • Logs Viewer (roles/logging.viewer) di project Anda.
    • Logs View Accessor (roles/logging.viewAccessor) di project yang menyimpan tampilan log yang ingin Anda kueri.

    Untuk mengetahui informasi selengkapnya tentang pemberian peran, lihat Mengelola akses ke project, folder, dan organisasi.

    Anda mungkin juga bisa mendapatkan izin yang diperlukan melalui peran khusus atau peran bawaan lainnya.

Cara menggunakan kueri di halaman ini

  1. Di konsol Google Cloud , buka halaman Log Analytics:

    Buka Log Analytics

    Jika Anda menggunakan kotak penelusuran untuk menemukan halaman ini, pilih hasil yang subjudulnya adalah Logging.

  2. Di panel Query, klik  SQL, lalu salin dan tempel kueri ke panel kueri SQL.

    Data log

    Sebelum Anda menyalin kueri, di klausa FROM, ganti kolom berikut

    • PROJECT_ID: ID project.
    • LOCATION: Lokasi tampilan log atau tampilan analisis.
    • BUCKET_ID: Nama atau ID bucket log.
    • LOG_VIEW_ID: ID tampilan log, yang dibatasi hingga 100 karakter dan hanya dapat menyertakan huruf, angka, garis bawah, dan tanda hubung.

    Berikut menunjukkan format klausa FROM untuk tampilan log:

    FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
    

    Contoh log di halaman ini membuat kueri tampilan log. Untuk mengirim kueri tampilan analisis, gunakan format jalur berikut: `analytics_view.PROJECT_ID.LOCATION.ANALYTICS_VIEW_ID`. Dalam ekspresi sebelumnya, PROJECT_ID adalah ID project Anda, dan LOCATION serta ANALYTICS_VIEW_ID adalah lokasi dan nama tampilan analisis Anda.

    Data rekaman aktivitas

    Berikut ini menunjukkan format penyebab FROM untuk membuat kueri tampilan _AllSpans:

    FROM `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
    

    Klausul FROM berisi kolom berikut:

    • PROJECT_ID: ID project.
    • LOCATION: Lokasi bucket pengamatan.
    • _Trace adalah nama bucket pengamatan
    • Spans adalah nama set data.
    • _AllSpans adalah nama tampilan.

Untuk menggunakan kueri yang ditampilkan dalam dokumen ini di halaman BigQuery Studio atau menggunakan alat command line bq, lalu edit klausa FROM dan masukkan jalur ke set data tertaut.

Data log

Misalnya, untuk membuat kueri tampilan _AllLogs pada set data tertaut bernama mydataset yang ada di project myproject, jalur yang digunakan adalah myproject.mydataset._AllLogs.

Data rekaman aktivitas

Misalnya, untuk membuat kueri tampilan _AllSpans pada set data tertaut bernama my_linked_dataset yang ada di project myproject, jalur yang digunakan adalah `myproject.my_linked_dataset._AllSpans`.

Kasus penggunaan umum

Bagian ini mencantumkan beberapa kasus penggunaan umum yang dapat membantu Anda membuat kueri kustom.

Menampilkan entri log di bucket log default

Untuk mengkueri bucket _Default, jalankan kueri berikut:

SELECT
  timestamp, severity, resource.type, log_name, text_payload, proto_payload, json_payload
FROM
  `PROJECT_ID.LOCATION._Default._AllLogs`
-- Limit to 1000 entries
LIMIT 1000

Mengekstrak nilai kolom dengan ekspresi reguler

Untuk mengekstrak nilai dari string menggunakan ekspresi reguler, gunakan fungsi REGEXP_EXTRACT:

SELECT
  -- Display the timestamp, and the part of the name that begins with test.
  timestamp, REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Get the value of jobName, which is a subfield in a JSON structure.
  JSON_VALUE(json_payload.jobName) IS NOT NULL
ORDER BY timestamp DESC
LIMIT 20

Untuk mengetahui informasi selengkapnya, lihat dokumentasi REGEXP_EXTRACT.

Untuk kecocokan substring, seperti kueri sebelumnya, penggunaan fungsi CONTAINS_SUBSTR menghasilkan kueri yang lebih efisien.

Menampilkan semua data rekaman aktivitas

Untuk membuat kueri tampilan _AllSpans, jalankan kueri berikut:

-- Display all data.
SELECT *
FROM `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
-- Limit to 10 entries.
LIMIT 10

Menampilkan informasi rentang umum

Untuk menampilkan informasi rentang umum, seperti waktu mulai dan durasi, jalankan kueri berikut:

SELECT
  start_time,
  -- Set the value of service name based on the first non-null value in the list.
  COALESCE(
    JSON_VALUE(resource.attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."g.co/gae/app/module"')) AS service_name,
  name AS span_name,
  duration_nano,
  status.code AS status,
  trace_id,
  span_id
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
LIMIT 10

Untuk mempelajari lebih lanjut, lihat Ekspresi bersyarat.

Menampilkan persentil ke-50 dan ke-99 dari latensi rentang

Untuk menampilkan persentil ke-50 dan ke-99 latensi untuk setiap layanan rpc, jalankan kueri berikut:

SELECT
  -- Compute 50th and 99th percentiles for each service
  STRING(attributes['rpc.service']) || '/' || STRING(attributes['rpc.method']) AS rpc_service_method,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(50)] AS duration_nano_p50,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(99)] AS duration_nano_p99
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE
  -- Matches spans whose kind field has a value of 2 (SPAN_KIND_SERVER).
  kind = 2
GROUP BY rpc_service_method

Untuk mengetahui informasi selengkapnya tentang enumerasi, lihat dokumentasi OpenTelemetry: SpanKind.

Untuk melihat hasil secara grafis, Anda dapat membuat diagram dengan dimensi yang ditetapkan ke rpc_service_method. Anda dapat menambahkan dua ukuran, satu untuk rata-rata nilai duration_nano_p50, dan yang lainnya untuk rata-rata kolom duration_nano_p99.

Memfilter entri log

Untuk menerapkan filter ke kueri, tambahkan klausa WHERE. Sintaksis yang Anda gunakan dalam klausa ini bergantung pada jenis data kolom. Bagian ini memberikan beberapa contoh untuk berbagai jenis data.

Memfilter entri log menurut jenis payload

Entri log dapat memiliki salah satu dari tiga jenis payload. Untuk memfilter entri log menurut jenis payload, gunakan salah satu klausa berikut:

  • Payload teks

    -- Matches log entries that have a text payload.
    WHERE text_payload IS NOT NULL
    
  • Payload JSON

    -- Matches log entries that have a JSON payload.
    WHERE json_payload IS NOT NULL
    
  • Payload proto

    -- Matches log entries that have a proto payload.
    -- Because proto_payload has a data type of RECORD, this statement tests
    -- whether a mandatory subfield exits.
    WHERE proto_payload.type IS NOT NULL
    

Dalam hasil kueri, kolom json_payload dan proto_payload dirender dalam JSON, yang dapat Anda jelajahi.

Memfilter data log menurut stempel waktu

Untuk memfilter entri log berdasarkan stempel waktunya, sebaiknya gunakan pemilih rentang waktu. Namun, Anda juga dapat menentukan timestamp dalam klausa WHERE:

-- Matches log entries whose timestamp is within the most recent hour
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

Untuk mengetahui informasi selengkapnya tentang cara memfilter menurut waktu, lihat Fungsi waktu dan Fungsi stempel waktu.

Filter menurut resource

Untuk memfilter data log dan rekaman aktivitas menurut resource, tambahkan pernyataan resource.type ke klausa WHERE:

-- Matches log entries whose resource type is gce_instance
WHERE resource.type = "gce_instance"

Filter menurut tingkat keparahan

Untuk memfilter data log menurut tingkat keseriusan, tambahkan pernyataan severity ke klausa WHERE:

-- Matches log entries whose severity is INFO or ERROR
WHERE severity IS NOT NULL AND severity IN ('INFO', 'ERROR')

Anda juga dapat memfilter entri log menurut severity_number, yang merupakan bilangan bulat. Misalnya, klausa berikut cocok dengan semua entri log yang tingkat keparahannya setidaknya NOTICE:

-- Matches log entries whose severity level is at least NOTICE
WHERE severity_number IS NOT NULL AND severity_number > 200

Untuk mengetahui informasi tentang nilai yang di-enumerasi, lihat LogSeverity.

Memfilter menurut nama log

Untuk memfilter data log menurut nama log, tambahkan pernyataan log_name atau log_id ke klausa WHERE:

  • Nama log menentukan jalur resource:

    -- Matches log entries that have the following log ID.
    WHERE log_name="projects/cloud-logs-test-project/logs/cloudaudit.googleapis.com%2Factivity"
    
  • ID log tidak menyertakan jalur resource:

    -- Matches log entries that have the following log id.
    WHERE log_id = "cloudaudit.googleapis.com/data_access"
    

Memfilter entri log menurut label resource

Label resource disimpan sebagai struktur JSON. Untuk memfilter menurut nilai kolom dalam struktur JSON, gunakan fungsi JSON_VALUE:

SELECT
  timestamp, JSON_VALUE(resource.labels.zone) AS zone, json_payload, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries whose resource type is gce_instance and whose zone is
  -- us-central1-f. Because resource has data type JSON, you must use JSON_VALUE
  -- to get the value for subfields, like zone.
  resource.type = "gce_instance" AND
  JSON_VALUE(resource.labels.zone) = "us-central1-f"
ORDER BY timestamp ASC

Kueri sebelumnya mengandalkan format label resource, karena label tersebut disimpan dalam entri log. Berikut adalah contoh kolom resource:

{
   type: "gce_instance"
   labels: {
      instance_id: "1234512345123451"
      project_id: "my-project"
      zone: "us-central1-f"
   }
}

Untuk mengetahui informasi tentang semua fungsi yang dapat mengambil dan mengubah data JSON, lihat Fungsi JSON.

Memfilter menurut permintaan HTTP

Untuk hanya membuat kueri entri log yang memiliki kolom permintaan HTTP, gunakan klausa berikut:

-- Matches log entries that have a HTTP request_method field.
-- Don't compare http_request to NULL. This field has a data type of RECORD.
WHERE http_request.request_method IS NOT NULL

Anda juga dapat menggunakan pernyataan IN:

-- Matches log entries whose HTTP request_method is GET or POST.
WHERE http_request.request_method IN ('GET', 'POST')

Memfilter menurut status HTTP

Untuk hanya membuat kueri entri log yang memiliki status HTTP, gunakan klausa berikut:

-- Matches log entries that have an http_request.status field.
WHERE http_request.status IS NOT NULL

Memfilter menurut kolom dalam jenis data JSON

Untuk membuat kueri entri log hanya saat subkolom dari kolom dengan jenis data JSON memiliki nilai tertentu, ekstrak nilai menggunakan fungsi JSON_VALUE:

-- Compare the value of the status field to NULL.
WHERE JSON_VALUE(json_payload.status) IS NOT NULL

Klausa sebelumnya sedikit berbeda dengan klausa berikut:

-- Compare the status field to NULL.
WHERE json_payload.status IS NOT NULL

Klausul pertama menguji apakah nilai kolom status adalah NULL. Klausul kedua menguji apakah kolom status ada. Misalkan tampilan log berisi dua entri log. Untuk satu entri log, kolom json_payload memiliki bentuk berikut:

{
    status: {
        measureTime: "1661517845"
    }
}

Untuk entri log lainnya, kolom json_payload memiliki struktur yang berbeda:

{
    @type: "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished"
    jobName: "projects/my-project/locations/us-central1/jobs/test1"
    relativeUrl: "/food=cake"
    status: "NOT_FOUND"
    targetType: "APP_ENGINE_HTTP"
}

Klausul WHERE json_payload.status IS NOT NULL cocok dengan kedua entri log. Namun, klausa WHERE JSON_VALUE(json_payload.status) IS NOT NULL hanya cocok dengan entri log kedua.

Memfilter entri rekaman aktivitas

Untuk menerapkan filter ke kueri, tambahkan klausa WHERE. Sintaksis yang Anda gunakan dalam klausa ini bergantung pada jenis data kolom. Bagian ini memberikan beberapa contoh untuk berbagai jenis data.

Memfilter menurut jenis data string

Kolom name disimpan sebagai String.

  • Untuk menganalisis hanya rentang yang menentukan name, gunakan klausa berikut:

    -- Matches spans that have a name field.
    WHERE name IS NOT NULL
    
  • Untuk menganalisis hanya rentang yang memiliki nilai "POST" untuk name, gunakan klausa berikut:

    -- Matches spans whose name is POST.
    WHERE STRPOS(name, "POST") > 0
    
  • Untuk menganalisis hanya rentang yang name berisi nilai "POST", gunakan operator LIKE bersama dengan karakter pengganti:

    -- Matches spans whose name contains POST.
    WHERE name LIKE "%POST%"
    

Memfilter menurut jenis data bilangan bulat

Kolom kind adalah bilangan bulat, yang dapat mengambil nilai antara nol dan lima:

  • Untuk menganalisis hanya rentang yang menentukan kind, gunakan klausa berikut:

    -- Matches spans that have field named kind.
    WHERE kind IS NOT NULL
    
  • Untuk menganalisis rentang yang nilai kind-nya adalah satu atau dua, gunakan klausa berikut:

    -- Matches spans whose kind value is 1 or 2.
    WHERE kind IN (1, 2)
    

Memfilter menurut jenis data RECORD

Beberapa kolom dalam skema rekaman aktivitas memiliki jenis data RECORD. Kolom ini dapat menyimpan satu atau beberapa struktur data, atau menyimpan entri berulang dari struktur data yang sama.

Memfilter menurut status atau kode status

Kolom status adalah contoh kolom yang jenis datanya adalah RECORD. Kolom ini menyimpan satu struktur data, dengan anggota yang diberi label code dan message.

  • Untuk menganalisis rentang hanya saat kolom status.code memiliki nilai 1, tambahkan klausa berikut:

    -- Matches spans that have a status.code field that has a value of 1.
    WHERE status.code = 1
    

    Kolom status.code disimpan sebagai bilangan bulat.

  • Untuk menganalisis rentang tempat kolom status bukan EMPTY, tambahkan klausa berikut:

    -- Matches spans that have status field. When the status field exists, it
    -- must contain a subfield named code.
    -- Don't compare status to NULL, because this field has a data type of RECORD.
    WHERE status.code IS NOT NULL
    

Kolom events dan links disimpan dengan jenis data RECORD, tetapi ini adalah kolom berulang.

  • Untuk mencocokkan rentang yang memiliki minimal satu peristiwa, gunakan klausa berikut:

    -- Matches spans that have at least one event. Don't compare events to NULL.
    -- The events field has data type of RECORD and contains a repeated fields.
    WHERE ARRAY_LENGTH(events) > 0
    
  • Untuk mencocokkan rentang yang memiliki peristiwa yang kolom name-nya memiliki nilai message, gunakan klausa berikut:

    WHERE
      -- Exists is true when any event in the array has a name field with the
      -- value of message.
      EXISTS(
        SELECT 1
        FROM UNNEST(events) AS ev
        WHERE ev.name = 'message'
      )
    

Memfilter menurut jenis data JSON

Kolom attributes berjenis JSON. Setiap atribut individual adalah pasangan nilai kunci.

  • Untuk menganalisis hanya rentang yang menentukan attributes, gunakan klausa berikut:

    -- Matches spans where at least one attribute is specified.
    WHERE attributes IS NOT NULL
    
  • Untuk menganalisis hanya rentang yang memiliki kunci atribut bernama component dengan nilai "proxy", gunakan klausa berikut:

    -- Matches spans that have an attribute named component with a value of proxy.
    WHERE attributes IS NOT NULL
          AND JSON_VALUE(attributes, '$.component') = 'proxy'
    

    Anda juga dapat menggunakan pernyataan LIKE bersama dengan karakter pengganti untuk melakukan pengujian berisi:

    -- Matches spans that have an attribute named component whose value contains proxy.
    WHERE attributes IS NOT NULL
          AND JSON_VALUE(attributes, '$.component') LIKE '%proxy%'
    

Mengelompokkan dan menggabungkan entri log

Bagian ini dibuat berdasarkan contoh sebelumnya dan menggambarkan cara Anda dapat mengelompokkan dan menggabungkan entri log. Jika Anda tidak menentukan pengelompokan, tetapi menentukan agregasi, satu hasil akan dicetak karena SQL memperlakukan semua baris yang memenuhi klausul WHERE sebagai satu grup.

Setiap ekspresi SELECT harus disertakan dalam kolom grup atau diagregasi.

Mengelompokkan entri log menurut stempel waktu

Untuk mengelompokkan data menurut stempel waktu, gunakan fungsi TIMESTAMP_TRUNC, yang memangkas stempel waktu ke perincian tertentu seperti HOUR:

SELECT
  -- Truncate the timestamp by hour.
  TIMESTAMP_TRUNC(timestamp, HOUR) AS hour,
  JSON_VALUE(json_payload.status) AS status,
  -- Count the number log entries in each group.
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries that have a status field whose value isn't NULL.
  json_payload IS NOT NULL AND JSON_VALUE(json_payload.status) IS NOT NULL
GROUP BY
  -- Group by hour and status
  hour,status
ORDER BY hour ASC

Untuk mengetahui informasi selengkapnya, lihat dokumentasi TIMESTAMP_TRUNC dan Fungsi tanggal waktu.

Mengelompokkan entri log menurut resource

Kueri berikut menunjukkan cara mengelompokkan entri log menurut jenis resource, lalu menghitung jumlah entri log di setiap grup:

SELECT
   -- Count the number of log entries for each resource type
   resource.type, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
GROUP BY resource.type
LIMIT 100

Mengelompokkan entri log menurut tingkat keparahan

Kueri berikut menunjukkan cara mengelompokkan entri log berdasarkan tingkat keparahan, lalu menghitung jumlah entri log di setiap grup:

SELECT
  -- Count the number of log entries for each severity.
  severity, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  severity IS NOT NULL
GROUP BY severity
ORDER BY severity
LIMIT 100

Mengelompokkan entri log menurut log_id

Kueri berikut menunjukkan cara mengelompokkan entri log menurut ID log, lalu menghitung jumlah entri log di setiap grup:

SELECT
  -- Count the number of log entries for each log ID.
  log_id, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
GROUP BY log_id
ORDER BY count DESC
LIMIT 100

Menghitung latensi rata-rata permintaan HTTP per URL

Kueri berikut menggambarkan cara mengelompokkan entri log menurut URL permintaan HTTP dan lokasi, lalu menghitung jumlah entri log di setiap grup:

SELECT
  -- Compute the average latency for each group. Because the labels field has a
  -- data type of JSON, use JSON_VALUE to get the value of checker_location.
  JSON_VALUE(labels.checker_location) AS location,
  AVG(http_request.latency.seconds) AS secs, http_request.request_url
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries when the request_method field is GET.
  http_request IS NOT NULL AND http_request.request_method IN ('GET')
GROUP BY
  -- Group by request URL and location
  http_request.request_url, location
ORDER BY location
LIMIT 100

Menghitung rata-rata byte yang dikirim untuk pengujian subnetwork

Kueri berikut menunjukkan cara mengelompokkan entri log menurut lokasi yang ditentukan dalam label resource, lalu menghitung jumlah entri log di setiap grup:

SELECT
  -- Compute the average number of bytes sent per location. Because labels has
  -- a data type of JSON, use JSON_VALUE to get the value of the location field.
  -- bytes_sent is a string. Must cast to a FLOAT64 before computing average.
  JSON_VALUE(resource.labels.location) AS location,
  AVG(CAST(JSON_VALUE(json_payload.bytes_sent) AS FLOAT64)) AS bytes
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  resource.type = "gce_subnetwork" AND json_payload IS NOT NULL
GROUP BY
  -- Group by location
  location
LIMIT 100

Untuk mengetahui informasi selengkapnya, lihat Fungsi JSON dan Fungsi konversi.

Menghitung entri log dengan kolom yang cocok dengan pola

Untuk menampilkan substring yang cocok dengan ekspresi reguler, gunakan fungsi REGEXP_EXTRACT:

SELECT
  -- Extract the value that begins with test.
  -- Count the number of log entries for each name.
  REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  json_payload.jobName IS NOT NULL
GROUP BY name
ORDER BY count
LIMIT 20

Untuk contoh tambahan, lihat dokumentasi REGEXP_EXTRACT.

Mengelompokkan dan menggabungkan data rekaman aktivitas

Bagian ini menggambarkan cara Anda dapat mengelompokkan dan menggabungkan rentang. Jika Anda tidak menentukan pengelompokan, tetapi menentukan agregasi, satu hasil akan dicetak karena SQL memperlakukan semua entri yang memenuhi klausa WHERE sebagai satu grup.

Setiap ekspresi SELECT harus disertakan dalam kolom grup atau diagregasi.

Mengelompokkan rentang menurut waktu mulai

Untuk mengelompokkan data menurut waktu mulai, gunakan fungsi TIMESTAMP_TRUNC, yang memangkas stempel waktu ke perincian tertentu seperti HOUR:

SELECT
  -- Truncate the start time to the hour. Count the number of spans per group.
  TIMESTAMP_TRUNC(start_time, HOUR) AS hour,
  status.code AS code,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE
  -- Matches spans shows start time is within the previous 12 hours.
  start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 HOUR)
GROUP BY
  -- Group by hour and status code.
  hour, code
ORDER BY hour DESC

Untuk mengetahui informasi selengkapnya, lihat dokumentasi TIMESTAMP_TRUNC dan Fungsi tanggal waktu.

Menghitung rentang menurut kode status

Untuk menampilkan jumlah rentang dengan kode status tertentu, jalankan kueri berikut:

SELECT
  -- Count the number of spans for each status code.
  status.code,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE status.code IS NOT NULL
GROUP BY status.code

Jika Anda mengganti status.code dengan kind, kueri sebelumnya akan melaporkan jumlah rentang untuk setiap nilai enumerasi kind. Demikian pula, jika Anda mengganti status.code dengan name, hasil kueri akan mencantumkan jumlah entri untuk setiap nama rentang.

Menghitung durasi rata-rata semua rentang

Untuk menampilkan durasi rata-rata, setelah mengelompokkan data rentang menurut nama rentang, jalankan kueri berikut:

SELECT
  -- Group by name, and then compute the average duration for each group.
  name,
  AVG(duration_nano) AS nanosecs,
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
GROUP BY name
ORDER BY nanosecs DESC

Menghitung durasi rata-rata dan persentil per nama layanan

Kueri berikut menghitung jumlah rentang dan berbagai statistik untuk setiap layanan:

SELECT
  -- Set the service name by the first non-null value.
  COALESCE(
    JSON_VALUE(resource.attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."g.co/gae/app/module"')) AS service_name,

  -- Count the number spans for each service name. Also compute statistics.
  COUNT(*) AS span_count,
  AVG(duration_nano) AS avg_duration_nano,
  MIN(duration_nano) AS min_duration_nano,
  MAX(duration_nano) AS max_duration_nano,

  -- Calculate percentiles for duration
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(50)] AS p50_duration_nano,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(95)] AS p95_duration_nano,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(99)] AS p99_duration_nano,

  -- Count the number of unique trace IDs. Also, collect up to 5 unique
  -- span names and status codes.
  COUNT(DISTINCT trace_id) AS distinct_trace_count,
  ARRAY_AGG(DISTINCT name IGNORE NULLS LIMIT 5) AS sample_span_names,
  ARRAY_AGG(DISTINCT status.code IGNORE NULLS LIMIT 5) AS sample_status_codes
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
GROUP BY service_name
ORDER BY span_count DESC

Bagian ini menjelaskan dua pendekatan yang dapat Anda gunakan untuk menelusuri beberapa kolom tampilan yang Anda kueri:

  • Penelusuran berbasis token: Anda menentukan lokasi penelusuran, kueri penelusuran, lalu menggunakan fungsi SEARCH. Karena fungsi SEARCH memiliki aturan khusus tentang cara data ditelusuri, sebaiknya Anda membaca dokumentasi SEARCH.

  • Penelusuran berbasis substring: Anda memberikan lokasi penelusuran, string literal, lalu menggunakan fungsi CONTAINS_SUBSTR. Sistem melakukan pengujian yang tidak peka huruf besar/kecil untuk menentukan apakah literal string ada dalam ekspresi. Fungsi CONTAINS_SUBSTR menampilkan TRUE jika literal string ada dan FALSE jika tidak. Nilai penelusuran harus berupa literal STRING, tetapi bukan literal NULL.

Kueri berikut hanya mempertahankan baris yang memiliki kolom yang sama persis dengan "35.193.12.15":

SELECT
  timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID` AS t
WHERE
  -- Search data access audit logs for the IP address that matches 35.193.12.15.
  -- The use of backticks prevents the string from being tokenized.
  proto_payload IS NOT NULL AND
  log_id = "cloudaudit.googleapis.com/data_access" AND
  SEARCH(t,"`35.193.12.15`")
ORDER BY timestamp ASC
LIMIT 20

Jika tanda petik terbalik tidak ada dalam string kueri, string kueri akan dibagi berdasarkan aturan yang ditentukan dalam dokumentasi SEARCH. Misalnya, saat pernyataan berikut dijalankan, string kueri dibagi menjadi empat token: "35", "193", "12", dan "15":

  SEARCH(t,"35.193.12.15")

Pernyataan SEARCH sebelumnya mencocokkan baris saat satu kolom mencocokkan keempat token. Urutan token tidak menjadi masalah.

Anda dapat menyertakan beberapa pernyataan SEARCH dalam kueri. Misalnya, dalam kueri sebelumnya, Anda dapat mengganti filter pada ID log dengan pernyataan seperti berikut:

  SEARCH(t,"`cloudaudit.googleapis.com/data_access`")

Pernyataan sebelumnya menelusuri setiap kolom entri log di tampilan log, sedangkan pernyataan asli hanya menelusuri kolom log_id entri log.

Untuk melakukan beberapa penelusuran di beberapa kolom, pisahkan setiap string dengan spasi. Misalnya, pernyataan berikut cocok dengan baris tempat kolom berisi "Hello World", "happy", dan "days":

  SEARCH(t,"`Hello World` happy days")

Terakhir, Anda dapat menelusuri kolom tertentu, bukan menelusuri seluruh tabel. Misalnya, pernyataan berikut hanya menelusuri kolom bernama text_payload dan json_payload:

   SEARCH((text_payload, json_payload) ,"`35.222.132.245`")

Untuk mengetahui informasi tentang cara memproses parameter fungsi SEARCH, lihat halaman referensi BigQuery Fungsi penelusuran.

Misalnya, kueri berikut mengambil semua entri log audit Akses Data dengan alamat IP tertentu yang stempel waktunya berada dalam rentang waktu tertentu. Terakhir, kueri mengurutkan hasil, lalu menampilkan 20 hasil terlama:

SELECT
  timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID` AS t
WHERE
  -- Search data access audit logs for the IP address that matches 35.193.12.15.
  -- CONTAINS_SUBSTR performs a contains-test.
  proto_payload IS NOT NULL AND
  log_id = "cloudaudit.googleapis.com/data_access" AND
  CONTAINS_SUBSTR(t,"35.193.12.15")
ORDER BY timestamp ASC
LIMIT 20

Membuat kueri beberapa tampilan

Pernyataan kueri memindai satu atau beberapa tabel atau ekspresi dan menampilkan baris hasil yang dihitung. Misalnya, Anda dapat menggunakan pernyataan kueri untuk menggabungkan hasil pernyataan SELECT pada tabel atau set data yang berbeda dengan berbagai cara, lalu memilih kolom dari data gabungan.

Untuk menggabungkan tampilan, batasan berikut berlaku:

  1. Lokasi tampilan memenuhi salah satu hal berikut:

    • Semua tampilan memiliki lokasi yang sama.
    • Semua tampilan berada di lokasi global atau us.
  2. Saat resource penyimpanan menggunakan kunci enkripsi yang dikelola pelanggan (CMEK), salah satu hal berikut akan berlaku:

    • Resource penyimpanan yang menggunakan CMEK menggunakan kunci Cloud KMS yang sama.
    • Resource penyimpanan yang menggunakan CMEK memiliki ancestor umum, dan ancestor tersebut menentukan kunci Cloud KMS default yang berada di lokasi yang sama dengan resource penyimpanan.

    Jika satu atau beberapa resource penyimpanan menggunakan CMEK, sistem akan mengenkripsi data sementara yang dihasilkan oleh gabungan dengan kunci Cloud KMS umum atau kunci Cloud KMS default ancestor.

Misalnya, Anda memiliki dua tampilan yang berada di lokasi yang sama. Kemudian, Anda dapat menggabungkan tampilan ini jika salah satu kondisi berikut berlaku:

  • Resource penyimpanan tidak menggunakan CMEK.
  • Satu resource penyimpanan menggunakan CMEK dan yang lainnya tidak.
  • Kedua resource penyimpanan menggunakan CMEK dan keduanya menggunakan kunci Cloud KMS yang sama.
  • Kedua resource penyimpanan menggunakan CMEK, tetapi menggunakan kunci yang berbeda. Namun, resource tersebut berbagi ancestor yang menentukan kunci Cloud KMS default yang berada di lokasi yang sama dengan resource penyimpanan.

    Misalnya, anggaplah hierarki resource untuk bucket log dan bucket pengamatan mencakup organisasi yang sama. Anda dapat menggabungkan tampilan di bucket tersebut jika, untuk organisasi tersebut, Anda telah mengonfigurasi setelan resource default untuk Cloud Logging dan untuk bucket kemampuan pengamatan dengan kunci Cloud KMS default yang sama untuk lokasi penyimpanan.

Menggabungkan dua tampilan log berdasarkan ID aktivitas

Untuk menggabungkan informasi dari dua tabel, gunakan salah satu operator join:

SELECT
  -- Do an inner join on two tables by using the span ID and trace ID.
  -- Don't join only by span ID, as this field isn't globally unique.
  -- From the first view, show the timestamp, severity, and JSON payload.
  -- From the second view, show the JSON payload.
  a.timestamp, a.severity, a.json_payload, b.json_payload, a.span_id, a.trace
FROM  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_1` a
JOIN  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_2` b
ON
  a.span_id = b.span_id AND
  a.trace = b.trace
LIMIT 100

Membuat kueri dua tampilan log dengan pernyataan gabungan

Untuk menggabungkan hasil dari dua pernyataan SELECT atau lebih dan menghapus baris duplikat, gunakan operator UNION. Untuk mempertahankan baris duplikat, gunakan operator UNION ALL:

SELECT
  timestamp, log_name, severity, json_payload, resource, labels
-- Create a union of two log views
FROM(
  SELECT * FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_1`
  UNION ALL
  SELECT * FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_2`
)
-- Sort the union by timestamp.
ORDER BY timestamp ASC
LIMIT 100

Gabungkan data log dan rekaman aktivitas menggunakan ID rekaman aktivitas

Kueri berikut menggabungkan data log dan rekaman aktivitas menggunakan ID rentang dan rekaman aktivitas:

SELECT
  T.trace_id,
  T.span_id,
  T.name,
  T.start_time,
  T.duration_nano,
  L.log_name,
  L.severity,
  L.json_payload
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans` AS T
JOIN
  `PROJECT_ID.LOCATION._Default._AllLogs` AS L
ON
  -- Join log and trace data by both the span ID and trace ID.
  -- Don't join only on span ID, this field isn't globally unique.
  T.span_id = L.span_id
  -- A regular expression is required because the storage format of the trace ID
  -- differs between a log view and a trace view.
  AND T.trace_id = REGEXP_EXTRACT(L.trace, r'/([^/]+)$')
WHERE T.duration_nano > 1000000
LIMIT 10

Respons kueri mencantumkan ID rekaman aktivitas dan rentang, yang memungkinkan Anda membuat kueri untuk masing-masing ID guna mengumpulkan informasi lebih lanjut. Selain itu, hasil mencantumkan tingkat keparahan entri log dan payload JSON.

Menghapus entri log duplikat

Log Analytics tidak menghapus entri log duplikat sebelum kueri dijalankan. Perilaku ini berbeda dengan saat Anda mengkueri entri log menggunakan Logs Explorer, yang menghapus entri duplikat dengan membandingkan nama log, stempel waktu, dan kolom ID penyisipan.

Anda dapat menggunakan validasi tingkat baris untuk menghapus entri log duplikat.

Untuk mengetahui informasi selengkapnya, lihat Pemecahan masalah: Ada entri log duplikat dalam hasil Log Analytics saya.

Langkah berikutnya

Untuk dokumentasi referensi SQL atau contoh lainnya, lihat dokumen berikut: