在 Stackdriver 日志记录中标记正确的 GCE 实例名称

Tagging proper GCE Instance name in Stackdriver logging

我在 Debian 上使用 Google Compute Engine 实例 运行 用于 运行 用 Node.js.

编写的服务

出于日志记录的目的,我正在使用 Stackdriver 日志记录。正在生成日志,但是,日志条目未在正确的 GCE 实例名称下过滤。这是资源标志在日志条目中的方式

resource: {
  labels: {
   instance_id:  "6000000000000000000" //A numeric id
   project_id:  "my-project"
   zone:  ""
  }
  type:  "gce_instance"   
 }

实例 ID 生成为数字 ID,但实例名称未在资源标签内生成,因此,我必须在 Stackdriver 中 selecting GCE 实例后检查数字 ID并且它不属于实例的名称。此外,如果我 select 实例并单击“查看日志”选项,它会为实例名称而不是实例 ID 设置 stackdriver 标志过滤器,因此我也无法获得正确的日志。名称参数不会自动生成。这是应该的

resource: {
  labels: {
   instance_id:  "6000000000000000000" //A numeric id
   name: "instance-name"
   project_id:  "my-project"
   zone:  ""
  }
  type:  "gce_instance"   
 }

我在写日志条目时没有添加任何自定义标签,因此我假设它应该自动生成。

这是我的日志服务代码。

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

function write(data) {
  const logging = new Logging();
  const logObj = logging.log('my-service');
  const logData = data.logData;
  const logText = data.logText;
  const severity = data.severity || 'DEFAULT';
  const httpRequest = data.httpRequest;

  // The metadata associated with the entry
  const metadata = {
    severity: severity,
    httpRequest: httpRequest
  };

  const logPayload = {
    text: logText,
    data: logData
  };

  // Prepares a log entry
  const entry = logObj.entry(metadata, logPayload);
  await logObj.write(entry);
}

我是这样称呼它的 -

loggingService.write({
  httpRequest: httpRequest,
  logText: 'Text Data',
  logData: logDataDump.dump,
  severity: loggingService.DEBUG
});

那么,有什么方法可以在登录 Stackdriver 时在资源标志中自动生成实例名称吗?

我猜你想像这样卷曲 http://metadata.google.internal(Ruby 中的代码):

machine = if Google::Cloud.env.compute_engine?
  [ "gce_instance", {
    "instance_id" => `curl http://metadata.google.internal/computeMetadata/v1/instance/id -H "Metadata-Flavor: Google"`,
    "zone" => `curl http://metadata.google.internal/computeMetadata/v1/instance/zone -H "Metadata-Flavor: Google"`.split("/").last,
  } ]
else
  "global"
end
  1. 就查找实例名称可用的日志而言,尝试以下高级过滤器会有所帮助:

resource.type="gce_instance" jsonPayload.resource.name="my_instance"

以我为例,它显示:

资源:{ 编号:"numeric instance-id" 姓名:"instance-name" 类型:"instance" 区域:“us-central1-a” }

  1. 在 "is there any way to auto-generate the instance name",如果您正在查看 jsonpayload 这就是 configuration 可能发生的地方。但是查看 resource.labels,您只会发现这三个 (instance_id、project_id、zone)。

默认情况下,只有 instance_id 和 project_id 可用于资源标志。我在他们的 Github 回购协议中有 raised an issue 也可以在那里添加实例名称。

这是当 GCE 实例上的代码 运行s 时自动设置资源标志时的代码。

Metadata.getGCEDescriptor = function(callback) {
  gcpMetadata
    .instance('id')
    .then(function(resp) {
      callback(null, {
        type: 'gce_instance',
        labels: {
          instance_id: resp.data,
        },
      });
    })
    .catch(callback);
};

但是,在他们添加资源标志之前,有两种选择。我们可以直接使用 curl 命令(或 Node.js 中的请求模块)使用 REST API,如 Nakilon in their answer as follows (Documentation 所述)-

instace_id = curl http://metadata.google.internal/computeMetadata/v1/instance/id -H "Metadata-Flavor: Google"
zone = curl http://metadata.google.internal/computeMetadata/v1/instance/zone -H "Metadata-Flavor: Google"
instance_name = curl http://metadata.google.internal/computeMetadata/v1/instance/name -H "Metadata-Flavor: Google"

或者我们可以使用 NPM 包 gcp-metadata 来使用 node.js 轻松获取数据。在内部,Stackdriver node.js 客户端也使用相同的包。下面是我如何使用 gcp-metadata

获取实例名称
const gcpMetadata = require('gcp-metadata');
const res = await gcpMetadata.instance('name');
const instance_name = res.data;

实例的可用属性是 -

attributes/
cpu-platform
description
disks/
hostname
id
image
licenses/
machine-type
maintenance-event
name
network-interfaces/
preempted
remaining-cpu-time
scheduling/
service-accounts/
tags
virtual-clock/
zone

请查看 documentation 以了解所有元数据可用属性的说明。

请记住,在计算引擎实例中 运行ning 时,curl 方法和 gcp-metadata 包都可以使用。所以它不会 运行 在本地机器上。

一旦 Github 问题在任何即将发布的版本中得到解决,我将更新答案。