查看 Gemini for Google Cloud 日志

本文档介绍了如何启用 Gemini for Google Cloud 活动的收集和存储,包括:

  • Gemini for Google Cloud 提示和回答日志,例如用户输入、上下文信息和回答。
  • Gemini for Google Cloud 元数据日志,例如用户接受的遥测元数据和代码行。

如果您需要生成 Gemini Code Assist 指标,请参阅监控 Gemini for Google Cloud 使用情况

Gemini for Google Cloud 不会收集或向 Cloud Logging 发送用户与 Gemini for Google Cloud的任何其他互动,包括书面反馈。收集的数据会发送到 Cloud Logging 进行存储。您可以通过搜索资源类型为 cloudaicompanion.googleapis.com/Instance 的日志条目来查看这些数据。

此功能不会在 Gemini in Vertex AI 中记录提示或回答。如需为 Gemini in Vertex AI 启用日志,请参阅启用数据访问审核日志

Identity and Access Management (IAM) 角色控制主账号访问日志的权限。您可以向主账号授予预定义角色,也可以创建自定义角色。如需详细了解所需权限,请参阅访问权限控制

默认情况下,Cloud Logging 会对以静态方式存储的客户内容进行加密。Logging 存储在日志存储桶中的数据使用密钥加密密钥进行加密,此过程称为信封加密。访问日志记录数据需要访问这些密钥加密密钥,Google 会为您管理这些密钥,您无需执行任何操作。

您的组织可能具有我们的默认静态加密不提供的监管、合规性相关或高级加密要求。为满足贵组织的要求,您可以自行管理用于保护您数据的加密密钥,而不是由 Google 代为管理。

如需详细了解客户管理的加密密钥 (CMEK) 的使用情况(包括优点和限制),请参阅客户管理的加密密钥

限制

Google Cloud 中的 Gemini 日志数据记录仅限于用户在 IDE 中与 Gemini Code Assist 的互动。

准备工作

查看 Gemini for Google Cloud 用户日志和元数据日志

如需查看 Gemini for Google Cloud 用户日志和元数据日志,请执行以下操作之一:

控制台

  1. 在 Google Cloud 控制台中,转到 Logs Explorer 页面:

    前往 Logs Explorer

    如果您使用搜索栏查找此页面,请选择子标题为 Logging 的结果。

  2. 在工具栏中,选择一个 Google Cloud 控制台项目。
  3. 在工具栏中,展开所有资源菜单,然后选择资源 Cloud AI Companion 实例

gcloud

运行以下命令:

gcloud logging read "resource.type=cloudaicompanion.googleapis.com/Instance" --project PROJECT_ID  --limit 3

PROJECT_ID 替换为您要查看其 Gemini for Google Cloud 日志的项目的 ID。

API

  1. 创建一个包含以下信息的 JSON 文件:

      {
        "resourceNames": [
          "projects/PROJECT_ID"
        ],
        "pageSize": 5,
        "filter": "resource.type: cloudaicompanion.googleapis.com/Instance"
      }
    

    PROJECT_ID 替换为您要查看其 Gemini for Google Cloud 日志的项目的 ID。

  2. 获取身份验证令牌

    TOKEN=$(gcloud auth print-access-token)
    
  3. 使用 cURL 调用 entries.list 方法

    curl -X POST --data-binary @JSON_FILE_NAME \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      "https://logging.googleapis.com/v2/entries:list"

    JSON_FILE_NAME 替换为您在上一步中创建的 JSON 文件的路径。

    如需详细了解身份验证,请参阅使用 REST 时进行身份验证

    响应会返回一组日志条目。

Gemini for Google Cloud 日志

LogEntry 是 Cloud Logging 中的数据基本单位。以下部分列出了 LogEntry 中针对 Gemini for Google Cloud Platform 事件(例如用户请求数量Gemini for Google Cloud 回答)的字段。

用户请求数量

下表列出了用户请求日志条目中找到的字段:

