我正在 main.go 中创建新的 relic 事务,并且必须将它传递给处理程序,然后传递给 Controller 等等。有没有办法可以全局定义它,然后可以在任何处理程序、 Controller 或数据库事务中访问它?
import(
"github.com/gin-gonic/gin"
newrelic "github.com/newrelic/go-agent"
)
// main.go
func newrelicHandler() (gin.HandlerFunc, newrelic.Application) {
newrelicConfig := newrelic.NewConfig("NEW_RELIC_APP_NAME", "NEW_RELIC_APP_KEY")
app, err := newrelic.NewApplication(newrelicConfig)
if err != nil {
return func(c *gin.Context) {
c.Next()
}, app
}
return func(c *gin.Context) {
txn := app.StartTransaction(c.Request.URL.Path, c.Writer, c.Request)
c.Set("newRelicTransaction", txn)
apm, ok := c.Get("newRelicTransaction")
defer txn.End()
c.Next()
}, app
}
func main() {
r := gin.New()
x, app := newrelicHandler()
r.Use(x)
}
// test/handler.go
func (t *TestHandler) Display(c *gin.Context) {
apmTxn, ok := c.Get("newRelicTransaction")
test, err := t.testCtrl.Display(apmTxn)
if err != nil {
return err
}
c.JSON(http.StatusOK, gin.H{"message": "success"})
}
// test/controller.go
func (t *TestCtrl) Display(txn interface{}) {
apmTxn, ok := txn.(newrelic.Transaction)
if !ok {
fmt.Println("ERR")
}
segment := newrelic.StartSegment(apmTxn, "SomeSegmentName")
// get data
segment.End()
return
}
最佳答案
避免使用全局上下文,而是在入口点创建一个,然后将其作为参数传递给任何需要它的函数。
您可以使用 nrgin
Gin 框架提供的包。
而在 main()
功能
newrelic.NewApplication(cfg)
nrgin.Middleware(app)
传入 newrelic 实例的函数。这将添加 Gin 事务上下文键 - newRelicTransaction
到上下文。 router.Use(nrgin.Middleware(app))
然后,您可以将这个相同的上下文对象传递给可以接受
context.Context
类型参数的其他函数。自 gin.Context
只是实现 context
Go的界面。示例代码
import "github.com/newrelic/go-agent/_integrations/nrgin/v1"
func main() {
cfg := newrelic.NewConfig("Gin App", mustGetEnv("NEW_RELIC_LICENSE_KEY"))
app, err := newrelic.NewApplication(cfg)
if nil != err {
fmt.Println(err)
}
router := gin.Default()
router.Use(nrgin.Middleware(app))
router.GET("/example-get", GetController)
router.Run(":80")
}
func GetController(c *gin.Context) {
if txn := nrgin.Transaction(c); nil != txn {
txn.SetName("custom-name")
}
databaseGet(c)
c.Writer.WriteString("example response...")
}
func databaseGet(c context.Context) {
if txn := nrgin.Transaction(c); nil != txn {
txn.SetName("custom-name")
}
c.Writer.WriteString("example response...")
}
关于go - 如何在golang中为new relic(Golang New relic integration)创建通用或全局上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69523822/