英文:
Golang, redis transactions and not being show in new relic panel
问题
所以...我已经卡在这个问题上几天了,我按照文档和其他人的建议进行了操作,但似乎没有起作用。我正在使用Golang和GRPC,并将新的遗物引入其中,以跟踪事务和整体性能。我成功地声明了事务和段,但是在数据库事务方面,它们没有出现在数据库部分。我尝试将新的遗物上下文传递给Redis客户端,同时尝试使用后台上下文和当前事务上下文,但似乎没有起作用。查询已经执行,但没有数据被报告。以下是我所拥有的示例:
1 - 执行事务的一个函数
// updateCache ...
func updateCached(data *statemachinepkgv1.StateMachine, sessionID string, ctx context.Context) (*statemachinepkgv1.StateMachine, error) {
// 事务和段逻辑
// 这不会创建一个全新的遗物应用程序,只是获取主实例
relic, err := tools.InitRelic()
if err != nil {
log.Fatalf("failed to create/instace newrelic.NewApplication: %v", err)
}
txn := relic.StartTransaction("redis", nil, nil)
defer newrelic.StartSegment(txn, "updateCached").End()
defer newrelic.StartSegment(tools.CurrentTransaction, "updateCached").End() // tools.CurrentTransaction 存储了具有单例设计的主 Web 事务上下文
defer txn.End()
dataParse, err := json.Marshal(data)
if err != nil {
return data, err
}
duration, err := time.ParseDuration(os.Getenv("GO_STATEMACHINE_REDIS_TIMELIFE"))
if err != nil {
return data, err
}
// REDIS LOGIC
dbTransaction := newrelic.FromContext(ctx)
newRelicContext := newrelic.NewContext(context.Background(), dbTransaction)
err = masterClient.Set(newRelicContext, sessionID, string(dataParse), duration).Err()
if err != nil {
return data, err
}
return data, nil
}
2 - Redis 单例
package tools
import (
"context"
"os"
"github.com/go-redis/redis/v8"
nrredis "github.com/newrelic/go-agent/v3/integrations/nrredis-v8"
newrelic "github.com/newrelic/go-agent/v3/newrelic"
)
var redisOpt = &redis.Options{
Addr: os.Getenv("GO_STATEMACHINE_REDIS_HOST") + ":" + os.Getenv("GO_STATEMACHINE_REDIS_PORT"),
DB: 1,
Password: os.Getenv("GO_STATEMACHINE_REDIS_PASSWORD"),
}
var Client *redis.Client = nil
var Ctx context.Context = nil
func getTransaction() *newrelic.Transaction {
redisTransaction := newrelic.FromContext(context.Background())
return redisTransaction
}
func init() {
Client = redis.NewClient(redisOpt)
Client.AddHook(nrredis.NewHook(redisOpt))
txn := getTransaction()
Ctx = newrelic.NewContext(context.Background(), txn)
}
func GetRedis() (*redis.Client, context.Context) {
if Client == nil {
Client = redis.NewClient(redisOpt)
Client.AddHook(nrredis.NewHook(redisOpt))
txn := getTransaction()
Ctx = newrelic.NewContext(context.Background(), txn)
}
return Client, Ctx
}
3 - 新遗物单例
package tools
import (
"context"
"fmt"
"log"
"os"
newrelic "github.com/newrelic/go-agent"
)
var RelicApplication newrelic.Application = nil
var CurrentTransaction newrelic.Transaction = nil
func init() {
fmt.Println("INIT RELIC CREATING AT RUNTIME")
cfg := newrelic.NewConfig("go-vozyengine-statemachine-service", os.Getenv("NRELIC_KEY"))
cfg.Logger = newrelic.NewDebugLogger(os.Stdout)
cfg.BrowserMonitoring.Attributes.Enabled = true
cfg.TransactionTracer.Enabled = true
cfg.TransactionEvents.Enabled = true
cfg.DistributedTracer.Enabled = true
cfg.CustomInsightsEvents.Enabled = true
cfg.ErrorCollector.Enabled = true
cfg.ErrorCollector.CaptureEvents = true
var err error
RelicApplication, err = newrelic.NewApplication(cfg)
if err != nil {
log.Fatalf("failed to create newrelic.NewApplication: %v", err)
}
fmt.Println("INIT RELIC = RETURNING")
}
func SetSubTransaction(txn newrelic.Transaction) {
// 设置新的当前事务
CurrentTransaction = txn
}
func SetSubTransactionByContext(ctx context.Context) {
fmt.Println("SETTING SUB TRANSACTION VIA CONTEXT - default set")
txn := newrelic.FromContext(ctx)
SetSubTransaction(txn)
}
func InitRelic() (newrelic.Application, error) {
fmt.Println("INIT RELIC REBUG")
if RelicApplication == nil {
fmt.Println("INIT RELIC = NOT INIT CREATING")
cfg := newrelic.NewConfig("go-vozyengine-statemachine-service", "29827623658187f9e25fdde2f2fee06da906NRAL")
cfg.Logger = newrelic.NewDebugLogger(os.Stdout)
cfg.BrowserMonitoring.Attributes.Enabled = true
// Enabling distributed tracing will disable the cross application tracing feature. Distributed tracing is
// an improved version of cross-application tracing and only one can be enabled at a time.
cfg.DistributedTracer.Enabled = true
RelicApplication, err := newrelic.NewApplication(cfg)
if err != nil {
log.Fatalf("failed to create newrelic.NewApplication: %v", err)
}
fmt.Println("INIT RELIC = RETURNING")
return RelicApplication, err
} else {
fmt.Println("INIT RELIC = ALREADY INIT RETURNING")
return RelicApplication, nil
}
}
非常感谢您的帮助!
英文:
So... I've been stuck on this for a couple of days now, I have followed the documentation and pears advice but does not seem to work, I'm using Golang with GRPC and implementing a new relic into it, to track transactions and overall performance, I manage to declare transaction and segments, but as far as database transactions the are not appearing in the database section, I have tried to pass the new relic context into the Redis client in the moment I do the transaction, also tried with background context, and the current transaction context, but does not seem to work. the queries are made but no data is being reported
here's an example of what I have
1 - one of the functions that do transactions
// updateCache ...
func updateCached(data *statemachinepkgv1.StateMachine, sessionID string, ctx context.Context) (*statemachinepkgv1.StateMachine, error) {
//Transaction and segment logic
//this does not create a brand new relic application, just gets the main instance
relic, err := tools.InitRelic()
if err != nil {
log.Fatalf("failed to create/instace newrelic.NewApplication: %v", err)
}
txn := relic.StartTransaction("redis", nil, nil)
defer newrelic.StartSegment(txn, "updateCached").End()
defer newrelic.StartSegment(tools.CurrentTransaction, "updateCached").End() //tools.CurrentTransaction has the context of main web transaction stored with singleton design
defer txn.End()
dataParse, err := json.Marshal(data)
if err != nil {
return data, err
}
duration, err := time.ParseDuration(os.Getenv("GO_STATEMACHINE_REDIS_TIMELIFE"))
if err != nil {
return data, err
}
//REDIS LOGIC
dbTransaction := newrelic.FromContext(ctx)
newRelicContext := newrelic.NewContext(context.Background(), dbTransaction)
err = masterClient.Set(newRelicContext, sessionID, string(dataParse), duration).Err()
if err != nil {
return data, err
}
return data, nil
}
2 - redis singleton
package tools
import (
"context"
"os"
"github.com/go-redis/redis/v8"
nrredis "github.com/newrelic/go-agent/v3/integrations/nrredis-v8"
newrelic "github.com/newrelic/go-agent/v3/newrelic"
)
var redisOpt = &redis.Options{
Addr: os.Getenv("GO_STATEMACHINE_REDIS_HOST") + ":" + os.Getenv("GO_STATEMACHINE_REDIS_PORT"),
DB: 1,
Password: os.Getenv("GO_STATEMACHINE_REDIS_PASSWORD"),
}
var Client *redis.Client = nil
var Ctx context.Context = nil
func getTransaction() *newrelic.Transaction {
redisTransaction := newrelic.FromContext(context.Background())
return redisTransaction
}
func init() {
Client = redis.NewClient(redisOpt)
Client.AddHook(nrredis.NewHook(redisOpt))
txn := getTransaction()
Ctx = newrelic.NewContext(context.Background(), txn)
}
func GetRedis() (*redis.Client, context.Context) {
if Client == nil {
Client = redis.NewClient(redisOpt)
Client.AddHook(nrredis.NewHook(redisOpt))
txn := getTransaction()
Ctx = newrelic.NewContext(context.Background(), txn)
}
return Client, Ctx
}
3 - new relic singleton
package tools
import (
"context"
"fmt"
"log"
"os"
newrelic "github.com/newrelic/go-agent"
)
var RelicApplication newrelic.Application = nil
var CurrentTransaction newrelic.Transaction = nil
func init() {
fmt.Println("INIT RELIC CREATING AT RUNTIME")
cfg := newrelic.NewConfig("go-vozyengine-statemachine-service", os.Getenv("NRELIC_KEY"))
cfg.Logger = newrelic.NewDebugLogger(os.Stdout)
cfg.BrowserMonitoring.Attributes.Enabled = true
cfg.TransactionTracer.Enabled = true
cfg.TransactionEvents.Enabled = true
cfg.DistributedTracer.Enabled = true
cfg.CustomInsightsEvents.Enabled = true
cfg.ErrorCollector.Enabled = true
cfg.ErrorCollector.CaptureEvents = true
var err error
RelicApplication, err = newrelic.NewApplication(cfg)
if err != nil {
log.Fatalf("failed to create newrelic.NewApplication: %v", err)
}
fmt.Println("INIT RELIC = RETURNING")
}
func SetSubTransaction(txn newrelic.Transaction) {
//set new current transaction
CurrentTransaction = txn
}
func SetSubTransactionByContext(ctx context.Context) {
fmt.Println("SETTING SUB TRANSACTION VIA CONTEXT - default set")
txn := newrelic.FromContext(ctx)
SetSubTransaction(txn)
}
func InitRelic() (newrelic.Application, error) {
fmt.Println("INIT RELIC REBUG")
if RelicApplication == nil {
fmt.Println("INIT RELIC = NOT INIT CREATING")
cfg := newrelic.NewConfig("go-vozyengine-statemachine-service", "29827623658187f9e25fdde2f2fee06da906NRAL")
cfg.Logger = newrelic.NewDebugLogger(os.Stdout)
cfg.BrowserMonitoring.Attributes.Enabled = true
// Enabling distributed tracing will disable the cross application tracing feature. Distributed tracing is
// an improved version of cross-application tracing and only one can be enabled at a time.
cfg.DistributedTracer.Enabled = true
RelicApplication, err := newrelic.NewApplication(cfg)
if err != nil {
log.Fatalf("failed to create newrelic.NewApplication: %v", err)
}
fmt.Println("INIT RELIC = RETURNING")
return RelicApplication, err
} else {
fmt.Println("INIT RELIC = ALREADY INIT RETURNING")
return RelicApplication, nil
}
}
any help is appreciated, thanks a lot!.
答案1
得分: 0
最后通过更新所有依赖项来解决了问题,必须升级GRPC版本及其相关依赖项。
还要更改Redis事务使用的上下文。
以下是最终的代码:
1 - 示例函数用法
dbTransaction := newrelic.FromContext(ctx)
newRelicContext := newrelic.NewContext(context.Background(), dbTransaction)
data, err := tools.Client.Get(newRelicContext, id).Result()
2 - Redis单例
package tools
import (
"context"
"os"
"github.com/go-redis/redis/v8"
nrredis "github.com/newrelic/go-agent/v3/integrations/nrredis-v8"
newrelic "github.com/newrelic/go-agent/v3/newrelic"
)
var redisOpt = &redis.Options{
Addr: os.Getenv("****************") + ":" + os.Getenv("*****************"),
DB: 1,
Password: os.Getenv("******************"),
}
var Client *redis.Client = nil
var Ctx context.Context = nil
func getTransaction() *newrelic.Transaction { return nil }
func init() {
Client = redis.NewClient(redisOpt)
Client.AddHook(nrredis.NewHook(redisOpt))
txn := getTransaction()
Ctx = newrelic.NewContext(context.Background(), txn)
}
func GetRedis() (*redis.Client, context.Context) {
if Client == nil {
Client = redis.NewClient(redisOpt)
Client.AddHook(nrredis.NewHook(redisOpt))
txn := getTransaction()
Ctx = newrelic.NewContext(context.Background(), txn)
}
return Client, Ctx
}
3 - newRelic单例
package tools
import (
"context"
"log"
"os"
newrelic "github.com/newrelic/go-agent/v3/newrelic"
)
var RelicApplication *newrelic.Application
var CurrentTransaction *newrelic.Transaction
func init() {
log.Println("INIT RELIC CREATING AT RUNTIME")
var err error
RelicApplication, err = newrelic.NewApplication(
newrelic.ConfigAppName("**********************"),
newrelic.ConfigLicense(os.Getenv("NRELIC_KEY")),
newrelic.ConfigDebugLogger(os.Stdout),
newrelic.ConfigDistributedTracerEnabled(true),
func(config *newrelic.Config) {
config.Enabled = true
},
)
if err != nil {
log.Println("ERROR INITING NEW RELIC: ", err)
}
log.Println("INIT RELIC = RETURNING")
}
func SetSubTransaction(txn *newrelic.Transaction) {
//set new current transaction
CurrentTransaction = txn
}
func SetSubTransactionByContext(ctx context.Context) {
txn := newrelic.FromContext(ctx)
SetSubTransaction(txn)
}
func InitRelic() (*newrelic.Application, error) {
if RelicApplication == nil {
var err error
writer, err := os.OpenFile("log_file", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
log.Println("ERROR OPENING LOG FILE: ", err)
return nil, err
}
RelicApplication, err = newrelic.NewApplication(
newrelic.ConfigAppName("**********************"),
newrelic.ConfigLicense(os.Getenv("NRELIC_KEY")),
newrelic.ConfigDebugLogger(os.Stdout),
newrelic.ConfigInfoLogger(writer),
newrelic.ConfigDistributedTracerEnabled(true),
func(config *newrelic.Config) {
config.Enabled = false
},
)
if err != nil {
log.Println("ERROR INITING NEW RELIC: ", err)
}
return RelicApplication, err
} else {
return RelicApplication, nil
}
}
英文:
At the end with was fixed by updating all dependencies, had to upgrade GRPC version and it's respective dependencies.
also change the context used by the redis transactions.
Here the final code
1 - example function usage
dbTransaction := newrelic.FromContext(ctx)
newRelicContext := newrelic.NewContext(context.Background(), dbTransaction)
data, err := tools.Client.Get(newRelicContext, id).Result()
2 - Redis Singleton
package tools
import (
"context"
"os"
"github.com/go-redis/redis/v8"
nrredis "github.com/newrelic/go-agent/v3/integrations/nrredis-v8"
newrelic "github.com/newrelic/go-agent/v3/newrelic"
)
var redisOpt = &redis.Options{
Addr: os.Getenv("****************") + ":" + os.Getenv("*****************"),
DB: 1,
Password: os.Getenv("******************"),
}
var Client *redis.Client = nil
var Ctx context.Context = nil
func getTransaction() *newrelic.Transaction { return nil }
func init() {
Client = redis.NewClient(redisOpt)
Client.AddHook(nrredis.NewHook(redisOpt))
txn := getTransaction()
Ctx = newrelic.NewContext(context.Background(), txn)
}
func GetRedis() (*redis.Client, context.Context) {
if Client == nil {
Client = redis.NewClient(redisOpt)
Client.AddHook(nrredis.NewHook(redisOpt))
txn := getTransaction()
Ctx = newrelic.NewContext(context.Background(), txn)
}
return Client, Ctx
}
3 - newRelic singleton
package tools
import (
"context"
"log"
"os"
newrelic "github.com/newrelic/go-agent/v3/newrelic"
)
var RelicApplication *newrelic.Application
var CurrentTransaction *newrelic.Transaction
func init() {
log.Println("INIT RELIC CREATING AT RUNTIME")
var err error
RelicApplication, err = newrelic.NewApplication(
newrelic.ConfigAppName("**********************"),
newrelic.ConfigLicense(os.Getenv("NRELIC_KEY")),
newrelic.ConfigDebugLogger(os.Stdout),
newrelic.ConfigDistributedTracerEnabled(true),
func(config *newrelic.Config) {
config.Enabled = true
},
)
if err != nil {
log.Println("ERROR INITING NEW RELIC: ", err)
}
log.Println("INIT RELIC = RETURNING")
}
func SetSubTransaction(txn *newrelic.Transaction) {
//set new current transaction
CurrentTransaction = txn
}
func SetSubTransactionByContext(ctx context.Context) {
txn := newrelic.FromContext(ctx)
SetSubTransaction(txn)
}
func InitRelic() (*newrelic.Application, error) {
if RelicApplication == nil {
var err error
writer, err := os.OpenFile("log_file", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
log.Println("ERROR OPENING LOG FILE: ", err)
return nil, err
}
RelicApplication, err = newrelic.NewApplication(
newrelic.ConfigAppName("**********************"),
newrelic.ConfigLicense(os.Getenv("NRELIC_KEY")),
newrelic.ConfigDebugLogger(os.Stdout),
newrelic.ConfigInfoLogger(writer),
newrelic.ConfigDistributedTracerEnabled(true),
func(config *newrelic.Config) {
config.Enabled = false
},
)
if err != nil {
log.Println("ERROR INITING NEW RELIC: ", err)
}
return RelicApplication, err
} else {
return RelicApplication, nil
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论