apigee-127 / swagger-tools

A Node.js and browser module that provides tooling around Swagger.
MIT License
702 stars 373 forks source link

Doesn't play well with New Relic #501

Closed rws-github closed 7 years ago

rws-github commented 7 years ago

All my web transactions are logged as being against /

whitlockjc commented 7 years ago

I don't have enough information to help. Please elaborate and I'll do my best to help.

rws-github commented 7 years ago

My server routing looks like this:

// status and version do not require auth
app.get('/api/v1/status', status)
app.get('/api/v1/version', version)

swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) {
  app.use(bodyParser.urlencoded({ limit: config.jsonLimit, extended: false }))
  app.use(bodyParser.text({ limit: config.jsonLimit }))
  app.use(bodyParser.json({ limit: config.jsonLimit }))

  // Interpret Swagger resources and attach metadata to request - must be first in swagger-tools middleware chain
  app.use(middleware.swaggerMetadata())

  // Serve the Swagger documents and Swagger UI
  app.use(middleware.swaggerUi())

  // enforce auth
  if (config.useAuth) {
    app.use(security, ssl)
  }

  // Validate Swagger requests
  app.use(middleware.swaggerValidator())

  // Route validated requests to appropriate controller
  var routerConfig = {
    controllers: './lib/controllers', // path from root of the project
    useStubs: process.env.NODE_ENV === 'development' // Conditionally turn on stubs (mock mode)
  }
  app.use(middleware.swaggerRouter(routerConfig))

  const server = http.createServer(app)
  server.listen(config.port)
})

Our New Relic monitoring using https://www.npmjs.com/package/newrelic only detects incoming requests that go to swagger as GET or PUT against / even though the path may be /api/v1/foo/bar. Is there a way to have swagger tools register each path in the swagger document with express directly?

whitlockjc commented 7 years ago

No because swagger-tools is server-agnostic. Looking at the documentation, it seems that this module inspects the server router to wire itself into the request/response chain. I wonder if you can use this to do what you want.

In the end, I'm not sure how swagger-tools could be modified to support the newrelic package because newrelic is framework-aware while swagger-tools is not (by design). Maybe create an issue in their project and cc me? Maybe we can figure this out.

whitlockjc commented 7 years ago

I'm closing this because as of right now, this is not a problem with swagger-tools. I will continue to support you as we figure this out but until there is a bug, or a reasonable feature request, this should stay closed.

rws-github commented 7 years ago

Thanks for the response. After trial and error, doing this got me the result I was looking for.

  app.use((req, res, next) => {
    if (req.swagger && req.swagger.apiPath) {
      const transaction = newrelic.agent.tracer.getTransaction()
      if (transaction) {
        transaction.nameState.pathStack = ['/', `/api${req.swagger.apiPath}`]
      }
    }
    middleware.swaggerRouter(routerConfig).apply(this, [req, res, next])
  })