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

时间:2018-06-18 13:17:56

标签: node.js google-cloud-platform google-api-nodejs-client stackdriver google-cloud-stackdriver

我正在使用在Debian上运行的Google Compute Engine Instance来运行用Node.js编写的服务。

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

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

实例id是作为数字ID生成的,但是实例的名称不是在资源标签内生成的,因此,我必须在Stackdriver中选择GCE Instance后检查数字ID并且它不属于实例的名称。此外,如果我选择实例并单击View logs选项,它会为实例名称而不是实例ID设置stackdriver标志过滤器,因此我也没有获得正确的日志。 name参数未自动生成。这是它应该是什么

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时在资源标志中自动生成实例名称?

3 个答案:

答案 0 :(得分:1)

我猜您想像这样卷曲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 :(得分:1)

默认情况下,只有instance_id和project_id可用于资源标志。我在他们的Github存储库上有raised an issue,也在那里添加了实例名称。

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

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在其答案中提到的那样(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以获得所有元数据可用属性的说明。

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

在任何即将发布的版本中解决Github问题后,我都会更新答案。

答案 2 :(得分:0)

  1. 就查找实例名称可用的日志而言,尝试使用以下高级过滤器将有所帮助:

resource.type =“ gce_instance” jsonPayload.resource.name =“ my_instance”

对于我的实例,它显示:

资源:{   id:“数字实例ID”   名称:“实例名称”   类型:“实例”   区域:“ us-central1-a' }

  1. 如果您正在查看jsonpayload,则“是否有任何方法可以自动生成实例名称” 这就是configuration可能发生的地方。但是查看resource.labels,您只会发现这三个(instance_id,project_id,区域)。