You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Google Cloud Logging API获取next_page_token?解决生成器对象错误

解决GCE日志获取中next_page_token访问失败的问题

错误原因

loggingClient.list_entries()默认返回的是生成器对象,它会自动遍历所有分页条目,但生成器本身没有next_page_token属性,直接访问会抛出AttributeError。

解决方案

方案1:自动遍历所有日志(无需手动处理token)

如果只是需要获取当月所有日志,直接迭代生成器即可,它会自动处理分页逻辑:

from pytz import timezone
from datetime import datetime
from calendar import monthrange
from google.cloud import logging
from google.oauth2 import service_account

def getInstanceLogsList(
    instanceId: str,
    authTokenDict: dict,
):
    today = datetime.now().astimezone(tz=timezone("Asia/Kolkata"))

    monthStartDay = 1
    monthEndDay = monthrange(today.year, today.month)[1]
    
    credentials = service_account.Credentials.from_service_account_info(authTokenDict)
    loggingClient = logging.Client(credentials=credentials)

    # 生成符合RFC3339标准的时间字符串(GCP Logging要求的格式)
    end_dt = datetime(year=today.year, month=today.month, day=monthEndDay, hour=23, minute=59, second=59, tzinfo=timezone("Asia/Kolkata"))
    start_dt = datetime(year=today.year, month=today.month, day=monthStartDay, hour=0, minute=0, second=0, tzinfo=timezone("Asia/Kolkata"))
    startDateTimeObject = start_dt.isoformat()
    endDateTimeObject = end_dt.isoformat()

    listLogsResponse = []
    # 直接迭代生成器,自动处理分页
    for entry in loggingClient.list_entries(
        filter_=f'resource.type = "gce_instance" AND resource.labels.instance_id = "{instanceId}" AND timestamp >= "{startDateTimeObject}" AND timestamp <= "{endDateTimeObject}"'
    ):
        listLogsResponse.append(entry)
    
    return listLogsResponse

方案2:手动获取next_page_token(需保存token时使用)

如果需要手动控制分页并获取next_page_token,需要通过pages属性访问分页响应对象:

from pytz import timezone
from datetime import datetime
from calendar import monthrange
from google.cloud import logging
from google.oauth2 import service_account

def getInstanceLogsList(
    instanceId: str,
    authTokenDict: dict,
):
    today = datetime.now().astimezone(tz=timezone("Asia/Kolkata"))

    monthStartDay = 1
    monthEndDay = monthrange(today.year, today.month)[1]
    
    credentials = service_account.Credentials.from_service_account_info(authTokenDict)
    loggingClient = logging.Client(credentials=credentials)

    # 生成符合RFC3339标准的时间字符串
    end_dt = datetime(year=today.year, month=today.month, day=monthEndDay, hour=23, minute=59, second=59, tzinfo=timezone("Asia/Kolkata"))
    start_dt = datetime(year=today.year, month=today.month, day=monthStartDay, hour=0, minute=0, second=0, tzinfo=timezone("Asia/Kolkata"))
    startDateTimeObject = start_dt.isoformat()
    endDateTimeObject = end_dt.isoformat()

    pageToken = None
    listLogsResponse = []
    
    while True:
        # 获取分页迭代器
        iterator = loggingClient.list_entries(
            filter_=f'resource.type = "gce_instance" AND resource.labels.instance_id = "{instanceId}" AND timestamp >= "{startDateTimeObject}" AND timestamp <= "{endDateTimeObject}"',
            page_token=pageToken
        ).pages
        
        try:
            page = next(iterator)
            listLogsResponse.extend(page)
            pageToken = page.next_page_token
            if not pageToken:
                break
        except StopIteration:
            break
    
    return listLogsResponse

额外注意事项

原代码中用strftime("%Y-%m-%dT%H:%M:%S%z")生成的时区格式是+0530,而GCP Logging的timestamp筛选要求RFC3339格式(如+05:30),改用isoformat()可以避免筛选条件失效。


内容的提问来源于stack exchange,提问作者Daniel Vanum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 04:50:18