字段 值和备注
LogEntry.resource.type Gemini for Google Cloud 资源类型cloudaicompanion.googleapis.com/Instance
LogEntry.resource.labels.resource_container 使用 Gemini for Google Cloud 的资源容器的唯一 ID。
LogEntry.resource.labels.location 使用 Gemini for Google Cloud 的位置。
LogEntry.resource.labels.instance_id 使用了 Gemini for Google Cloud 的资源的唯一 ID。
LogEntry.labels.method 可以是以下任一项,具体取决于调用 logEntry 的对象:

CompleteTask:例如,来自 Gemini Code Assist 或其他 Gemini for Google Cloud 服务的对话请求。

GenerateCode:例如,生成代码的请求,例如 Gemini Code Assist 中的代码转换请求。

CompleteCode:例如,在 IDE 中工作时补全代码的请求,例如 Gemini Code Assist 中的内嵌建议
LogEntry.labels.product Gemini for Google Cloud 服务名称。如果 Gemini for Google Cloud 产品为 Gemini Code Assist,则此值为 code_assist。如果 Gemini for Google Cloud 产品为 Gemini Cloud Assist,则此值为 cloud_assist。否则,此值为 unknown
LogEntry.labels.request_id 用于将请求与回答日志条目相关联的唯一标识符。
LogEntry.labels.user_id 发出此请求的用户的标识符。
LogEntry.jsonPayload 日志条目的载荷。
LogEntry.logName 标识日志。

以下示例展示了对话提示事件的示例日志条目:

{
  "insertId": "654581e30003b19e340bbd96",
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
        instance_id: "default"
        location: "global"
        resource_container: "my-project-id"
     }
  },
  "timestamp": "2023-11-03T23:27:31.242078Z",
  "labels": {
    "product": "code_assist",
    "request_id": "4ea1e265-ea5d-4d11-b3c8-39bad9c96326"
    "user_id": "user@company.com"
  },
  "jsonPayload" : {
    @type: "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.RequestLog"
    "taskCompletionRequest":
      input: {
        messages: [{
          author: "USER"
          content: "What are some best practices to save cost on my Google Cloud bill?"
        }]
        preamble: ""
      }
  }
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Frequest",
  "receiveTimestamp": "2023-11-03T23:27:31.255648319Z"
  "severity": "INFO"
}

以下示例展示了自动内嵌代码建议提示和在代码文件中提示 Gemini for Google Cloud RequestLog 条目示例。

内嵌代码建议的提示数据使用 codeCompletionRequest 对象(如以下示例所示),而手动触发的生成使用 codeGenerationRequest

{
  "insertId": "654581e30003b19e340bbd96",
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
        instance_id: "default"
        location: "global"
        resource_container: "my-project-id"
     }
  },
  "timestamp": "2023-11-03T23:27:31.242078Z",
  "labels": {
    "product": "code_assist",
    "request_id": "4ea1e265-ea5d-4d11-b3c8-39bad9c96326"
    "user_id": "user@company.com"
  },
  "jsonPayload" : {
    @type: "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.RequestLog"
    "codeCompletionRequest": {
      "input_data_context": {
        "additional_context": {
          "files": [
            {
              "language": "go",
              "path": "{/path/to/../current-file.go",
              "segments": [
                {
                  "content": "...Prefix Text..."
                },
                {
                  "content": "...Suffix Text..."
                }
              ],
              "state": ["EDITED"]
            },
            {
              "language": "go",
              "path": "/path/to/../recent-file.go",
              "segments": [
                {
                  "content": "...File Text..."
                }
              ],
              "state": ["RECENTLY_OPENED"]
            }
          ]
        }
      }
    }
  }
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Frequest",
  "receiveTimestamp": "2023-11-03T23:27:31.255648319Z"
  "severity": "INFO"
}

代理互动日志

与 Gemini 的某些互动可能会针对单个用户操作生成多个日志条目(请求、响应和元数据)。此类互动的示例包括:

  • 代理执行涉及工具使用的任务(例如,模型调用 read_filereplace 等内部函数,如日志示例所示)。
  • 一个代理与其他代理互动。
