排查 Logging 代理问题

本页面提供了相关说明,帮助您排查在安装 Logging 代理或与之交互时出现的常见问题。

核对清单

如果您在安装或使用 Logging 代理时遇到问题,请检查以下内容:

  • 如果 Linux 安装命令导致错误,请确保使用 sudo 作为安装命令的前缀。

  • 验证代理服务是否正在虚拟机实例上运行:

    • 对于 Windows 虚拟机,请使用以下 PowerShell 命令:

      Get-Service -Name StackdriverLogging
      

      搜索名为 Stackdriver Logging 的服务。如果代理未运行,您可能需要将其重启。

    • 对于 Linux 虚拟机,请使用以下命令:

      sudo service google-fluentd status
      

      如果代理未运行,则可能需要使用以下命令将其重启:

      sudo service google-fluentd restart
      

      如果重启失败,并且日志输出显示“已通过元数据停用”(Disabled via metadata),则您可能正在运行来自于 Google Cloud Marketplace 的映像,而默认情况下 Logging 代理对于此类映像处于停用状态。google-logging-enable 实例元数据键控制 Logging 代理的启用状态,值为 0 时停用代理。要重新启用代理,请移除 google-logging-enable 键或将其值设置为 1。如需了解详情,请参阅创建停用 Logging 代理的实例

      如果未通过元数据停用代理,请重新安装代理。请参阅下文中的重新安装代理部分。

  • 查看代理是否向日志中写入了错误消息。

    • 在 Windows 上,从版本 v1-9 开始,Logging 代理会将其日志保存在 C:\Program Files (x86)\Stackdriver\LoggingAgent\fluentd.log 中。

      无法获取先前版本代理的日志。

    • 在 Linux 上,Logging 代理是一个 fluentd 软件包,其消息会记录到 /var/log/google-fluentd/google-fluentd.log 中:

      • 如果您看到 HTTP 429 错误,则您的 Logging API 配额可能已经用完。您可以通过在 Google Cloud 控制台中选择 API 和服务 > 信息中心来查看可用配额。选择 Logging API。

      • 如果您遇到 API 访问或授权问题,请转到验证 Compute Engine 凭据

  • 如果代理似乎运行正常,但您没有收到数据,则应检查代理是否正在向正确的项目发送数据。请参阅下面的验证 Compute Engine 凭据部分。

  • 如果代理授权失败,请检查私钥的凭据是否缺失或无效

验证代理安装

要检查安装是否成功,请在日志浏览器中查找该代理的测试日志条目。

  1. 在 Google Cloud 控制台的导航面板中,选择 Logging,然后选择 Logs Explorer

    前往 Logs Explorer

  2. 在页面顶部,选择包含您的虚拟机实例的项目:

    • Compute Engine 虚拟机实例部分,选择包含虚拟机实例的 Google Cloud 项目。
    • 对于 Amazon EC2 虚拟机实例,请选择将您的 AWS 账号关联到 Google Cloud 服务的 AWS 连接器项目
  3. Windows 标签 (windows tabs) 中,为您的虚拟机实例选择相应资源:

    • 对于 Compute Engine,请选择 GCE 虚拟机实例
    • 对于 Amazon EC2,请选择 AWS EC2 实例 (AWS EC2 Instance)。
    • 选择 syslog (Linux)、fluent.info (Windows) 或所有日志

如果您看到“gRPC 成功发送到了 Logging API”(Successfully sent gRPC to Logging API) 日志条目,则表明代理安装已完成。代理每次安装及每次重启后,此消息都会生成一次。

如需详细了解日志浏览器,请参阅使用日志浏览器

测试代理

如果您怀疑代理未正常工作,请检查代理是否正在运行并尝试向 Logging 发送测试消息:

Linux 实例

以下步骤适用于运行 Linux 的 Compute Engine 和 Amazon EC2 虚拟机实例:

  1. 在您的虚拟机实例执行以下命令,以验证 Logging 代理是否正在运行:

    ps ax | grep fluentd
    

    您将看到类似如下所示的输出:

     2284 ?        Sl     0:00 /opt/google-fluentd/embedded/bin/ruby /usr/sbin/google-fluentd [...]
     2287 ?        Sl    42:44 /opt/google-fluentd/embedded/bin/ruby /usr/sbin/google-fluentd [...]
    
  2. 在您的虚拟机实例上运行以下命令,以发送测试日志消息:

    logger "Some test message"
    

