Search code examples
node.jsgoogle-cloud-platformgoogle-api-nodejs-clientstackdrivergoogle-cloud-stackdriver

Tagging proper GCE Instance name in Stackdriver logging


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?


Solution

  • 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.