请求日志条目

以下示例展示了发起代理互动的请求的示例日志条目:

{
  "insertId": "qe9xxub2r",
  "jsonPayload": {
    "taskCompletionRequest": {
      "input": {
        "messages": [
          {
            "author": "USER",
            "content": "hi can you add one test here\nCurrent File Path:\n```cpp\n/usr/local/google/home/pdec/test.cpp\n```\n\n"
          }
        ],
        "preamble": ""
      }
    },
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.RequestLog"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "resource_container": "my-project-id",
      "instance_id": "default",
      "location": "global"
    }
  },
  "timestamp": "2025-10-08T10:09:52.225165428Z",
  "severity": "INFO",
  "labels": {
    "request_id": "e60facb1485b17b7",
    "client_version": "unknown",
    "product": "code_assist",
    "method": "CompleteTask",
    "user_id": "user@company.com",
    "client_name": "cloudcode_cli"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Frequest",
  "receiveTimestamp": "2025-10-08T10:09:52.581787548Z"
}
响应日志条目

以下示例展示了包含多条消息的代理互动中的示例响应日志条目:

{
  "insertId": "qe9xxub2t",
  "jsonPayload": {
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.ResponseLog",
    "taskCompletionResponse": {
      "output": {
        "messages": [
          {
            "content": "**Reading File Contents**\n\nI'm currently focused on reading the contents of `/usr/local/google/home/pdec/test.cpp`. This will inform what kind of test needs to be written and how it should be structured.\n\n\n",
            "author": "MODEL"
          },
          {
            "author": "MODEL",
            "content": "**File Inspection Begins**\n\nI've initiated the process of reading the test file. My immediate goal is to grasp its existing structure and identify the testing framework, if one exists. This will directly influence the design of the new test case I'll be adding.\n\n\n"
          },
          {
            "author": "MODEL",
            "content": "Of course. What is the test about? I'll read the file to understand the context."
          },
          {
            "content": "read_file({\"absolute_path\":\"/usr/local/google/home/pdec/test.cpp\"})",
            "author": "MODEL"
          }
        ]
      }
    }
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "resource_container": "my-project-id",
      "instance_id": "default",
      "location": "global"
    }
  },
  "timestamp": "2025-10-08T10:09:52.227354297Z",
  "severity": "INFO",
  "labels": {
    "product": "code_assist",
    "request_id": "e60facb1485b17b7",
    "user_id": "user@company.com",
    "client_version": "unknown",
    "method": "CompleteTask",
    "client_name": "cloudcode_cli"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fresponse",
  "receiveTimestamp": "2025-10-08T10:09:52.581787548Z"
}
元数据日志条目

以下示例展示了代理互动中的示例元数据日志条目:

{
  "insertId": "qe9xxub2s",
  "jsonPayload": {
    "apiRequest": {},
    "clientName": "cloudcode_cli",
    "requestId": "e60facb1485b17b7",
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog",
    "clientVersion": "unknown"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "location": "global",
      "instance_id": "default",
      "resource_container": "my-project-id"
    }
  },
  "timestamp": "2025-10-08T10:09:52.226420727Z",
  "severity": "INFO",
  "labels": {
    "method": "CompleteTask",
    "product": "code_assist",
    "user_id": "user@company.com"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata",
  "receiveTimestamp": "2025-10-08T10:09:52.581787548Z"
}

以下示例展示了代理互动的日志条目的另一个示例,其中包含请求 ID 4b66a582bad9cf2c

请求日志条目

{
  "insertId": "4qvt8nb2k",
  "jsonPayload": {
    "taskCompletionRequest": {
      "input": {
        "messages": [
          {
            "author": "USER",
            "content": "FunctionResponse{name: read_file, response: {\"output\":\"#include <iostream>\\n\\n// Function to calculate the greatest common divisor (GCD) of two numbers.\\nint gcd(int a, int b) {\\n    if (b == 0) {\\n        return a;\\n    }\\n    return gcd(b, a % b);\\n}\\n\\n// Function to calculate the least common multiple (LCM) of two numbers.\\nint lcm(int a, int b) {\\n    return (a * b) / gcd(a, b);\\n}\\n\\n// Function to check if a number is prime.\\nint is_prime(int a) {\\n    if (a < 2) {\\n        return 0;\\n    }\\n    for (int i = 2; i * i <= a; ++i) {\\n        if (a % i == 0) {\\n            return 0;\\n        }\\n    }\\n    return 1;\\n}\\n\\n// Function for extended Euclidean algorithm.\\nint extended_gcd(int a, int b, int &x, int &y) {\\n    if (b == 0) {\\n        x = 1;\\n        y = 0;\\n        return a;\\n    }\\n    int x1, y1;\\n    int d = extended_gcd(b, a % b, x1, y1);\\n    x = y1;\\n    y = x1 - (a / b) * y1;\\n    return d;\\n}\\n\\n// Test function\\nvoid run_tests() {\\n    // Test gcd\\n    if (gcd(10, 15) == 5) {\\n        std::cout << \\\"gcd(10, 15) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(10, 15) failed\\\" << std::endl;\\n    }\\n\\n    // Test lcm\\n    if (lcm(10, 15) == 30) {\\n        std::cout << \\\"lcm(10, 15) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"lcm(10, 15) failed\\\" << std::endl;\\n    }\\n\\n    // Test is_prime\\n    if (is_prime(7) == 1) {\\n        std::cout << \\\"is_prime(7) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(7) failed\\\" << std::endl;\\n    }\\n    if (is_prime(10) == 0) {\\n        std::cout << \\\"is_prime(10) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(10) failed\\\" << std::endl;\\n    }\\n\\n    // Test extended_gcd\\n    int x, y;\\n    int g = extended_gcd(35, 15, x, y);\\n    if (g == 5 && 35 * x + 15 * y == g) {\\n        std::cout << \\\"extended_gcd(35, 15) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"extended_gcd(35, 15) failed\\\" << std::endl;\\n    }\\n\\n    // Test is_prime with 1\\n    if (is_prime(1) == 0) {\\n        std::cout << \\\"is_prime(1) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(1) failed\\\" << std::endl;\\n    }\\n\\n    // Test is_prime with 9\\n    if (is_prime(9) == 0) {\\n        std::cout << \\\"is_prime(9) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(9) failed\\\" << std::endl;\\n    }\\n\\n    // Test is_prime with 13\\n    if (is_prime(13) == 1) {\\n        std::cout << \\\"is_prime(13) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(13) failed\\\" << std::endl;\\n    }\\n\\n    // Test lcm with 7 and 9\\n    if (lcm(7, 9) == 63) {\\n        std::cout << \\\"lcm(7, 9) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"lcm(7, 9) failed\\\" << std::endl;\\n    }\\n\\n    // Test gcd with 12 and 18\\n    if (gcd(12, 18) == 6) {\\n        std::cout << \\\"gcd(12, 18) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(12, 18) failed\\\" << std::endl;\\n    }\\n\\n    // Test gcd with two primes\\n    if (gcd(7, 13) == 1) {\\n        std::cout << \\\"gcd(7, 13) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(7, 13) failed\\\" << std::endl;\\n    }\\n\\n    // Test is_prime with 97\\n    if (is_prime(97) == 1) {\\n        std::cout << \\\"is_prime(97) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(97) failed\\\" << std::endl;\\n    }\\n\\n    // Test extended_gcd with 48 and 18\\n    int x2, y2;\\n    int g2 = extended_gcd(48, 18, x2, y2);\\n    if (g2 == 6 && 48 * x2 + 18 * y2 == g2) {\\n        std::cout << \\\"extended_gcd(48, 18) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"extended_gcd(48, 18) failed\\\" << std::endl;\\n    }\\n\\n    // Test gcd with 27 and 18\\n    if (gcd(27, 18) == 9) {\\n        std::cout << \\\"gcd(27, 18) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(27, 18) failed\\\" << std::endl;\\n    }\\n    // test 999 and 123\\n    if (gcd(999, 123) == 3) {\\n        std::cout << \\\"gcd(999, 123) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(999, 123) failed\\\" << std::endl;\\n    }\\n    \\n    \\n}\\n\\nint main() {\\n    run_tests();\\n    return 0;\\n}\"}}"
          }
        ],
        "preamble": ""
      }
    },
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.RequestLog"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "resource_container": "my-project-id",
      "instance_id": "default",
      "location": "global"
    }
  },
  "timestamp": "2025-10-08T10:10:03.457717366Z",
  "severity": "INFO",
  "labels": {
    "request_id": "4b66a582bad9cf2c",
    "method": "CompleteTask",
    "client_version": "unknown",
    "product": "code_assist",
    "client_name": "cloudcode_cli",
    "user_id": "user@company.com"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Frequest",
  "receiveTimestamp": "2025-10-08T10:10:03.606059154Z"
}

