census-instrumentation / opencensus-node

A stats collection and distributed tracing framework
https://opencensus.io
Apache License 2.0
273 stars 96 forks source link

Can't get custom tags populated as labels in Stackdriver UI #430

Closed mluggy closed 5 years ago

mluggy commented 5 years ago

What version of OpenCensus are you using?

0.0.9

What version of Node are you using?

10.15.3

What did you do?

Run the repl sample as-is against Stackdriver .

What did you expect to see?

The method, status and error tags appearing as labels with their values populated, filterable and groupable on the Stackdriver UI.

What did you see instead?

The labels were there but they were missing values. Only the automatic "opencensus_task" had values.

Additional context

const { globalStats, MeasureUnit, AggregationType, TagMap } = require('@opencensus/core')

const fs = require('fs')
const readline = require('readline')

// Enable OpenCensus exporters to export metrics to Prometheus Monitoring.
const { StackdriverStatsExporter } = require('@opencensus/exporter-stackdriver')

const exporter = new StackdriverStatsExporter({
  projectId: 'myProject',
  keyFilename: 'myCredentialsFile'
})

// Pass the created exporter to global Stats
globalStats.registerExporter(exporter)

// The latency in milliseconds
const mLatencyMs = globalStats.createMeasureDouble('repl/latency', MeasureUnit.MS, 'The latency in milliseconds per REPL loop')

// Counts/groups the lengths of lines read in.
const mLineLengths = globalStats.createMeasureInt64('repl/line_lengths', MeasureUnit.BYTE, 'The distribution of line lengths')

// Creates a stream to read our file
const stream = fs.createReadStream('./test.txt')

// Creates an interface to read and process our file line by line
const lineReader = readline.createInterface({ input: stream })

const methodTagKey = { name: 'method' }
const statusTagKey = { name: 'status' }
const errorTagKey = { name: 'error' }

// Create and Register the view.
const latencyView = globalStats.createView(
  'demo/latency',
  mLatencyMs,
  AggregationType.DISTRIBUTION,
  [methodTagKey, statusTagKey, errorTagKey],
  'The distribution of the latencies',
  // Bucket Boundaries:
  // [>=0ms, >=25ms, >=50ms, >=75ms, >=100ms, >=200ms, >=400ms, >=600ms, >=800ms, >=1s, >=2s, >=4s, >=6s]
  [0, 25, 50, 75, 100, 200, 400, 600, 800, 1000, 2000, 4000, 6000]
)
globalStats.registerView(latencyView)

// Create and Register the view.
const lineCountView = globalStats.createView(
  'demo/lines_in',
  mLineLengths,
  AggregationType.COUNT,
  [methodTagKey, statusTagKey],
  'The number of lines from standard input'
)
globalStats.registerView(lineCountView)

// Create and Register the view.
const lineLengthView = globalStats.createView(
  'demo/line_lengths',
  mLineLengths,
  AggregationType.DISTRIBUTION,
  [methodTagKey, statusTagKey],
  'Groups the lengths of keys in buckets',
  // Bucket Boudaries:
  // [>=0B, >=5B, >=10B, >=15B, >=20B, >=40B, >=60B, >=80, >=100B, >=200B, >=400, >=600, >=800, >=1000]
  [0, 5, 10, 15, 20, 40, 60, 80, 100, 200, 400, 600, 800, 1000]
)
globalStats.registerView(lineLengthView)

// The begining of our REPL loop
let startTime = new Date()
let endTime
// REPL is the read, evaluate, print and loop
lineReader.on('line', function (line) { // Read
  // Registers the Tags for our measurements
  const tags = new TagMap()
  tags.set(methodTagKey, { value: 'REPL' })
  tags.set(statusTagKey, { value: 'OK' })

  try {
    const processedLine = processLine(line) // Evaluate
    console.log(processedLine) // Print

    console.log([{
      measure: mLineLengths,
      value: processedLine.length
    }, {
      measure: mLatencyMs,
      value: (new Date()) - startTime.getTime()
    }], tags)

    globalStats.record([{
      measure: mLineLengths,
      value: processedLine.length
    }, {
      measure: mLatencyMs,
      value: (new Date()) - startTime.getTime()
    }], tags)
  } catch (err) {
    const errTags = new TagMap()
    errTags.set(methodTagKey, { value: 'REPL' })
    errTags.set(statusTagKey, { value: 'ERROR' })
    errTags.set(errorTagKey, { value: err.message })

    globalStats.record([{
      measure: mLatencyMs,
      value: (new Date()) - startTime.getTime()
    }], errTags)
  }

  // Restarts the start time for the REPL
  startTime = new Date()
})

/**
 * Takes a line and process it.
 * @param {string} line The line to process
 */
function processLine (line) {
  // Currently, it just capitalizes it.
  return line.toUpperCase()
}
mayurkale22 commented 5 years ago

Thanks for filling the issue. I ran the shared example (only changed the projectId). This is what I see on stackdriver UI.

Screen Shot 2019-03-18 at 5 44 47 PM Screen Shot 2019-03-18 at 5 45 17 PM

However, one thing is weird, In filter option once I select the label (for example: Method) I don't see corresponding values (auto populated) there. I have to manually enter the value (in this case "REPL") to apply the filter.

mluggy commented 5 years ago

thanks, so this has to be a problem on Stackdriver UI or a delay populating the suggestion list.

Somehow related - do you know how to populate a description for the labels? the opencensus_task seems to have it but the others don't. I tried this:

const methodTagKey = { name: 'method', description: 'Method description' }
mayurkale22 commented 5 years ago

so this has to be a problem on Stackdriver UI or a delay populating the suggestion list.

There are some delay for populating the suggestion list. Now I see values in the list.

Screen Shot 2019-03-19 at 12 30 07 PM

Do you know how to populate a description for the labels? the opencensus_task seems to have it but the others don't. I tried this:

Currently TagKey interface does not allow you to add custom description for the keys. If you use Gauge API (with LabelKey interface) which has an option to set description field.

In case of default opencensus_task label, we have separate logic to add the desciption. https://github.com/census-instrumentation/opencensus-node/blob/1c0d0b5bc6495babe6f896ae47b230f0430b80a9/packages/opencensus-exporter-stackdriver/src/stackdriver-monitoring-utils.ts#L124-L128

I think we should open a separate feature request to add support for description field for TagKey.

jasonvangundy commented 3 years ago

Did you ever get to a root cause with this? I am having the exact same problem. It's been 12-24 hours since the creation of my metric (with status tag applied) and I still do not have any values showing up for status.