Tagging proper GCE Instance name in Stackdriver lo

2019-07-25 07:06发布

I am using Google Compute Engine Instance running on Debian for running a service written in Node.js.

For logging purpose, I am using Stackdriver logging. The logs are getting generated, however, The log entries are not getting filtered under proper GCE Instance name. Here's how the resource flags are in a log entry

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

The instance id is getting generated as a numeric id, but the name of the instance is not generated inside the resource labels, thus, I have to check for numeric id after selecting GCE Instance in Stackdriver and it doesn't come under the name of the instance. Also if I select the instance and click on the View logs option, it set the stackdriver flag filter for the instance name, not the instance id, thus I don't get proper logs too. The name parameter is not getting generated automatically. Here's what it should be

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

I am not adding any custom labels while writing a log entry, thus I am assuming it should generate automatically.

Here's my logging service code.

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);
}

Here's how I call it -

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

So, is there any way to auto-generate the instance name in the resource flag while logging to Stackdriver?

3条回答
太酷不给撩
2楼-- · 2019-07-25 07:50
  1. In terms of finding the logs where instance name is available, trying the following advanced filter helps:

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

For my instance, it showed:

resource: { id: "numeric instance-id" name: "instance-name" type: "instance" zone: "us-central1-a' }

  1. On "is there any way to auto-generate the instance name", if you're looking at the jsonpayload that is where configuration can happen. But looking at resource.labels, you'll find those three only (instance_id, project_id, zone).
查看更多
够拽才男人
3楼-- · 2019-07-25 07:55

I guess you want to curl http://metadata.google.internal like this (code in 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
查看更多
Explosion°爆炸
4楼-- · 2019-07-25 08:08

By default, there's just instance_id and project_id available for resource flag. I have raised an issue on their Github repo to add instance name also there.

This is the code they have when setting resource flag automatically when the code runs on GCE instance.

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

However, until they add the resource flag, there're two options to do it. We can either use the REST API directly using curl command (or request module in Node.js) as mentioned by 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"

Or we can use the NPM package gcp-metadata to get the data easily using node.js. Internally, the Stackdriver node.js client also uses the same package. Here's how I got the instance name using gcp-metadata

const gcpMetadata = require('gcp-metadata');
const res = await gcpMetadata.instance('name');
const instance_name = res.data;

The available properties for the instances are -

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

Please check the documentation for explanation of all the metadata available properties.

Just to keep in mind that both the curl method and the gcp-metadata package will work when running in a compute engine instance. So it won't run in the local machine.

I will update the answer, as soon as the Github issue is resolved in any of the upcoming versions.

查看更多
登录 后发表回答