响应日志条目

{
  "insertId": "4qvt8nb2m",
  "jsonPayload": {
    "taskCompletionResponse": {
      "output": {
        "messages": [
          {
            "author": "MODEL",
            "content": "**Testing the functions**\\n\\nI'm focusing on adding a new test case to `test.cpp`.  The existing `run_tests` function is a great starting point. I'm considering which function to test further – maybe `extended_gcd`? I'll review the current tests for that function and then devise a new test scenario to add.\\n\\n\\n"
          },
          {
            "author": "MODEL",
            "content": "**Evaluating LCM Test**\\n\\nI've finalized the new test case for the `lcm` function within the `test.cpp` file.  I'm adding a test for `lcm(12, 18)` to confirm the result is 36. I plan to use the `replace` command to inject this new test directly before the closing brace of the `run_tests` function.  I've identified a unique line in `test.cpp` as the anchor for replacement.\\n\\n\\n"
          },
          {
            "author": "MODEL",
            "content": "**Inserting the new test**\\n\\nI've created a test case for `lcm(12, 18)`, confirming the expected result of 36. To implement this, I'm targeting the `run_tests` function.  I'll use the `replace` command and will search the end of the `run_tests` function to inject the new test, right before the closing brace.  I'm ready to implement this and confirm that it passes.\\n\\n\\n"
          },
          {
            "author": "MODEL",
            "content": "I've reviewed the file. I'll add a test case for the `lcm` function with inputs 12 and 18."
          },
          {
            "content": "replace({\"file_path\":\"/usr/local/google/home/pdec/test.cpp\",\"instruction\":\"add a test for the lcm function with 12 and 18\",\"new_string\":\"    // test 999 and 123\\n    if (gcd(999, 123) == 3) {\\n        std::cout << \\\"gcd(999, 123) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(999, 123) failed\\\" << std::endl;\\n    }\\n    \\n    // Test lcm with 12 and 18\\n    if (lcm(12, 18) == 36) {\\n        std::cout << \\\"lcm(12, 18) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"lcm(12, 18) failed\\\" << std::endl;\\n    }\\n    \\n}\",\"old_string\":\"    // test 999 and 123\\n    if (gcd(999, 123) == 3) {\\n        std::cout << \\\"gcd(999, 123) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(999, 123) failed\\\" << std::endl;\\n    }\\n    \\n    \\n}\"})",
            "author": "MODEL"
          }
        ]
      }
    },
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.ResponseLog"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "location": "global",
      "resource_container": "my-project-id",
      "instance_id": "default"
    }
  },
  "timestamp": "2025-10-08T10:10:03.461137399Z",
  "severity": "INFO",
  "labels": {
    "client_name": "cloudcode_cli",
    "client_version": "unknown",
    "method": "CompleteTask",
    "request_id": "4b66a582bad9cf2c",
    "product": "code_assist",
    "user_id": "user@company.com"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fresponse",
  "receiveTimestamp": "2025-10-08T10:10:03.606059154Z"
}

元数据日志条目

{
  "insertId": "4qvt8nb2l",
  "jsonPayload": {
    "clientVersion": "unknown",
    "apiRequest": {},
    "clientName": "cloudcode_cli",
    "requestId": "4b66a582bad9cf2c",
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "resource_container": "my-project-id",
      "location": "global",
      "instance_id": "default"
    }
  },
  "timestamp": "2025-10-08T10:10:03.459902984Z",
  "severity": "INFO",
  "labels": {
    "product": "code_assist",
    "user_id": "user@company.com",
    "method": "CompleteTask"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata",
  "receiveTimestamp": "2025-10-08T10:10:03.606059154Z"
}

Gemini for Google Cloud 回答

下表展示了 Gemini for Google Cloud 回答字段和说明:

字段 值和备注
LogEntry.resource.type Gemini for Google Cloud 资源类型cloudaicompanion.googleapis.com/Instance
LogEntry.resource.labels.resource_container 使用 Gemini for Google Cloud 的资源容器的唯一 ID。
LogEntry.resource.labels.location 使用 Gemini for Google Cloud 的位置。
LogEntry.resource.labels.instance_id 使用了 Gemini for Google Cloud 的资源的唯一 ID。
LogEntry.labels.method 可以是以下任一项,具体取决于调用 logEntry 的对象:

CompleteTask:例如,来自 Gemini Code Assist 或其他 Gemini for Google Cloud 服务的对话请求。

GenerateCode:例如,生成代码的请求,例如 Gemini Code Assist 中的代码转换请求。

CompleteCode:例如,在 IDE 中工作时补全代码的请求,例如 Gemini Code Assist 中的内嵌建议
LogEntry.labels.product Gemini for Google Cloud 服务名称。如果 Gemini for Google Cloud 产品为 Gemini Code Assist,则此值为 code_assist。如果 Gemini for Google Cloud 产品为 Gemini Cloud Assist,则此值为 cloud_assist。否则,此值为 unknown
LogEntry.labels.request_id 用于将请求与回答日志条目相关联的唯一标识符。
LogEntry.labels.user_id 发出此请求的用户的标识符。
LogEntry.jsonPayload 日志条目的载荷。用于生成回答的所有来源引用都以 attribution_context 的形式包含在此对象中。
LogEntry.logName 标识日志。

Gemini for Google Cloud 元数据日志

如需生成元数据日志,必须为 VS Code 和 IntelliJ 扩展程序启用“Gemini Code Assist 扩展程序”遥测设置。此外,对于 VS Code,还必须“启用全局遥测数据收集设置”

Gemini for Google Cloud 元数据日志遵循与 Gemini for Google Cloud 日志相同的结构,但指定了不同的字段。下表列出了用户请求日志条目中找到的字段:

字段 值和备注
LogEntry.@type Gemini for Google Cloud 元数据资源类型type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog
LogEntry.labels.method 对于元数据日志,此标签值为 Export.Metrics
LogEntry.labels.product Gemini for Google Cloud 服务名称。如果 Gemini for Google Cloud 产品为 Gemini Code Assist,则此值为 code_assist。如果 Gemini for Google Cloud 产品为 Gemini Cloud Assist,则此值为 cloud_assist。否则,此值为 unknown
LogEntry.labels.user_id 发出此请求的用户的标识符。
LogEntry.jsonPayload 表示 codeExposure 事件或 code.Acceptance 事件。codeExposure 事件表示向用户显示了代码建议。code.Acceptance 事件表示用户发生了某些接受事件,例如覆盖输入、Tab 键或完全接受。
LogEntry.jsonPayload.clientName IDE 名称,例如 CloudCodeVscode
LogEntry.jsonPayload.clientVersion IDE 版本号。
LogEntry.jsonPayload.codeAcceptance 仅适用于 VS Code 和 IntelliJ IDE,表示用户发生了某些接受事件,例如覆盖输入、Tab 键或完全接受。还包含以下字段:
  • linesCount:用户接受的代码行总数。
  • commentLinesCount:用户接受的代码中的注释行数。只有当 Gemini Code Assist 能够确定接受的行中有多少是注释行时,此属性才会显示。
  • originalRequestId:用于将 codeExposure 事件与零个或零个以上的 codeAcceptance 事件相关联的标识符。可用于计算接受率接受的代码行数度量。
  • programmingLanguage:所接受代码的编程语言,例如 python
