Skip to content

add tracer.trace() and tracer.wrap() as high level APIs#457

Merged
rochdev merged 6 commits into
v0.10.0from
tracer-trace-wrap
Feb 26, 2019
Merged

add tracer.trace() and tracer.wrap() as high level APIs#457
rochdev merged 6 commits into
v0.10.0from
tracer-trace-wrap

Conversation

@rochdev

@rochdev rochdev commented Feb 22, 2019

Copy link
Copy Markdown
Member

This PR adds a tracer.trace() and tracer.wrap() as high level APIs to make it easier to do manual instrumentation without having to manage the span and scope lifecycle manually.

For example, the following are equivalent:

tracer.trace()
tracer.trace('web.request', () => {
  // some code
})
const childOf = tracer.scope().active()
const span = tracer.startSpan('test', { childOf })

try {
  tracer.scope().activate(span, () => {
    // some code
  })
} catch (e) {
  span.addTags({
    'error.type': e.name,
    'error.msg': e.message,
    'error.stack': e.stack,
  })

  throw e
} finally {
  span.finish()
}
tracer.wrap()
const fn = tracer.wrap('web.request', () => {
  // some code
})
const childOf = tracer.scope().active()
const span = tracer.startSpan('test', { childOf })

const fn = tracer.scope().bind(() => {
  try {
    // some code
  } catch (e) {
    span.addTags({
      'error.type': e.name,
      'error.msg': e.message,
      'error.stack': e.stack,
    })

    throw e
  } finally {
    span.finish()
  }
}, span)

It also allows to wait for a promise to be resolved or a callback to be called before finishing the span, which makes it a lot simpler to manually instrument asynchronous operations.

For example, the following are equivalent for wrapping a function that returns a promise:

const fn = tracer.wrap('web.request', () => {
  return new Promise((resolve, reject) => {
    // some code
  })
})
const childOf = tracer.scope().active()
const span = tracer.startSpan('test', { childOf })

const fn = tracer.scope().bind(() => {
  const promise = new Promise((resolve, reject) => {
    // some code
  })

  promise
    .then(() => span.finish()
    .catch(err => {
      span.addTags({
        'error.type': err.name,
        'error.msg': err.message,
        'error.stack': err.stack,
      })
      span.finish()
    })

  return promise
}, span)

@gbbr gbbr left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As requested, left some nits. I think this is great to have such thorough documentation making it crystal clear what's happening.

Comment thread docs/index.d.ts Outdated
Comment thread docs/index.d.ts Outdated
@gbbr

gbbr commented Feb 26, 2019

Copy link
Copy Markdown

👍

@rochdev

rochdev commented Feb 26, 2019

Copy link
Copy Markdown
Member Author

One thing I'm not sure is what should the default resource name be? Right now it's the default from the tracer.

@brettlangdon Thoughts? tracer.trace is equivalent to tracer.trace in Ruby and tracer.wrap is equivalent to tracer.wrap in Python.

@brettlangdon

Copy link
Copy Markdown
Member

@rochdev in dd-trace-py we default the resource name to operation name if resource name was not provided.

@rochdev

rochdev commented Feb 26, 2019

Copy link
Copy Markdown
Member Author

@brettlangdon This is the same right now as it's the tracer default, but I was wondering if we could use a smarter default for tracer.trace.

@brettlangdon

Copy link
Copy Markdown
Member

Yeah, that is at least consistent with the other tracers, not sure we need to try and be fancy here.

Comment thread src/tracer.js

@brettlangdon brettlangdon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, I like it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants