nrcontext

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2021 License: MIT Imports: 8 Imported by: 0

README

newrelic-context

Contains different helpers to integrate NewRelic agent v3 with Gorm v2.

When to use this?

This is a workaround to an issue where the postgres integration doesn't display database NR metrics as expected.

If using another type of database, MySQL for example, you might have a simpler option as other drivers work just fine.

Installation

go get github.com/getndazn/newrelic-context

In this package:

  • ContextWithTxn - Set NewRelic transaction to context
  • GetTnxFromContext - Get NewRelic transaction from context anywhere
  • NewRelicMiddleware - Reports time in NewRelic and sets transaction in context
  • WrapHTTPClient - Wraps client transport with newrelic RoundTripper with transaction from context
  • SetTxnToGorm - Sets transaction from Context to gorm settings
  • AddGormCallbacks - Adds callbacks to NewRelic, you should call SetTxnToGorm to make them work
  • RedisWrapper - Logs gopkg.in/redis.v5 time in newrelic
  • WrapRedisClient - Returns copy of redis client with newrelic for transaction

API documentation is available on godoc.org

Examples:

Use NewRelicMiddleware:

package main

import (
    "github.com/getndazn/newrelic-context"
    "log"
    "net/http"
)

func indexHandlerFunc(rw http.ResponseWriter, req *http.Request) {
    rw.Write([]byte("I'm an index page!"))
}

func main() {
    var handler http.Handler

    handler = http.HandlerFunc(indexHandlerFunc)
    nrmiddleware, err := nrcontext.NewMiddleware("test-app", "my-license-key")
    if err != nil {
        log.Print("Can't create newrelic middleware: ", err)
    } else {
        handler = nrmiddleware.Handler(handler)
    }

    http.ListenAndServe(":8000", handler)
}

Use HTTPClientWrap:

func Consume(ctx context.Context, query string) {
    client := &http.Client{Timeout: 10}
    nrcontext.WrapHTTPClient(ctx, client)
    _, err := client.Get(fmt.Sprintf("https://www.google.com.vn/?q=%v", query))
    if err != nil {
        log.Println("Can't fetch google :(")
        return
    }
    log.Println("Google fetched successfully!")
}

Use with Gorm:

var db *gorm.DB

func initDB() *gorm.DB {
    db, err := gorm.Open(sqlite.Open("./foo.db"))
    if err != nil {
        panic("failed to connect database")
    }
    nrgorm.AddGormCallbacks(db)
    return db
}

func catalogPage(db *gorm.DB) http.Handler {
    return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
        var products []Product
        db := nrcontext.SetTxnToGorm(req.Context(), db)
        db.Find(&products)
        for i, v := range products {
            rw.Write([]byte(fmt.Sprintf("%v. %v\n", i, v.Name)))
        }
    })
}

func main() {
    db = initDB()
    defer db.Close()

    handler := catalogPage(db)
    nrmiddleware, _ := nrcontext.NewMiddleware("test-app", "my-license-key")
    handler = nrmiddleware.Handler(handler)

    http.ListenAndServe(":8000", handler)
}

Use with Redis:

func catalogPage(redisClient *redis.Client) http.Handler {
    return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
        redisClient := WrapRedisClient(req.Context(), redisClient)

        redisClient.Set("key", "value", 0)
        // ...
        redisClient.Get("other-key")
    })
}

func main() {
    client := redis.NewClient(...)

    handler := catalogPage(db)
    nrmiddleware, _ := nrcontext.NewMiddleware("test-app", "my-license-key")
    handler = nrmiddleware.Handler(handler)

    http.ListenAndServe(":8000", handler)
}

Documentation

Overview

Contains different helpers to make life easier with NewRelic and Context

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContextWithTxn

func ContextWithTxn(c context.Context, txn *newrelic.Transaction) context.Context

Set NewRelic transaction to context

func GetTnxFromContext

func GetTnxFromContext(c context.Context) *newrelic.Transaction

Get NewRelic transaction from context anywhere

func SetTxnToGorm

func SetTxnToGorm(ctx context.Context, db *gorm.DB) *gorm.DB

Sets transaction from Context to gorm settings, returns cloned DB

func WrapHTTPClient

func WrapHTTPClient(ctx context.Context, c *http.Client, rq func() (*http.Request, error))

Gets NewRelic transaction from context and wraps client transport with newrelic RoundTripper

func WrapRedisClient

func WrapRedisClient(ctx context.Context, c *redis.Client) *redis.Client

Gets transaction from Context and applies RedisWrapper, returns cloned client

Types

type NewRelicMiddleware

type NewRelicMiddleware struct {
	// contains filtered or unexported fields
}

func NewMiddleware

func NewMiddleware(appname string, license string) (*NewRelicMiddleware, error)

Creates new middleware that will report time in NewRelic and set transaction in context

func NewMiddlewareWithApp

func NewMiddlewareWithApp(app *newrelic.Application) *NewRelicMiddleware

Same as NewMiddleware but accepts newrelic.Application

func NewMiddlewareWithConfig

func NewMiddlewareWithConfig(opts newrelic.ConfigOption) (*NewRelicMiddleware, error)

Same as NewMiddleware but accepts newrelic.Config

func (*NewRelicMiddleware) Handler

func (nr *NewRelicMiddleware) Handler(h http.Handler) http.Handler

Creates wrapper for your handler

func (*NewRelicMiddleware) SetTxnNameFunc

func (nr *NewRelicMiddleware) SetTxnNameFunc(fn TxnNameFunc)

Allows to change transaction name. By default `fmt.Sprintf("%s %s", r.Method, r.URL.Path)`

type TxnNameFunc

type TxnNameFunc func(*http.Request) string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL