使用 Cloud Logging 作为 VFX 渲染流水线的日志记录服务器

本教程概述了如何使用 Cloud Logging 代替日志记录服务器进行应用特定的日志记录。默认情况下,Cloud Logging 可聚合来自系统和许多常见应用的日志。此外,本教程还介绍了如何将来自自定义工作流或非常见应用的日志导入 Cloud Logging。

短期有效的工作器在许多计算工作负载中都很常见,如视觉效果 (VFX) 渲染流水线和构建系统。本教程重点介绍了视觉效果工作负载,并以独立视觉效果渲染程序 V-Ray 为例。在典型的使用场景中,虚拟机实例由队列系统按需创建,分配给作业(如一个或多个需要渲染的帧),并在作业完成后终止。您不仅必须在渲染过程中获取日志,而且还要从实例执行的渲染之前或之后的作业(如文件转换或将本地渲染的帧复制到常见存储服务)中获取日志。

目标

  • 创建一个实例,并在该实例上安装 Cloud Logging 代理。
  • 配置自定义应用或工作流以将日志发送到该 Cloud Logging 代理。
  • 使用 Python 客户端库将日志直接发送到 Logging。
  • 在 Logging 中查看、过滤和搜索日志。
  • 将日志从 Logging 导出到长期可访问的存储空间。

费用

本教程使用 Google Cloud 的以下收费组件:

  • Compute Engine

您可使用价格计算器根据您的预计使用量来估算费用。 Google Cloud 新用户可能有资格申请免费试用

请参阅 Logging 价格,了解本教程中与使用 Cloud Logging 相关的费用。

准备工作

  1. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到项目选择器页面

  2. 确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能

  3. 启用 Compute Engine API。

    启用 API

  4. 安装 gcloud beta 命令组件:

    gcloud components install beta
  5. 设置默认项目,这样就不必为每个命令提供 --project 标志:

    gcloud config set project PROJECT_ID

创建 Compute Engine 实例

Cloud Logging 代理适用于 Compute Engine 虚拟机实例和 Amazon Elastic Compute Cloud (Amazon EC2) 虚拟机实例。如需详细了解该代理和其支持的虚拟机实例,请参阅产品文档中的 Logging 代理

在本教程中,您可以创建带默认虚拟机类型的实例。但是,在生产中,您必须确定应用需要多少计算能力,并相应地选择虚拟机。

  1. 在 Cloud Console 中,转到虚拟机实例页面。

    转到“虚拟机实例”

  2. 点击创建实例
  3. 创建新实例页面上,填写实例的属性。 对于高级配置选项,展开管理、安全、磁盘、网络、单独租用部分。
  4. 点击创建以创建实例。

创建新实例需要一些时间。在本教程中,虚拟机实例被命名为 sd-tutorial

配置 Compute Engine 实例

使用具有超级用户权限的帐号创建虚拟机实例后,完成以下步骤:

  1. 使用 SSH 连接到 sd-tutorial 实例。

    gcloud compute ssh sd-tutorial
  2. 安装 Cloud Logging 代理。如需详细说明,请参阅安装 Cloud Logging 代理

  3. 下载并安装 pip

    sudo yum install python-pip
  4. 下载并安装 Cloud Logging Python 库

    pip install --user --upgrade google-cloud-logging
  5. /etc/google-fluentd/config.d/vray.conf 下为 V-Ray 创建 Cloud Logging 代理配置文件,其中包含以下内容:

    <source>
      @type tail
      read_from_head true
      format /^(\[(?<time>.*?)\])?((?<severity> ?(debug|info|warning|error|critical)): )?(?<message>.*)$/
      time_format %Y/%b/%d|%H:%M:%S
        # Log file names must be of the format SH.SEQ.SHOT.ROLE.log.
        # For example: myfilm.fba.0050.render.log
      path /home/*/vray/logs/*.log
      pos_file /var/lib/google-fluentd/pos/vray.pos
      tag vray.*
    </source>
    <filter vray.**>
      @type record_transformer
      <record>
        # Parse the log file name and add additional key:value records
        # to aid in filtering and searching logs in Logging.
        # Assumes you are following the convention in this tutorial.
        show ${tag_parts[-5]}
        seq ${tag_parts[-4]}
        shot ${tag_parts[-3]}
        role ${tag_parts[-2]}
        tag ${tag_suffix[1]} # Strip off the "vray." prefix.
      </record>
    </filter>
    

    如需详细了解 fluentd 配置,请参阅配置文件语法

  6. 重新加载 Cloud Logging 代理配置:

    sudo service google-fluentd reload

    在生产环境中,接下来您可以将此配置好的虚拟机转换为您的流水线可按需启动的自定义虚拟机映像

视觉效果的特殊注意事项

每个渲染软件包都会生成自己的日志输出。虽然本教程使用 V-Ray 独立渲染程序,但您可以调整本教程,以适应输出到 stdout/stderr 的其他渲染程序或应用。本教程使用通用的 fluentd 配置,并要求您的队列系统将渲染程序的输出重定向至一个格式特定且易于搜索的文件名。如果在单个虚拟机上运行多个作业,则需要使用唯一文件名。

为 Logging 中的日志文件命名

在定义 Logging 日志的命名惯例时,请遵循您的工作室使用的命名惯例最佳做法。Logging 可以跨资源进行搜索,因此使用一致的命名惯例可确保您能够搜索由不同资源生成且标记为具有相同或类似数据的日志。在本教程中,队列管理器会在启动渲染工作器进程前将下面的值填充到环境变量中,然后这些变量用于标记日志并生成唯一文件名:

字段名称 环境变量
显示(项目)名称 SHOW myfilm
序列名称 SEQ fba
镜头编号 SHOT 0050
角色 ROLE render

此示例将这些值汇编入视觉效果工作流的典型命名惯例:

<SHOW>.<SEQ>.<SHOT>.<ROLE>.log

例如,镜头 fba0050 的渲染日志的标记如下所示:

myfilm.fba.0050.render.log

本教程要求队列管理器根据此惯例设置日志文件名,但修改日志文件名来满足工作室的不同需求却非常简单。

手动测试 Logging 配置

要在不使用渲染程序或队列管理器的情况下检查配置,请将示例日志条目复制到测试日志中。在您的主目录中,输入以下命令:

mkdir -p vray/logs/
export SHOW='testshow' SEQ='testseq' SHOT='testshot' ROLE='testrole'
echo "debug: Test log line at `date` from ${HOSTNAME}" >> vray/logs/${SHOW}.${SEQ}.${SHOT}.${ROLE}.log

这一行应很快显示在日志查看器中。

验证日志传送

  1. 在 Cloud Console 中,转到日志查看器页面。

    转到“日志查看器”页面

    日志菜单下,您应该会看到使用您创建的日志名称标记的条目(本例中为 testshow.testseq.testshot.testrole)。

  2. 在此日志中查看您的输出:

    Cloud Logging 日志查看器

    您还可以使用 gcloud 工具 beta 版命令,在需要时替换 [project-id][log-name] 以读取日志:

    # List all logs.
    gcloud beta logging logs list
    
    # Read the contents of a specific log.
    gcloud beta logging read projects/[project-id]/logs/[log-name]
    

如需详细了解如何使用 gcloud 命令行工具进行日志记录,请参阅读取日志条目相关文档。

从渲染程序将日志写入 Logging

在正确设置并验证配置后,您可以使用如下所示的 V-Ray 独立命令行将日志发送给 Logging。在此示例中,命令行标志从为重定向到文件而优化的输出开始 V-Ray 进程。队列管理器会将 SCENE_FILE 替换为合适的本地文件路径。它还应该填充用于生成日志名称的四个环境变量(SHOWSEQSHOTROLE),如为日志文件命名部分中所述。

vray \
   -display=0 \
   -showProgress=0 \
   -progressUseCR=0 \
   -progressUseColor=0 \
   -sceneFile SCENE_FILE > vray/logs/${SHOW}.${SEQ}.${SHOT}.${ROLE}.log 2>&1

直接将日志写入 Cloud Logging API

大多数视觉效果流水线都使用某种脚本语言来执行编程任务,如素材资源准备、发布、数据传输、渲染或转码。您可以使用客户端库将这些任务的输出记录到 Logging。本教程使用 Python,因为它广泛应用于 VFX 行业。

您可以从本地工作站和基于云的工作站将日志发送到 Logging。您不需要安装 Logging 代理并以此方式写入日志,因为您通过 Python API 与 Logging 进行通信。

使用 Python 库将日志写入 Cloud Logging

要使用 Python 脚本将日志写入 Cloud Logging,您必须先执行以下操作:

  • 构建日志元数据。
  • 提供严重级别。
  • 确定要记录到的资源类型。

该脚本执行以下操作:

  • 进行检查,确保使用正确的命名惯例。
  • 汇编日志数据。
  • 在 Google 项目资源层级写入日志。

如果从本地工作站或服务器进行日志记录,则必须在将日志写入 Logging 前进行身份验证。如果从云实例进行日志记录,则已完成身份验证。

#!/usr/bin/python
#
# Copyright 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from google.cloud import logging
from google.cloud.logging.resource import Resource
import getpass
import os
import socket

def write(text, severity='INFO', show=None, seq=None, shot=None, role=None, **kwargs):
    '''Wrapper method for assembling the payload to send to logger.log_text.'''

    # Extract and build LOG_ID from environment.
    # For example: 'myfilm.slb.0050.render'
    if not show:
        show = os.getenv('SHOW')
    if not seq:
        seq = os.getenv('SEQ')
    if not shot:
        shot = os.getenv('SHOT')
    if not role:
        role = os.getenv('ROLE')

    if not show or not seq or not shot or not role:
        raise Exception('One or more log name tokens are empty. Unable to log.')
    # end if

    # Assemble logger name.
    logger_name = '.'.join([
        show,
        seq,
        shot,
        role
    ])

    print '# Logging to %s...' % logger_name

    # Build logger object.
    logging_client = logging.Client()
    logger = logging_client.logger(logger_name)

    # Assemble the required log metadata.
    label_payload = {
        "artist" : getpass.getuser(),
        "hostname" : socket.gethostname(),
        "show" : show,
        "seq" : seq,
        "shot" : shot,
        "role" : role
    }

    # Add optional kwargs to payload.
    label_payload.update(kwargs)

    # Write log.
    logger.log_text(
        text,
        resource=Resource(type='project', labels={'project_id':show}),
        severity=severity,
        labels=label_payload
    )

# end write

您可以将该模块导入流水线中的任何 Python 脚本,并在本地艺术家工作站或云实例上运行脚本:

import logToStackdriver as lts
lts.write( 'This is the text to log.', show='myfilm', seq='slb', shot='0050', role='render' )

默认情况下,所有日志都会写入“项目”资源,您可以在 Google Cloud Console 中找到该资源,具体位于 Logging > 日志 > Google 项目下:

Cloud Logging > 日志 > Google 项目

导出日志

如果您想在日志保留期限过后继续保存自己的日志,则应导出这些日志。

如需进行廉价且长期的存储,请将日志导出到 Compute Engine 存储分区。要对其执行大数据分析,请导出到 BigQuery 数据集。不论哪种情况,都需要首先创建一个名为接收器的对象。您可以利用接收器创建一个过滤器来选择要导出的日志条目,并且还可选择 Compute Engine 或 BigQuery 作为目标位置。创建接收器后,其会立即开始将指定日志导出到指定目标位置。您可以使用 Cloud Logging API 或直接使用 gcloud logging 命令行工具在日志查看器中导出日志。

导出到 BigQuery

您可以使用 SQL 语义查询存储在 BigQuery 中的日志。许多第三方分析工具都原生支持这些日志。请按照以下步骤操作:

  1. 创建 BigQuery 数据集

  2. 创建具有过滤器的接收器,将日志导出到该表。请注意,以下命令行中的 [PROJECT_ID] 是指您的 Google Cloud 项目。

    gcloud beta logging sinks create render-errors-bq  \
        bigquery.googleapis.com/projects/[PROJECT_ID]/datasets/[DATASET] \
        --log-filter "jsonPayload.SHOW=myfilm AND jsonPayload.SHOT=fba AND severity>=WARNING"
    
  3. 您将收到一条消息,其中包含要添加到 BigQuery 数据集的服务帐号名称。您可以通过点击数据集名称旁边的下拉列表,然后点击共享数据集的方式使用网页界面

发送到 Logging 且与此过滤器匹配的下一个日志,将在稍微延迟后发送到数据集中。要了解更多详情,请参阅接收器的工作原理文档。

导出到 Cloud Storage

要将日志保存到文件,请将其导出到 Cloud Storage 存储分区。对于 Cloud Storage 存储分区,您可以为访问频率较低的文件选择价格较低的存储类别,或利用免费用量限额。Cloud Storage 支持 HTTP,并且直接与许多其他 Google Cloud 产品集成,方便您使用。

以下步骤说明了如何导出到 Cloud Storage:

  1. 创建 Cloud Storage 存储分区。
  2. 在 Logging 中创建具有过滤器的接收器,将这些日志导出到 Cloud Storage。

    gcloud beta logging sinks create render-errors-gcs  \
        storage.googleapis.com/my-gcs-bucket \
        --log-filter "jsonPayload.SHOW=myfilm AND jsonPayload.SHOT=fba AND severity>=WARNING"
    

发送到 Logging 且与此过滤器匹配的下一个日志,将在稍微延迟后发送到存储分区的文件中。要了解更多详情,请参阅接收器的工作原理文档。

清理

为避免因本教程中使用的资源而导致您的 Google Cloud Platform 帐号产生费用,请执行以下操作:

删除项目

为了避免产生费用,最简单的方法是删除您为本教程创建的项目。

要删除项目,请执行以下操作:

  1. 在 Cloud Console 中,转到管理资源页面。

    转到“管理资源”页面

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

删除 Compute Engine 实例

要删除 Compute Engine 实例,请运行以下命令:

  1. 在 Cloud Console 中,转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 点击您要删除的实例。
  3. 点击删除 以删除实例。

删除您的 Cloud Storage 存储分区

如需删除 Cloud Storage 存储分区,请执行以下操作:

  1. 在 Cloud Console 中,转到 Cloud Storage 浏览器页面。

    转到“Cloud Storage 浏览器”页面

  2. 点击要删除的存储分区对应的复选框。
  3. 如需删除存储分区,请点击删除

后续步骤