LogEntry.jsonPayload.codeExposure 仅适用于 VS Code 和 IntelliJ IDE,表示向用户显示了代码建议。还包含以下字段:
  • programmingLanguage:曝光的编程语言,例如 python
  • originalRequestId:用于将 codeExposure 事件与零个或零个以上的 codeAcceptance 事件相关联的标识符。可用于计算接受率接受的代码行数度量。
LogEntry.jsonPayload.chatExposure 表示对话回答已向用户呈现。还包含以下字段:
  • originalRequestId:用于将 chatExposure 事件与零个或零个以上的 chatAcceptance 事件相关联的标识符。可用于计算对话接受率接受的对话行数度量。
  • is_agentic:一个标识符,用于指示 chatExposure 是否来自智能体模式。可用于区分智能体模式和非智能体模式下的对话接受率和接受的代码行数度量。
LogEntry.jsonPayload.chatAcceptance 指示用户对对话回答中的代码块执行了某个接受事件。还包含以下字段:
  • interactionType:用户与代码块的互动类型,例如 ACCEPT_CODE_BLOCK
  • programmingLanguage:所接受代码的编程语言,例如 python
  • linesCount:用户接受的代码行总数。
  • originalRequestId:用于将 chatExposure 事件与零个或零个以上的 chatAcceptance 事件相关联的标识符。
  • is_agentic:一个标识符,用于指示 chatAcceptance 是否来自智能体模式。可用于区分智能体模式和非智能体模式下的对话接受率和接受的代码行数度量。

以下示例展示了 codeExposure 日志条目示例:

{
  insertId: "whfrqgc1gj"
  jsonPayload: {
    @type: "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog"
    clientName: "CloudCodeVscode"
    clientVersion: "1.93.1"
    codeExposure: {
      originalRequestId: "cac019824a0b25ba"
      programmingLanguage: "python"
    }
  requestId: "0c5178fe-446f-4ab6-b996-520dec100cf8"
  }
  labels: {
    method: "Export.Metrics"
    product: "code_assist"
    user_id: "user@company.com"
  }
  logName: "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata"
  receiveTimestamp: "2025-02-03T23:34:35.662837985Z"
  resource: {
    labels: {
      instance_id: "default"
      location: "global"
      resource_container: "my-project-id"
    }
  type: "cloudaicompanion.googleapis.com/Instance"
  }
  severity: "INFO"
  timestamp: "2025-02-03T23:34:35.021564463Z"
}

以下示例展示了 codeAcceptance 日志条目示例:

{
  insertId: "whfrqgc1gk"
  jsonPayload: {
    @type: "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog"
    clientName: "CloudCodeVscode"
    clientVersion: "1.93.1"
    codeAcceptance: {
      linesCount: 2
      originalRequestId: "cac019824a0b25ba"
      programmingLanguage: "python"
    }
    requestId: "ddf11040-c315-452e-b7cd-928c3f97984e"
  }
  labels: {
    method: "Export.Metrics"
    product: "code_assist"
    user_id: "user@company.com"
  }
  logName: "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata"
  receiveTimestamp: "2025-02-03T23:34:37.632662272Z"
  resource: {
    labels: {
      instance_id: "default"
      location: "global"
      resource_container: "my-project-id"
    }
    type: "cloudaicompanion.googleapis.com/Instance"
  }
  severity: "INFO"
  timestamp: "2025-02-03T23:34:36.778692483Z"
} 

以下示例展示了 chatAcceptance 日志条目示例:

