流式传输和 Live Tailing 日志条目

本文档介绍了如何通过流式传输和 Live Tailing 来实时查看日志条目。借助流式传输日志,您可以实时查看日志条目,并且可以在 Logs Explorer 中查看流式传输日志。借助 Live Tailing,您可以实时查看日志条目;Live Tailing 以 gcloud CLI 命令 gcloud alpha logging tail 和 Cloud Logging API 方法 entries.tail 的形式提供。

使用 Logs Explorer、gcloud logging read 或 API 方法 entries.list 查看和分析日志时,您查看的是 Cloud Logging 已存储的日志条目。如果您流式传输或 Live Tail 日志条目,则在应用将日志条目写入 Cloud Logging API 后,您就可以立即查看日志条目。

在 Logs Explorer 中流式传输日志

在日志浏览器中,您可以使用流式传输日志实时查看日志数据。使用流式传输日志时,您可以添加查询,以仅流式传输与查询匹配的日志。如需流式传输日志,请执行以下操作:

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

    前往 Logs Explorer

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

  2. 在查询字段中,输入查询,然后点击流式传输日志。

    在 Logging 写入日志数据时,只有与查询匹配的日志才会显示在查询结果窗格中。如果未提供查询,则 Logging 会显示最近存储的日志条目。日志会继续流式传输,直到您选择日志面板上的滚动条。流式传输停止后,系统会显示重新开始流式传输按钮。

    如需了解查询,请参阅在 Logs Explorer 中构建查询。

在 Google Cloud CLI 中使用 Live Tailing

借助 Live Tailing,您可以在 Cloud Logging 写入日志条目时使用 Google Cloud CLI 或 Cloud Logging API 实时查看日志条目。

具有字段级访问权限控制的日志存储桶不支持 Live Tailing,但您可以在 Logs Explorer 中为这些存储桶流式传输日志。

如需了解 Live Tailing 的 API 方法,请参阅 entries.tail 方法。

安装 gcloud alpha logging tail

如需使用 gcloud alpha logging tail,您需要安装 Python 3 和 grpcio Python 软件包。

如需了解如何安装 Python,请参阅 Python 页面。如需了解如何安装 grpcio 软件包安装所需的 Python 软件包管理系统 pip,请参阅 Python 软件包安装程序页面。

完成以下步骤以安装 gcloud alpha logging tail:

  1. 确认您已安装 Google Cloud CLI。如需了解如何安装 Google Cloud CLI,请参阅安装 Google Cloud CLI。

  2. 确认您使用的是 gcloud CLI 的 302.0.0 或更高版本。

    gcloud version
    

    如需了解如何更新 gcloud CLI,请参阅 gcloud components update。

  3. 安装 gcloud CLI Alpha 版组件:

    gcloud components install alpha
    
  4. 对于 MacOS、Linux 和 Cloud Shell 用户:

    1. 安装 gRPC 客户端库:

       sudo pip3 install grpcio
      
    2. 将环境变量 CLOUDSDK_PYTHON_SITEPACKAGES 设置为任意值:

       export CLOUDSDK_PYTHON_SITEPACKAGES=1
      
  5. 使用以下命令设置 Google Cloud 项目 ID 并进行身份验证:

    gcloud config set project PROJECT_ID
    gcloud auth login
    

    要获取项目 ID,请参阅创建和管理项目。

  6. 通过运行以下命令来验证是否已安装 gcloud alpha logging tail:

    gcloud alpha logging tail
    

    该命令会显示以下消息:

    Initializing tail session.

    现在,您可以在 Logging 写入 Google Cloud 项目的日志条目时查看日志条目。

    Live Tail 期间的日志条目。

如需详细了解如何使用 Live Tailing,请参阅 gcloud alpha logging tail 参考指南。

缓冲和排序

由于 Logging 可以不按时间顺序接收日志条目,因此 Live Tailing 提供缓冲时段设置,以便您适当选择在系统写入日志条目时查看日志条目以及按升序查看日志条目。您可以将缓冲时段设置为 0 到 60 秒。

请注意缓冲时段的以下特性:

  • 默认缓冲时段为 2 秒。

  • Logging 会将日志条目写入日志存储桶的操作延迟一段时间(即缓冲时段的时长)。

  • 如果系统在缓冲时段之外写入日志条目,则 Logging 会在收到日志条目时返回日志条目。

配置缓冲时段时,您需要适当选择在系统写入日志时查看日志,以及不按顺序查看条目。

缓冲时段 权衡
0 秒 返回的最新日志条目,但可能不按顺序返回。
60 秒 延迟 60 秒才能看到返回的条目,但大多数日志都按升序返回。

限制和配额

下表列出了 Live Tailing 的限制和配额:

限制和配额 值
每分钟返回的条目数 60,000
如果与过滤条件匹配的条目数超过 60,000,则 Logging 会在响应中返回条目数。
每个 Google Cloud 项目打开的 Live Tailing 会话数 10

客户端限制

对于快速写入大量条目的 Google Cloud 项目,您的客户端可能无法在系统写入条目时使用这些条目。在这种情况下,Logging 会限制发送的条目总数,并优先处理最近的条目。在 Live Tail 结束时,Logging 会返回由于客户端限制而未显示的条目数。

将 Live Tailing 与客户端库搭配使用

借助 Live Tailing,您可以在 Cloud Logging 写入日志条目时实时查看日志条目。如需了解 Live Tailing 的 API 方法,请参阅 entries.tail 方法。

具有字段级访问权限控制的日志存储桶不支持 Live Tailing,但您可以在 Logs Explorer 中为这些存储桶流式传输日志。

此示例演示了给定 Logger 的 Live Tailing 日志条目。

Go

如需了解如何安装和使用 Logging 客户端库,请参阅 Logging 客户端库。

如需向 Logging 进行身份验证,请设置应用默认凭证。如需了解详情,请参阅为本地开发环境设置身份验证。

import (
	"context"
	"fmt"
	"io"

	logging "cloud.google.com/go/logging/apiv2"
	"cloud.google.com/go/logging/apiv2/loggingpb"
)

// tailLogs creates a channel to stream log entries that were recently ingested for a project
func tailLogs(projectID string) error {
	// projectID := "your_project_id"

	ctx := context.Background()
	client, err := logging.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("NewClient error: %w", err)
	}
	defer client.Close()

	stream, err := client.TailLogEntries(ctx)
	if err != nil {
		return fmt.Errorf("TailLogEntries error: %w", err)
	}
	defer stream.CloseSend()

	req := &loggingpb.TailLogEntriesRequest{
		ResourceNames: []string{
			"projects/" + projectID,
		},
	}
	if err := stream.Send(req); err != nil {
		return fmt.Errorf("stream.Send error: %w", err)
	}

	// read and print two or more streamed log entries
	for counter := 0; counter < 2; {
		resp, err := stream.Recv()
		if err == io.EOF {
			break
		}
		if err != nil {
			return fmt.Errorf("stream.Recv error: %w", err)
		}
		fmt.Printf("received:\n%v\n", resp)
		if resp.Entries != nil {
			counter += len(resp.Entries)
		}
	}
	return nil
}

Java

如需了解如何安装和使用 Logging 客户端库,请参阅 Logging 客户端库。

如需向 Logging 进行身份验证,请设置应用默认凭证。如需了解详情,请参阅为本地开发环境设置身份验证。

import com.google.cloud.logging.LogEntry;
import com.google.cloud.logging.LogEntryServerStream;
import com.google.cloud.logging.Logging;
import com.google.cloud.logging.Logging.TailOption;
import com.google.cloud.logging.LoggingOptions;

public class TailLogEntries {

  public static void main(String[] args) throws Exception {
    // TODO(developer): Optionally provide the logname as an argument.
    String logName = args.length > 0 ? args[0] : "";

    LoggingOptions options = LoggingOptions.getDefaultInstance();
    try (Logging logging = options.getService()) {

      // Optionally compose a filter to tail log entries only from specific log
      LogEntryServerStream stream;

      if (logName != "") {
        stream =
            logging.tailLogEntries(
                TailOption.filter(
                    "logName=projects/" + options.getProjectId() + "/logs/" + logName));
      } else {
        stream = logging.tailLogEntries();
      }
      System.out.println("start streaming..");
      for (LogEntry log : stream) {
        System.out.println(log);
        // cancel infinite streaming after receiving first entry
        stream.cancel();
      }
    }
  }
}

Node.js

如需了解如何安装和使用 Logging 客户端库,请参阅 Logging 客户端库。

如需向 Logging 进行身份验证,请设置应用默认凭证。如需了解详情,请参阅为本地开发环境设置身份验证。

const {Logging} = require('@google-cloud/logging');
const logging = new Logging();

/**
 * TODO(developer): Replace logName with the name of your log.
 */
const log = logging.log(logName);
console.log('running tail log entries test');

const stream = log
  .tailEntries({
    filter: 'timestamp > "2021-01-01T23:00:00Z"',
  })
  .on('error', console.error)
  .on('data', resp => {
    console.log(resp.entries);
    console.log(resp.suppressionInfo);
    // If you anticipate many results, you can end a stream early to prevent
    // unnecessary processing and API requests.
    stream.end();
  })
  .on('end', () => {
    console.log('log entry stream has ended');
  });

// Note: to get all project logs, invoke logging.tailEntries