forked from newrelic/go-agent
/
main.go
146 lines (134 loc) · 4.48 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
// An application that illustrates how to instrument jmoiron/sqlx with DatastoreSegments
//
// To run this example, be sure the environment varible NEW_RELIC_LICENSE_KEY
// is set to your license key. Postgres must be running on the default port
// 5432 and have a user "foo" and a database "bar".
//
// Adding instrumentation for the SQLx package is easy. It means you can
// make database calls without having to manually create DatastoreSegments.
// Setup can be done in two steps:
//
// Set up your driver
//
// If you are using one of our currently supported database drivers (see
// https://docs.newrelic.com/docs/agents/go-agent/get-started/go-agent-compatibility-requirements#frameworks),
// follow the instructions on installing the driver.
//
// As an example, for the `lib/pq` driver, you will use the newrelic
// integration's driver in place of the postgres driver. If your code is using
// sqlx.Open with `lib/pq` like this:
//
// import (
// "github.com/jmoiron/sqlx"
// _ "github.com/lib/pq"
// )
//
// func main() {
// db, err := sqlx.Open("postgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")
// }
//
// Then change the side-effect import to the integration package, and open
// "nrpostgres" instead:
//
// import (
// "github.com/jmoiron/sqlx"
// _ "github.com/newrelic/go-agent/_integrations/nrpq"
// )
//
// func main() {
// db, err := sqlx.Open("nrpostgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")
// }
//
// If you are not using one of the supported database drivers, use the
// `InstrumentSQLDriver`
// (https://godoc.org/github.com/newrelic/go-agent#InstrumentSQLDriver) API.
// See
// https://github.com/newrelic/go-agent/blob/master/_integrations/nrmysql/nrmysql.go
// for a full example.
//
// Add context to your database calls
//
// Next, you must provide a context containing a newrelic.Transaction to all
// methods on sqlx.DB, sqlx.NamedStmt, sqlx.Stmt, and sqlx.Tx that make a
// database call. For example, instead of the following:
//
// err := db.Get(&jason, "SELECT * FROM person WHERE first_name=$1", "Jason")
//
// Do this:
//
// ctx := newrelic.NewContext(context.Background(), txn)
// err := db.GetContext(ctx, &jason, "SELECT * FROM person WHERE first_name=$1", "Jason")
//
package main
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/jmoiron/sqlx"
newrelic "github.com/newrelic/go-agent"
_ "github.com/newrelic/go-agent/_integrations/nrpq"
)
var schema = `
CREATE TABLE person (
first_name text,
last_name text,
email text
)`
// Person is a person in the database
type Person struct {
FirstName string `db:"first_name"`
LastName string `db:"last_name"`
Email string
}
func mustGetEnv(key string) string {
if val := os.Getenv(key); "" != val {
return val
}
panic(fmt.Sprintf("environment variable %s unset", key))
}
func createApp() newrelic.Application {
cfg := newrelic.NewConfig("SQLx", mustGetEnv("NEW_RELIC_LICENSE_KEY"))
cfg.Logger = newrelic.NewDebugLogger(os.Stdout)
app, err := newrelic.NewApplication(cfg)
if nil != err {
log.Fatalln(err)
}
if err := app.WaitForConnection(5 * time.Second); nil != err {
log.Fatalln(err)
}
return app
}
func main() {
// Create application
app := createApp()
defer app.Shutdown(10 * time.Second)
// Start a transaction
txn := app.StartTransaction("main", nil, nil)
defer txn.End()
// Add transaction to context
ctx := newrelic.NewContext(context.Background(), txn)
// Connect to database using the "nrpostgres" driver
db, err := sqlx.Connect("nrpostgres", "user=foo dbname=bar sslmode=disable")
if err != nil {
log.Fatalln(err)
}
// Create database table if it does not exist already
// When the context is passed, DatastoreSegments will be created
db.ExecContext(ctx, schema)
// Add people to the database
// When the context is passed, DatastoreSegments will be created
tx := db.MustBegin()
tx.MustExecContext(ctx, "INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)", "Jason", "Moiron", "jmoiron@jmoiron.net")
tx.MustExecContext(ctx, "INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)", "John", "Doe", "johndoeDNE@gmail.net")
tx.Commit()
// Read from the database
// When the context is passed, DatastoreSegments will be created
people := []Person{}
db.SelectContext(ctx, &people, "SELECT * FROM person ORDER BY first_name ASC")
jason := Person{}
db.GetContext(ctx, &jason, "SELECT * FROM person WHERE first_name=$1", "Jason")
}