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!.
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
}
}