Windows 实例

Logging 代理具有两个 Windows 服务名称:

  • StackdriverLogging,用于 v1-5 及更高版本
  • fluentdwinsvc,用于早期版本

您应该正在运行一项代理服务。使用 PowerShell 在虚拟机实例上运行以下命令:

  1. 询问两项服务的状态。如果您知道应运行哪项服务,则使用相应服务名称即可:

    Get-Service StackdriverLogging,fluentdwinsvc
    
  2. 如果服务未运行,您将看到一条错误消息。如果服务正在运行,您将看到类似如下所示的输出:

    Status    Name                DisplayName
    ------    ----                -----------
    Running  StackdriverLogging   Cloud Logging
    
  3. 如果您同时查询这两项服务,应该会看到一条错误消息和 Running 状态:

    • 如果未显示任何 Running 状态,则 Logging 代理未运行。
    • 如果看到 StackdriverLogging 正在运行,那么您正在运行的是近期的代理版本。要确定具体的版本,请参阅获取版本
    • 如果看到 fluentdwinsvc 正在运行,应将代理升级到最新版本。
  4. 需要管理员权限:如果有任意版本的代理正在运行,请运行以下 PowerShell 命令,以发送测试日志消息:

    New-EventLog   -LogName Application -Source "Test Source"
    Write-EventLog -LogName Application -Source "Test Source" -EntryType Information -EventID 1 -Message "Testing 123 Testing."
    

查找测试消息

发送测试消息后,请在日志浏览器中查找该消息:

  1. 在 Google Cloud 控制台的导航面板中,选择 Logging,然后选择 Logs Explorer

    前往 Logs Explorer

  2. 在页面顶部,选择包含您的虚拟机实例的项目:

    • Compute Engine 虚拟机实例部分,选择包含虚拟机实例的 Google Cloud 项目。
    • 对于 Amazon EC2 虚拟机实例,请选择将您的 AWS 账号关联到 Google Cloud 服务的 AWS 连接器项目
  3. Windows 标签 (windows tabs) 中,为您的虚拟机实例选择相应资源:

    • 对于 Compute Engine,请选择 GCE 虚拟机实例
    • 对于 Amazon EC2,请选择 AWS EC2 实例 (AWS EC2 Instance)。
    • 选择 syslog (Linux)、fluent.info (Windows) 或所有日志
  4. 您应该会看到包含测试消息的日志条目。如果是这样,则表示 Logging 代理运行正常。

验证 Compute Engine 凭据

要使 Compute Engine 虚拟机实例在没有私钥凭据的情况下运行代理,该实例必须具有合适的访问权限范围,并且该实例使用的服务账号身份必须具有合适的 IAM 权限。

创建虚拟机实例时,默认范围和服务账号设置足以运行代理。非常旧的实例或默认设置已更改的实例可能没有合适的凭据。

加载默认凭据失败

如果 Logging 日志文件中有 Could not load the default credentials 故障,则表示代理可能无法连接到 Compute Engine 元数据服务器。

错误日志如下所示:

