title: Google GCP Trace: Trace with nested user functions information
body: <p>Currently this is the picture I have when analysing GCP trace. It is useful but we need to have a deeper analysis on some spots we want to improve.</p>
  
  <p><a href="https://i.stack.imgur.com/dD5Wr.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/dD5Wr.png" alt="Standard Trace without nested user function info"></a></p>
  
  <p>What we would like to do is to have something like this </p>
  
  <blockquote>
  <pre><code>  | vi/route/r   
       | function abc (75 ms)
         | redis-hget (1 ms)
         | datastore (69 ms)
            | function cde (30 ms)
                | ...
  </code></pre>
  </blockquote>
  
  <p>We have tried a lot but we didn't find further documentation regarding the concepts of GCP trace, rather only detailed API calls.</p>
  
  <p>Here is our POC</p>
  
  <p>Entry Level</p>
  
  <pre><code>require('@google-cloud/trace-agent').start({
      projectId: 'my-project',
      keyFilename: './my-credentials.json',
      stackTraceLimit: 0,
  });
  
  const express = require('express');
  const app = express();
  const bodyParser = require('body-parser');
  
  const toSecondLevel = require('./controllers/home');
  const initController = require('./controllers/init');
  
  app.post('/poc/', bodyParser.json(), async (req, res) =&gt; {
  
      const trace = require('@google-cloud/trace-agent').get()
  
      const rootSpan = trace.getCurrentRootSpan();
      const { requestType } = req.body;
  
      rootSpan.addLabel('Root - First Level' , requestType);
      await toSecondLevel(rootSpan, req, res);
  
      rootSpan.endSpan(new Date());
      res.send('Hello World! ===&gt; ' + requestType);
  });
  
  app.listen(3000, function () {
      console.log('Example app listening on port 3000!');
  });
  </code></pre>
  
  <p>Second Level</p>
  
  <pre><code>const toThirdLevel = require('../services/home')
  
  
  const secondLevelFunction = async (rootSpan, req, res) =&gt; {
  
      await secondLevelFunctionPromise(rootSpan);
  }
  
  
  const secondLevelFunctionPromise = (rootSpan) =&gt; new Promise((resolve, reject) =&gt; {
      const span = rootSpan.createChildSpan({ name: 'secondLevelFunction' });
      setTimeout(async () =&gt; {
          console.log('secondLevelFunction', span.getTraceContext())
          span.addLabel('Should be nested to Root?', 'NOT nested');
          await toThirdLevel(rootSpan, new Date());
  
          span.endSpan(new Date())
          resolve();
      }, 2400);
  })
  
  module.exports = secondLevelFunction;
  </code></pre>
  
  <p>And the third Level</p>
  
  <pre><code>const thirdLevelFunction = (rootSpan, parametro1) =&gt; new Promise((resolve, reject) =&gt; {
      const span = rootSpan.createChildSpan({ name: 'thirdLevelFunction' });
      setTimeout(() =&gt; {
          span.addLabel('thirdLevelFunction', 'not nested as well')
          console.log(span.getTraceContext())
  
          span.endSpan(new Date());
          resolve();
      }, 1392);
  })
  
  module.exports = thirdLevelFunction;
  </code></pre>
  
  <p>The problems / Conceptual questions:</p>
  
  <p>1- No <code>Span</code> is Nested in the POC</p>
  
  <p>2- All the Spans has <code>getTraceContext()</code>. Can I use this to some how nest my Spans?</p>
  
  <p>3- Is it possible to make what I am intending to do? (A- Nest my Span and B- Nest into the same tree showed in the first image?</p>
  
  <p>4- Class RootSpan extends Span. But I can't have any different behaviour from this.  </p>