查询和查看日志

借助 Google Distributed Cloud (GDC) 网闸隔离配置中的日志查询功能,您可以在收集日志后,检查项目工作负载中的操作和审核事件。您可以使用日志查询语言 (LogQL) 表达式在 Grafana 日志面板中过滤、直观呈现和导出日志流。对于程序化工作流,请按照标准 API 访问方法,通过 HTTP 或 gRPC 查询组织的 Log Query API。

准备工作

如需查询和直观呈现日志,您必须拥有必要的权限。

申请 IAM 组织角色

请与您的 IAM 组织管理员联系,申请获得以下角色:

  • Organization Grafana Viewer (organization-grafana-viewer):在 Grafana 监控实例的信息中心内直观呈现与组织相关的可观测数据。
  • Log Querier (log-query-api-querier-pa):访问 Log Query API,以查询 platform-obs 项目中的平台日志。

申请 IAM 项目角色

请与您的 IAM 项目管理员联系,申请获得以下角色:

  • Project Grafana Viewer (project-grafana-viewer):在项目命名空间中的 Grafana 监控实例的信息中心内直观呈现与项目相关的可观测数据。
  • Log Querier (log-query-api-querier):访问 Log Query API 以查询项目命名空间中的应用日志。

下表总结了 PA 和 AO 身份角色的 Role 要求:

角色 对象 集群 角色 命名空间 群组/用户
PA grafana 管理 API 服务器 project-grafana-viewer platform-obs 群组
PA log-query-api 管理 API 服务器 log-query-api-querier-pa platform-obs 群组
PA grafana 管理 API 服务器 project-grafana-viewer platform-obs 用户
PA log-query-api 管理 API 服务器 log-query-api-querier-pa platform-obs 用户
AO grafana 管理 API 服务器 project-grafana-viewer PROJECT_NAMESPACE 群组
AO log-query-api 管理 API 服务器 log-query-api-querier PROJECT_NAMESPACE 群组
AO grafana 管理 API 服务器 project-grafana-viewer PROJECT_NAMESPACE 用户
AO log-query-api 管理 API 服务器 log-query-api-querier PROJECT_NAMESPACE 用户

选择以下配置之一,以向 Management API 服务器上的用户组 (Config 1) 或个人用户 (Config 2) 授予 Grafana 访问权限。对于每种配置,您可以运行 kubectl 命令直接创建 RoleBinding,也可以将 RoleBinding YAML 清单保存到指定的基础设施即代码 (IaC) 文件路径,以便通过 GitOps 应用:

配置 1

此配置会向用户群组授予对管理 API 服务器上的 PA 和 AO Grafana 的访问权限。完成此配置后,请参阅本文档的 Grafana 信息中心部分,在 Grafana 上查看日志。

  • kubectl 命令

    运行以下命令,直接创建 RoleBinding:

    kubectl --kubeconfig KUBECONFIG create rolebinding RULE_NAME -n platform-obs --group=GROUP_NAME --role=project-grafana-viewer
    

    示例:

    kubectl --kubeconfig KUBECONFIG_PATH create rolebinding project-grafana-viewers-binding --role=project-grafana-viewer --group=my-team --namespace=platform-obs
    
  • IaC 文件路径

    或者,如需使用 IaC 管理 RoleBinding,请在以下路径中创建 YAML 文件:

    /infrastructure/zonal/zones/ZONE/org-admin/rolebindings/GROUP_NAME/YAML_FILE
    
  • YAML 文件

    将以下 RoleBinding 清单保存在 IaC 文件路径中的 YAML 文件中:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: RULE_NAME
      namespace: platform-obs
    subjects:
    - kind: Group
      name: GROUP_NAME
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: project-grafana-viewer
      apiGroup: rbac.authorization.k8s.io
    

配置 2

此配置会向用户授予在管理 API 服务器上访问 PA 和 AO Grafana 的权限。设置此配置后,请参阅本文档的 Grafana 信息中心部分,以在 Grafana 上查看日志。

  • kubectl 命令

    运行以下命令,直接创建 RoleBinding:

    kubectl --kubeconfig KUBECONFIG create rolebinding RULE_NAME -n platform-obs --user=EMAIL_ADDRESS --role=project-grafana-viewer
    

    示例:

    kubectl --kubeconfig KUBECONFIG_PATH create rolebinding project-grafana-viewers-binding --role=project-grafana-viewer --user=my-email@example.com --namespace=platform-obs
    
  • IaC 文件路径

    或者,如需使用 IaC 管理 RoleBinding,请在以下路径中创建 YAML 文件:

    /infrastructure/zonal/zones/ZONE/org-admin/rolebindings/EMAIL_ADDRESS/YAML_FILE
    
  • YAML 文件

    将以下 RoleBinding 清单保存在 IaC 文件路径中的 YAML 文件中:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: RULE_NAME
      namespace: platform-obs
    subjects:
    - kind: User
      name: EMAIL_ADDRESS
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: project-grafana-viewer
      apiGroup: rbac.authorization.k8s.io
    

替换以下内容:

  • KUBECONFIG:特定集群的 kubeconfig 文件的路径,该集群包含应用此 RoleBinding 的 NAMESPACE。
  • KUBECONFIG_PATH:示例命令中 kubeconfig 文件的路径。
  • RULE_NAME:此 RoleBinding 资源在命名空间中的唯一名称,例如 pa-project-grafana-viewer。
  • NAMESPACE:在其中创建和应用此 RoleBinding 的 Kubernetes 命名空间。请查看上表中的 Namespace 列。
  • EMAIL_ADDRESS:被授予该角色的用户的标识符,例如 application-operator@example.com。
  • ROLE:包含您要授予用户的权限的 Role 的名称。请在上表中查找可用角色。
  • GROUP_NAME:PA 用户所属的 Group 的名称,例如 pa-group。
  • ZONE:区域的名称。
  • YAML_FILE:RoleBinding 资源的 YAML 文件的名称。

如需详细了解这些角色,请参阅准备 IAM 权限。

查询和过滤日志

选择以下方法之一,以构建查询并过滤项目工作负载中的日志:

Grafana 日志面板

本部分介绍如何使用 Grafana 中的“日志”面板访问日志。

确定 Grafana 端点

以下网址是项目的 Grafana 实例的端点:

  https://GDC_URL/PROJECT_NAMESPACE/grafana

替换以下内容:

  • GDC_URL:GDC 中组织的网址。
  • PROJECT_NAMESPACE:您的项目命名空间。

    例如,org-1 组织中 platform-obs 项目的 Grafana 端点为 https://org-1/platform-obs/grafana。

在 Grafana 界面中查看日志

在 Grafana 界面中查询日志:

  1. 在 GDC 控制台中,选择您的项目。
  2. 在导航菜单中,依次选择运维 > Logging。
  3. 点击在 Grafana Loki 中查看全部。

    系统会打开一个新页面,其中显示您的 Grafana 端点和界面。

  4. 在界面上,点击导航菜单中的探索 探索,打开探索页面。

  5. 在探索栏的菜单中,根据您的 Universe 类型选择一个数据源来检索日志:

    • 单可用区 Universe:选择以下数据源之一,以显示 Universe 的单个可用区中的日志记录数据:

      • 运维日志:显示运维日志。
      • 审核日志:显示审核日志。
    • 多可用区 Universe:Grafana 可以连接到不同的可用区并显示跨可用区数据。选择以下数据源之一,以显示来自宇宙中任何可用区的日志记录数据,无论您登录的是哪个可用区:

      • 运维日志 ZONE_NAME:显示特定可用区的运维日志。
      • 审核日志 ZONE_NAME:显示特定可用区的审核日志。

      此外,如需在单个信息中心内实现跨可用区数据可视化,并向查询添加多个可用区,请选择混合作为数据源。

  6. 输入查询,使用 LogQL(日志查询语言)表达式从“日志”面板中搜索日志。您可以通过以下任一方式执行此步骤:

    • 使用交互式查询构建器界面。然后,点击运行查询。
    • 直接在文本字段中输入查询,然后按 Shift+Enter 运行查询。

    该页面会显示与您的查询匹配的日志。查询日志后,您可以将其导出。点击导出,以纯文本或 CSV 格式下载日志。您还可以为日志选择时间范围。

    在“探索”页面上选择“审核日志”选项,以获取审核日志。

    图 1. 用于从 Grafana 界面查询审核日志的菜单选项。

    在图 1 中,审核日志选项会显示一个界面,您可以通过该界面从 Grafana 构建查询来检索审核日志。

    如需查看用于查询不同日志的标签和值示例,请参阅示例查询和标签。

为日志选择时间范围

如需查询某个时间范围内的日志,请按以下步骤操作:

  1. 点击 Grafana 中的 时间选择器菜单。

  2. 从菜单中,执行以下操作之一:

    • 选择相对时间范围选项,例如过去 30 分钟。
    • 通过从日历中选择特定日期和时间,然后点击应用时间范围,设置自定义绝对时间范围。
  3. (可选)点击更改时间设置,通过时间范围控件更改时区和财年设置。

    时间设置会按信息中心保存。如需详细了解一段时间内的查询,请参阅 https://grafana.com/docs/loki/latest/reference/api/#query-loki-over-a-range-of-time。

Log Query API

本部分介绍了如何使用 Log Query API 访问日志。

确定 Log Query API 端点

Log Query API 公开了以下两个端点,用于查询审核日志和操作日志:

  • 审核日志端点:

    audit-log-query-api.ORG_DOMAIN
    
  • 操作日志端点:

    operational-log-query-api.ORG_DOMAIN
    

将 ORG_DOMAIN 替换为组织的域名。您可以使用 gdcloud config list 命令查看此属性。域名必须遵循语法 org-name.zone.google.gdch.com。例如,在 zone1 区域和测试环境中,名为 org-1 的组织具有类似于 org-1.zone1.google.gdch.test 的网域。

Log Query API 具有以下三个端点选项:

  • labels:列出项目的所有标签。
  • labels/labels/LABEL/values:列出项目的特定标签值。
  • logs:列出特定项目的日志。

如需了解详情,请参阅 API 文档。

发送查询

使用 HTTP 或 gRPC 客户端向 Log Query API 端点发送查询。

HTTP

按照说明使用 HTTP 客户端直接访问 API。 您可以依靠 kubectl 来管理身份验证,也可以自行处理身份验证。

使用 curl、wget 等 HTTP 客户端或您创建和管理的 HTTP 客户端查询 Log Query API。以下示例使用 curl 工具查询 API,您可以对 wget 命令使用类似的格式:

  1. 对 cURL 请求进行身份验证:

    1. 下载并安装 gdcloud CLI。
    2. 设置 gdcloud core/organization_console_url 属性:

      gdcloud config set core/organization_console_url https://GDC_URL
      

      将 GDC_URL 替换为 GDC 中组织的网址。

    3. 使用配置的身份提供方登录:

      gdcloud auth login
      
    4. 使用您的用户名和密码进行身份验证并登录。

    5. 将指定账号的身份令牌导出到环境变量:

      export TOKEN="$($HOME/gdcloud auth print-identity-token --audiences=https://LOG_QUERY_API_ENDPOINT)"
      

      将 LOG_QUERY_API_ENDPOINT 替换为您要从中查询日志的日志查询 API 端点以及您要连接到的网域。因此,audiences 标志的值可以是 https://operational-log-query-api.org-1.zone1.google.gdch.test。

      登录成功后,您可以通过 gdcloud auth print-identity-token 命令在 cURL 请求中使用授权标头。如需了解详情,请参阅 gdcloud auth print-identity-token。

  2. 如果您想列出项目的所有标签,请发送以下查询:

    curl -H "Authorization: Bearer ${TOKEN}" \
    https://LOG_QUERY_API_ENDPOINT/v1/projects/PROJECT_NAMESPACE/labels \
    -H "Content-Type: application/json" -v
    

    替换以下内容:

    • LOG_QUERY_API_ENDPOINT:您要从中查询日志的日志查询 API 端点。
    • PROJECT_NAMESPACE:您的项目命名空间。
  3. 如果您想列出项目的特定标签值,请发送以下查询:

    curl -H "Authorization: Bearer ${TOKEN}" \
    https://LOG_QUERY_API_ENDPOINT/v1/projects/PROJECT_NAMESPACE/labels/labels/LABEL/values \
    -H "Content-Type: application/json" -v
    

    替换以下内容:

    • LOG_QUERY_API_ENDPOINT:您要从中查询日志的日志查询 API 端点。
    • PROJECT_NAMESPACE:您的项目命名空间。
    • LABEL:您要查询其值的特定标签。
  4. 如果您想查询特定项目的日志,请构建 logs_filter 查询并将其添加到请求正文中:

    curl -X GET -H "Authorization: Bearer ${TOKEN}" \
    https://LOG_QUERY_API_ENDPOINT/v1/projects/PROJECT_NAMESPACE/logs \
    -H "Content-Type: application/json" -d \
    '{"logs_filter": {"labels_equal": {"LABEL": "LABEL_VALUE"}}}' -v
    

    替换以下内容:

    • LOG_QUERY_API_ENDPOINT:您要从中查询日志的日志查询 API 端点。
    • PROJECT_NAMESPACE:您的项目命名空间。
    • LABEL:您要查询其日志的特定标签。
    • LABEL_VALUE:要查询其日志的标签值。

    请参阅 API 文档,了解构建 logs_filter 查询的所有选项。