Starting google-fluentd 1.8.4: /opt/google-fluentd/embedded/lib/ruby/gems/2.6.0/gems/googleauth-0.9.0/lib/googleauth/application_default.rb:74:in `get_application_default': Could not load the default credentials. Browse to (RuntimeError) https://developers.google.com/accounts/docs/application-default-credentials for more information.

出现这种情况的可能原因之一是虚拟机具有自定义代理设置。如需解决此问题,请参阅代理设置说明 对 Compute Engine 元数据服务器(metadata.google.internal169.254.169.254)进行排除设置,使其不通过代理。如果错误仍然存在,请从虚拟机中移除默认的 Compute Engine 服务账号,然后重新添加。

验证访问权限范围

要验证访问权限范围,请执行以下操作:

  1. 在 Google Cloud 控制台的导航面板中,选择 Compute Engine,然后选择虚拟机实例

    前往虚拟机实例

  2. 点击虚拟机实例的名称。系统会显示实例的详情页面。

  3. Cloud API 访问权限范围部分中,点击详细信息以查看 API 列表。注意查找以下条目:

    1. 如果看到“此实例拥有所有 Google Cloud 服务的完整 API 访问权限”,则表明您拥有足够的访问权限范围。
    2. 如果在 Stackdriver Logging API(Cloud Logging API 的旧名称)旁边看到您拥有只写全部权限,则实例的访问范围足以运行 Cloud Logging 代理。
    3. 如果您在 Stackdriver Monitoring API(Cloud Monitoring API 的旧名称)旁边看到您拥有只写全部权限,则实例的访问范围足以运行 Cloud Monitoring 代理。

纠正问题

如果您的 Compute Engine 实例中没有合适的访问权限范围,请为实例添加所需的访问权限范围

下表展示了与 Logging 和 Monitoring 代理相关的访问权限范围:

访问权限范围 代理权限
https://www.googleapis.com/auth/logging.write 足以运行 Logging 代理
https://www.googleapis.com/auth/monitoring.write 足以运行 Monitoring 代理

验证默认服务账号权限

即使 Compute Engine 虚拟机实例具有足够的访问权限范围,实例的默认服务账号仍可能无法为代理提供适当的 IAM 权限。

要验证默认服务账号权限,请先找到默认服务账号:

  1. 在 Google Cloud 控制台的导航面板中,选择 Compute Engine,然后选择虚拟机实例

    前往虚拟机实例

  2. 点击虚拟机实例的名称。系统会显示实例的详情页面。

  3. 在页面上查找服务账号标题。该标题下会列出实例的默认服务账号。服务账号可能如下所示:

    [ID]-compute@developer.gserviceaccount.com
    
  4. 在 Google Cloud 控制台的导航面板中,选择 IAM

    前往 IAM

  5. 选择“查看方式:主账号”。您应该会看到人员、群组和服务账号的列表。角色列包含您项目中每个主账号所具有的角色。

  6. 在实例的默认服务账号对应的行中,您应该会看到一个或多个角色:

    • 如果看到 Editor,则说明该角色足以运行所有代理。Editor 是分配给 Compute Engine 服务账号的默认角色。
    • 如果看到日志写入者,则表明该角色足以运行 Logging 代理。要了解包含写入权限的其他 Logging 角色,请参阅 Cloud Logging 的访问权限控制
    • 如果看到监控指标写入者,则表明该角色足以运行 Monitoring 代理。要了解包含写入权限的其他 Monitoring 角色,请参阅 Cloud Monitoring 的访问权限控制

纠正问题

如果您的默认服务账号没有适当的角色,请尝试在 IAM 和管理 > IAM 页面修改服务账号的角色。添加合适的 Logging 或 Monitoring 角色,从而为代理授权:Logging > Logs WriterMonitoring > Monitoring Metric Writer

验证私钥凭据

在 Compute Engine 虚拟机实例上,您可以将代理配置为使用获得适当授权的非默认服务账号。在 AWS EC2 虚拟机实例上,您必须将代理配置为使用此类服务账号。

要以这种方式配置代理,您必须为指定的服务账号创建私钥凭据,并向代理提供这些凭据。

  1. 代理会查找环境变量 GOOGLE_APPLICATION_CREDENTIALS,该变量存有包含私钥凭据的文件的名称。
  2. 如果该环境变量不存在,则代理将在默认位置查找凭据:

    Linux

    /etc/google/auth/application_default_credentials.json
    

    Windows

    C:\ProgramData\Google\Auth\application_default_credentials.json
    
  3. 如果默认位置不包含凭据,则代理将使用元数据服务器中的应用默认凭据。

以下信息有助于您诊断私钥凭据相关问题:

  1. 私钥是否安装到位?
  2. 私钥是否仍对服务账号有效?
  3. 服务账号是否具有代理所需的角色?

要验证虚拟机实例上是否安装了有效的私钥凭据,请首先验证凭据文件是否存在于其预期位置,然后验证凭据文件中的信息是否有效。

凭据是否存在?

要查看您的实例上是否存在私钥服务账号凭据,请在您的实例上运行以下 Linux 命令:

sudo cat $GOOGLE_APPLICATION_CREDENTIALS
sudo cat /etc/google/auth/application_default_credentials.json

如果任一命令显示如下所示的文件,那么您的实例可能具有有效的私钥凭据。如果两个命令都显示文件,则会使用由 GOOGLE_APPLICATION_CREDENTIALS 表示的文件。

{
  "type": "service_account",
  "project_id": "[YOUR-PROJECT-ID]",
  "private_key_id": "[YOUR-PRIVATE-KEY-ID]",
  "private_key": "[YOUR-PRIVATE-KEY]",
  "client_email": "[YOUR-PROJECT-NUMBER]-[YOUR-KEY@DEVELOPER].gserviceaccount.com",
  "client_id": "[YOUR-CLIENT-ID]",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "{x509-cert-url}",
  "client_x509_cert_url": "{client-x509-cert-url}"
}

凭据配置之间的差异可能会导致代理使用的凭据与您的服务所需的凭据不同。例如,如果您在登录 shell 的 GOOGLE_APPLICATION_CREDENTIALS 中设置了自定义凭据位置,但未在代理的服务配置中设置该变量,则服务将查看默认位置而不是您的自定义位置。

如需查看或更改凭据环境变量,请在 /etc/default/google-fluentd 中访问或设置 GOOGLE_APPLICATION_CREDENTIALS

如果不存在凭据文件,请参阅添加凭据

凭据是否有效?

在凭据文件中,project_id 是您的 Google Cloud 项目,client_email 标识项目中的服务账号,private_key_id 则标识服务账号中的私钥。将此信息与 Google Cloud 控制台的 IAM 和管理 > 服务账号部分中显示的内容比对。

如果存在以下任一情况,则凭据文件无效:

  • 您检查的是 Compute Engine 实例,但凭据文件中的 Google Cloud 项目不是包含您的实例的项目。
  • 您检查的是 Amazon EC2 实例,但凭据文件中的 Google Cloud 项目不是您的 AWS 账号的连接器项目(名为 AWS Link...)。
  • 列出的服务账号不存在,可能已被删除。
  • 列出的服务账号没有启用正确的角色:Logs Writer(用于运行 Cloud Logging 代理)和 Monitoring Metric Writer(用于运行 Cloud Monitoring 代理)。
  • 私钥不存在,可能已被撤消。

可以使用 Google Cloud 控制台的 IAM 和管理 > 服务账号部分撤消凭据。如果不存在有效凭据,请参阅添加凭据,以替换现有凭据或添加新凭据。

如果服务账号正确无误,但私钥已被撤消,那么您可以创建一个新的私钥,并将其复制到您的实例上。请参阅创建服务账号密钥

否则,您必须按照添加凭据部分中所述创建新的服务账号。

验证日志排除查询

查看当前的排除项查询,确保您所查找的日志不会被意外排除。

验证防火墙

要查看您的实例是否有权访问 logging.googleapis.com,请在您的实例上运行以下 Linux 命令:

curl -sSL 'https://logging.googleapis.com/$discovery/rest?version=v2' | head

当防火墙屏蔽出站流量时,该命令可能需要一些时间才能完成。指示防火墙问题的示例输出:

curl: (7) Failed to connect to 2607:f8b0:4001:c03::5f: Network is unreachable

如需了解如何设置出站流量的规则,请访问防火墙规则

重新安装代理

安装最新版本的代理可以解决许多问题:

其他常见问题

下表列出了您在使用 Cloud Logging 代理时可能会遇到的一些常见问题,并介绍了相应的解决方法。

在 Linux 上,Logging 代理会将错误记录在 /var/log/google-fluentd/google-fluentd.log 中。在 Windows 上,Logging 代理会将错误记录在 C:\Program Files (x86)\Stackdriver\LoggingAgent\fluentd.log 中(从版本 v1-9 开始)。错误类 Google::APIClient::ClientError 表示权限或 API 访问权限出现问题。

代理成功运行后,您可能会开始看到错误。例如,某人可能已从您的项目或虚拟机实例中撤消必需的权限。

错误 原因 解决方案
Windows 上代理的安装程序无法运行 您可能将此安装程序下载到了某个系统目录。 将安装程序移至非系统目录,例如,C:\Users\[USERID]\
项目尚未启用 API 您尚未在项目中启用 Cloud Logging API。 转到 API 控制台,然后将 Cloud Logging API 的状态更改为开启
请求包含无效凭据

无法获取访问令牌(未配置任何范围?)
您的虚拟机实例没有合适的凭据。如果您使用的是 Amazon EC2,则必须先在虚拟机实例上安装凭据,然后才能安装代理。 请参阅向 Logging 代理授权,以安装凭据。
授权失败 未正确配置 Logging 代理的私钥授权凭据。 请参阅验证私钥凭据
调用方无权限 项目中用于授权的服务账号的权限不足。该服务账号可能是 Compute Engine 或 App Engine 中所用的默认服务账号,也可能是由用户定义的用于私钥授权的服务账号。该账号必须具有 Editor 角色。 在您的项目的 IAM 页面中更改服务账号的权限。如有必要,可以使用更改实例的服务账号和访问范围过程来修改现有虚拟机的访问范围。
无法获取项目 ID Cloud Logging 代理无法从服务账号的私钥凭据文件中获取项目 ID。 要添加或替换代理的项目 ID,请在您的虚拟机实例上修改代理的配置文件 /etc/google-fluentd/google-fluentd.conf。在 <match **> 部分中,添加以下行:
project_id [YOUR_PROJECT_ID]
否则,请参阅向 Logging 代理授权,以修复或替换凭据。
Window Logging 代理停止从某些渠道提取事件日志 Logging 代理在从某些渠道中提取事件日志时可能会毫无征兆地失败,即使 Logging 代理仍在运行并从其他一些渠道提取代理日志和事件日志也是如此。原因在于 windows_eventlog 插件存在此演示文稿中提到的一些问题。使用 windows_eventlog2 可解决此问题。 注意:windows_eventlog2 插件的数据格式并不向后兼容 windows_eventlog 插件。如果针对这些日志设置了任何 BigQuery 或 Google Cloud Storage 导出流水线,则需要进行相应的调整。请参阅 windows_eventlogwindows_eventlog2 提供的这一日志条目比较。要使用 windows_eventlog2,您必须先停止 Logging 代理,然后将配置文件替换为类似于此示例配置文件的文件。最后,启动 Logging 代理。
如果存在日志轮替,Logging 代理会停止提取日志 当使用 copytruncate 设置来设置日志轮替时,Logging 代理可能会无法跟踪其在输入文件中的位置。 最好使用 nocopytruncate 设置来确保日志轮替移动文件而不是截断文件。如果要保留 copytruncate 设置,则解决方法是定期重启代理。或者,您可以使用 postrotate 设置重启代理。
error_class=Errno::EADDRINUSE error="Address already in use - bind(2) for 0.0.0.0:24231" 虚拟机上正在运行多个 Logging 代理实例。 使用 ps -aux | grep "/usr/sbin/google-fluentd" 显示正在运行的代理进程(应该只有两个进程,一个是监管程序进程,另一个是工作器进程),使用 sudo netstat -nltp | grep :24231 显示占用该端口且正在运行的进程。根据需要终止旧实例。
由于 lib/fluent/config/types.rb 出现错误,Logging 代理无法启动 Logging 代理配置使用正则表达式解析器部分,而该部分的正则表达式格式不正确,导致 subexp 调用无效,并且出现类似于 Starting google-fluentd 1.8.6: /opt/google-fluentd/embedded/lib/ruby/gems/2.6.0/gems/fluentd-1.11.2/lib/fluent/config/types.rb:92: warning: invalid subexp call 的错误。 在代理配置文件中找到并修复格式错误的正则表达式。提示:搜索 regexparse

日志吞吐量限制

Logging 代理可以处理的最大日志吞吐量受限于 CPU。当日志吞吐量增加时,CPU 使用率往往也会提高。但是,采用默认配置的代理最多只能使用一个 CPU 核心。因此,当日志吞吐量出现峰值时,代理可能会达到 CPU 使用率限制。如果这些峰值是暂时的,Logging 代理会缓冲日志并赶上进度以最终处理日志。如果高日志吞吐量一直持续,日志可能会溢出缓冲区,并最终丢失。

通常,当每个日志条目为 1000 字节原始文本且不包含额外的格式处理时,Logging 代理会在每秒约 5500 条日志条目时达到单个核心 CPU 限制。如果日志条目需要高级处理(例如 JSON 或正则表达式解析),每秒最大日志条目数可能会低于此值。

如果您需要更高的日志吞吐量,请考虑使用 Ops Agent。在 Linux 上,对于 1000 字节的原始文本且不涉及额外处理的日志条目,Ops Agent 每秒可以处理约 16 万条日志条目。

超出日志大小限制

如果一个或多个日志条目超出大小限制,则您可能会在 fluentd 日志中找到类似于以下内容的条目:

Dropping 1 log message(s) error_class="Google::Apis::ClientError" error="Invalid request"



Dropping 1 log message(s) error="3:Log entry with size 1000515 bytes exceeds maximum size of 112640 bytes" error_code="3"

要解决此错误,请适当删减您的日志条目,使其不超出大小限制。例如,以下示例代码删减带有 mytag 标记的日志中 message 字段中的数据:

# Cloud Logging only supports log entries that are up to 256 KiB in size.
# Trim the entries to just under that size to avoid dropping them.
<filter [MY_TAG]>
  @type record_transformer
  enable_ruby true
  <record>
    message ${record['message'].length > 256000 ? "[Trimmed]#{record['message'][0..256000]}..." : record['message']}
  </record>
</filter>

日志重复

LogEntry.insertID 添加到代理的处理流水线中。如果 insertID 在多个重复日志中不同,则表示日志在日志文件中被多次跟踪。在存在日志轮换,或 pos 文件缺失或损坏时,可能会发生这种情况。为了减少发生此问题的可能性,请确保未将任何 in_tail 输入的位置文件配置为位于 /var/log 文件夹或任何其他可能启用了日志轮换的文件夹中。

日志记录流水线还根据 LogEntry.timestamp 字段来删除重复日志。确保正确解析日志条目的实际时间戳。如未将 Fluentd 设置为从日志条目解析原始时间戳,则 Fluentd 将使用其处理日志条目的时间。因此,如果多次读取输入,即使日志行中的时间戳相同,Fluentd 也可能将其视为具有不同时间戳的不同日志条目。

审核日志重复错误:Data points cannot be written more than 24h in the past

存在一个影响 1.8.5 到 1.9.3(含)版本的已知问题,这会导致如下日志在数据访问审核日志中重复出现(当代理运行超过 24 小时时):

Field timeSeries[0].points[0].interval.end_time had an invalid value of "2021-10-20T20:16:34.010866-07:00": Data points cannot be written more than 24h in the past.

解决方法是将代理升级到 1.9.4 或更高版本。

日志中的 Unicode 字符被替换为空格或“�”

默认情况下,in_tail 输入要求输入文件采用 ASCII 编码,因此它会将任何非 ASCII 字符替换为空格。如需实际注入 UTF-8 编码文件,您需要在 in_tail 配置中提供两个选项:

<source>
  @type tail
  …

  encoding UTF-8
  from_encoding UTF-8
</source>

这两个选项都是必需的。如果仅提供 encoding 选项,则提取日志中的非 ASCII 字符将被替换为“�”。

移除了由 Google Cloud Console 报告为已安装的代理

卸载代理后,Google Cloud 控制台最多可能需要一小时才能报告此更改。

Windows 中未显示 Logging 代理。卸载程序列表

如需在 Windows 控制面板的卸载程序列表中未列出 Logging 代理时将其卸载,请从安装它的目录运行 uninstall.exe