{
  "insertId": "1oru1grbow",
  "jsonPayload": {
    "clientVersion": "1.103.2",
    "requestId": "32a0b0b8c967d8e8",
    "clientName": "CloudCodeVscode",
    "chatAcceptance": {
      "interactionType": "ACCEPT_CODE_BLOCK",
      "programmingLanguage": "go",
      "linesCount": "15",
      "originalRequestId": "75f7c41e63162567"
    },
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "resource_container": "my-project-id",
      "instance_id": "default",
      "location": "global"
    }
  },
  "timestamp": "2025-08-25T09:34:01.240377123Z",
  "severity": "INFO",
  "labels": {
    "product": "code_assist",
    "method": "Export.Metrics",
    "user_id": "user@company.com"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata",
  "receiveTimestamp": "2025-08-25T09:34:01.704925625Z"
}

以下示例展示了 chatExposure 日志条目示例:

{
  insertId: "3diaj2c208"
  jsonPayload: {
    @type: "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog"
    clientName: "CloudCodeVscode"
    clientVersion: "1.93.1"
    chatExposure: {
      originalRequestId: "cac019824a0b25ba"
    }
  requestId: "0c5178fe-446f-4ab6-b996-520dec100cf8"
  }
  labels: {
    method: "Export.Metrics"
    product: "code_assist"
    user_id: "user@company.com"
  }
  logName: "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata"
  receiveTimestamp: "2025-02-03T23:34:35.662837985Z"
  resource: {
    labels: {
      instance_id: "default"
      location: "global"
      resource_container: "my-project-id"
    }
  type: "cloudaicompanion.googleapis.com/Instance"
  }
  severity: "INFO"
  timestamp: "2025-02-03T23:34:35.021564463Z"
}

计算接受率

以下部分介绍了如何使用 Gemini Code Assist 元数据日志计算代码建议接受率、对话回答接受率和总接受率。

计算代码接受率

如需使用 Gemini Code Assist 元数据日志计算代码接受率,请找到包含 codeAcceptance.originalRequestId 的事件中的唯一 ID 总数,然后将其除以包含 codeExposure.originalRequestId 的事件中的唯一 ID 总数。

您可以使用相应的元数据日志事件字段,按编程语言和用户进一步细化此计算结果。

计算对话接受率

如需使用 Gemini Code Assist 元数据日志计算对话接受率,请找到包含 chatAcceptance.originalRequestId 的事件中的唯一 ID 总数,然后将其除以包含 chatExposure.originalRequestId 的事件中的唯一 ID 总数。

您可以使用相应的元数据日志事件字段,按编程语言和用户进一步细化此计算结果。

计算总接受率

如需使用 Gemini Code Assist 元数据日志计算总接受率,请找到接受的事件总数,然后将其除以公开事件总数:

总接受率 = 接受的事件总数 ÷ 公开事件总数

  • 接受的事件总数:包含 codeAcceptance.originalRequestId 的事件中的唯一 ID 总数加上包含 chatAcceptance.originalRequestId 的事件中的唯一 ID 总数。
  • 公开事件总数:包含 codeExposure.originalRequestId 的事件中的唯一 ID 总数,加上包含 chatExposure.originalRequestId 的事件中的唯一 ID 总数。

此公式提供的接受率反映了所有 Gemini Code Assist 功能中任何建议被接受的总体概率。

计算被接受的代码行数

以下部分介绍了如何使用 Gemini Code Assist 元数据日志计算通过代码建议接受的代码行数、通过对话接受的代码行数,以及接受的代码总行数。

计算被接受的代码行数

如需计算接受的代码行数,请针对每个唯一的 codeAcceptance.originalRequestId 查找 codeAcceptance.linesCount 的最大值。 然后,将这些最大值相加,以计算接受的代码总行数。

您可以使用相应的元数据日志事件字段,按编程语言和用户进一步细化此计算结果。

计算通过对话接受的代码行数

如需计算通过对话接受的代码行数,请针对每个唯一的 chatAcceptance.originalRequestId 查找 chatAcceptance.linesCount 字段的值。然后,将这些最大值相加,以计算接受的对话总行数。

计算接受的代码总行数

如需使用 Gemini Code Assist 元数据日志计算接受的总行数,请将接受的代码行数通过对话接受的代码行数相加。

后续步骤