gRPC

gRPC 在各种编程语言中都得到了广泛支持,与 HTTP 客户端相比,它提供了更高效的通信方法。

如需使用 gRPC 查询日志,您必须满足以下前提条件:

  • 基于 Google 提供的协议缓冲区创建您自己的客户端库。
  • 在客户端中实现身份验证。
  • 实现重试。

如需了解协议缓冲区,请参阅 API 文档。

以下示例展示了如何使用未经身份验证的 gRPC 客户端从 Go 程序查询日志。该示例假设您创建了一个 golang 软件包,其中包含用于导入代码依赖项的 Bazel build 文件:

  1. 将以下代码保存到名为 client.go 的 Go 程序中:

    package main
    import (
            "context"
            "crypto/tls"
            "flag"
            "fmt"
            "google.golang.org/grpc/credentials"
            "google.golang.org/grpc/metadata"
            pb "<import path to generated log query api protos>/pkg/apis/public/logging/v1/proto"
            "google.golang.org/grpc"
    )
    
    var serverAddr = flag.String("server", "localhost:8080", "server address")
    
    func main() {
            flag.Parse()
            tc := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})
            conn, err := grpc.Dial(*serverAddr, grpc.WithTransportCredentials(tc))
    
            if err != nil {
                    panic(error.Error(fmt.Errorf("create client connection failed: %v", err)))
            }
            defer conn.Close()
    
            c := pb.NewLogsClient(conn)
            md := metadata.Pairs("clienttest", "test")
            ctx := metadata.NewOutgoingContext(context.Background(), md)
    
            err = listLabels(ctx, c, "project-foo")
            if err != nil {
                    panic(error.Error(err))
            }
    
            if err := listLabelValues(ctx, c, "project-foo", "resource-bar"); err != nil {
                    panic(error.Error(err))
            }
    
            if err := listLogs(ctx, c, "project-foo", &pb.ListLogsFilter{
                    LabelsEqual:    map[string]string{"resource-bar": "resource-bar-value"},
                    OrderAscending: true,
            }); err != nil {
                    panic(error.Error(err))
            }
    }
    
    // List all labels for a project.
    
    func listLabels(ctx context.Context, c pb.LogsClient, project string) error {
            lbr := &pb.ListLabelsRequest{
                    Parent:   project,
                    PageSize: 1000, // PageSize can be configured to limit the number of responses per page.
            }
            resp, err := c.ListLabels(ctx, lbr)
            if err != nil {
                    return fmt.Errorf("list labels: %v", err)
            }
            fmt.Printf("%v", resp)
            return nil
    }
    
    // List specific label values for a project.
    
    func listLabelValues(ctx context.Context, c pb.LogsClient, project string, label string) error {
            lbr := &pb.ListLabelValuesRequest{
                    Parent:   project,
                    Label:    label,
                    PageSize: 1000, // PageSize can be configured to limit the number of responses per page.
            }
            resp, err := c.ListLabelValues(ctx, lbr)
            if err != nil {
                    return fmt.Errorf("list label values: %v", err)
            }
            fmt.Printf("%v", resp)
            return nil
    }
    
    // List logs for a specific project.
    
    func listLogs(ctx context.Context, c pb.LogsClient, project string, lf *pb.ListLogsFilter) error {
            lbr := &pb.ListLogsRequest{
                    Parent:     project,
                    LogsFilter: lf,
                    PageSize:   5, // PageSize can be configured to limit the number of responses per page.
            }
            resp, err := c.ListLogs(ctx, lbr)
            if err != nil {
                    return fmt.Errorf("list logs: %v", err)
            }
            fmt.Printf("logs: %v", resp)
            return nil
    }
    
  2. 运行 Go 程序:

    go run PATH_TO_API/client.go -server=LOG_QUERY_API_ENDPOINT:443
    

    替换以下内容:

    • PATH_TO_API:API 文件的路径。
    • LOG_QUERY_API_ENDPOINT:您要从中查询日志的日志查询 API 端点。

    如果未指定服务器标志,则默认请求会发送到 localhost。

示例查询和标签

以下是可用于查询日志的一些默认标签:

  • cluster:集群的名称。
  • namespace:您的项目命名空间。
  • node:节点名称。
  • pod:Pod 名称。
  • container:容器名称。

以下代码示例展示了如何使用标签和值来查询不同的日志:

  • 选择服务器日志:

    {cluster="admin", namespace="kube-system", resources="k8s_container", container="kube-apiserver"}
    
  • 选择集群审核日志:

    {cluster="admin", resources="k8s_audit"}