Golang与Swagger集成New Relic的实践指南

Golang与Swagger集成New Relic的实践指南 你好,我是 New Relic 的新手。我使用了 Go Swagger 规范来搭建我的服务器并实现业务逻辑。我需要将 New Relic 集成到其中,但我不确定如何将 New Relic 包装到 Go 的处理器(handlers)里。是否有更好、更高效的方法来实现?我需要的只是在 New Relic 仪表板上对我的服务器进行监控和追踪(APM)。

1 回复

更多关于Golang与Swagger集成New Relic的实践指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go-Swagger项目中集成New Relic APM,可以通过中间件包装处理器来实现。以下是具体实现方案:

1. 安装New Relic Go Agent

go get github.com/newrelic/go-agent/v3/newrelic

2. 创建New Relic中间件

package middleware

import (
    "net/http"
    
    "github.com/go-openapi/runtime/middleware"
    "github.com/newrelic/go-agent/v3/newrelic"
)

// NewRelicMiddleware 包装swagger处理器
func NewRelicMiddleware(app *newrelic.Application, handler http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        txn := app.StartTransaction(r.Method + " " + r.URL.Path)
        defer txn.End()
        
        // 将事务注入上下文
        r = newrelic.RequestWithTransactionContext(r, txn)
        
        // 包装ResponseWriter以捕获状态码
        rw := newrelic.NewResponseWriter(w)
        
        // 调用原始处理器
        handler.ServeHTTP(rw, r)
        
        // 设置事务名称和状态码
        txn.SetName(r.Method + " " + r.URL.Path)
        txn.SetWebResponse(rw)
        txn.AddAttribute("http.statusCode", rw.StatusCode())
    })
}

// WrapSwaggerHandler 包装swagger生成的处理器
func WrapSwaggerHandler(app *newrelic.Application, handler middleware.Builder) http.Handler {
    return NewRelicMiddleware(app, handler)
}

3. 在主函数中初始化并集成

package main

import (
    "log"
    "os"
    
    "github.com/newrelic/go-agent/v3/newrelic"
    "your-project/restapi"
    "your-project/restapi/operations"
    "your-project/middleware"
)

func main() {
    // 初始化New Relic应用
    app, err := newrelic.NewApplication(
        newrelic.ConfigAppName("Your-Go-Swagger-App"),
        newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
        newrelic.ConfigDistributedTracerEnabled(true),
    )
    if err != nil {
        log.Fatal(err)
    }
    
    // 创建swagger API
    api := operations.NewYourAPI(swagger.FileJSON("swagger.json"))
    
    // 配置API处理器
    api.ServeError = middleware.ServeError
    api.Logger = log.Printf
    
    // 获取swagger处理器
    handler := api.Serve(nil)
    
    // 包装处理器
    wrappedHandler := middleware.WrapSwaggerHandler(app, handler)
    
    // 启动服务器
    log.Fatal(http.ListenAndServe(":8080", wrappedHandler))
}

4. 针对特定路由的监控

// 为特定操作添加自定义事务
func configureAPI(api *operations.YourAPI, app *newrelic.Application) {
    // 包装特定处理器
    api.GetUserHandler = operations.GetUserHandlerFunc(
        func(params operations.GetUserParams) middleware.Responder {
            // 获取当前事务
            txn := newrelic.FromContext(params.HTTPRequest.Context())
            if txn != nil {
                txn.AddAttribute("userID", params.UserID)
                txn.SetName("GetUser/" + params.UserID)
            }
            
            // 业务逻辑
            user, err := getUser(params.UserID)
            if err != nil {
                return operations.NewGetUserDefault(500)
            }
            
            return operations.NewGetUserOK().WithPayload(user)
        },
    )
}

5. 添加数据库查询监控

import (
    "database/sql"
    
    _ "github.com/newrelic/go-agent/v3/integrations/nrmysql"
    // 或使用其他数据库驱动
    // _ "github.com/newrelic/go-agent/v3/integrations/nrpq"
)

func initDB(app *newrelic.Application) *sql.DB {
    // 使用New Relic包装的数据库驱动
    db, err := sql.Open("nrmysql", "user:password@/dbname")
    if err != nil {
        log.Fatal(err)
    }
    
    return db
}

6. 环境变量配置

export NEW_RELIC_LICENSE_KEY=your_license_key_here
export NEW_RELIC_APP_NAME="Your-Go-Swagger-App"
export NEW_RELIC_LOG=stdout
export NEW_RELIC_DISTRIBUTED_TRACING_ENABLED=true

这个实现方案通过中间件包装所有HTTP处理器,自动捕获请求/响应数据。New Relic仪表板将显示:

  • 请求响应时间
  • 吞吐量
  • 错误率
  • 数据库查询性能
  • 分布式追踪信息

确保在部署前设置正确的New Relic许可证密钥和环境变量。

回到顶部