Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable DT by Default for the Go Agent #495

Merged
merged 10 commits into from
May 19, 2022
15 changes: 5 additions & 10 deletions v3/examples/client/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

//
package main

import (
Expand All @@ -14,14 +14,14 @@ import (

func doRequest(txn *newrelic.Transaction) error {
req, err := http.NewRequest("GET", "http://localhost:8000/segments", nil)
if nil != err {
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for fixing this, these always bothered me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a matter of principle I've been fixing those as I encounter them. when doing other fixes.

return err
}
client := &http.Client{}
seg := newrelic.StartExternalSegment(txn, req)
defer seg.End()
resp, err := client.Do(req)
if nil != err {
if err != nil {
return err
}
fmt.Println("response code is", resp.StatusCode)
Expand All @@ -35,19 +35,14 @@ func main() {
newrelic.ConfigDebugLogger(os.Stdout),
newrelic.ConfigDistributedTracerEnabled(true),
)
if nil != err {
if err != nil {
fmt.Println(err)
os.Exit(1)
}

// Wait for the application to connect.
if err = app.WaitForConnection(5 * time.Second); nil != err {
fmt.Println(err)
}

txn := app.StartTransaction("client-txn")
err = doRequest(txn)
if nil != err {
if err != nil {
txn.NoticeError(err)
}
txn.End()
Expand Down
6 changes: 3 additions & 3 deletions v3/examples/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func external(w http.ResponseWriter, r *http.Request) {
resp, err := http.DefaultClient.Do(req)
es.End()

if nil != err {
if err != nil {
io.WriteString(w, err.Error())
return
}
Expand Down Expand Up @@ -199,7 +199,7 @@ func roundtripper(w http.ResponseWriter, r *http.Request) {
// request = newrelic.RequestWithTransactionContext(request, txn)

resp, err := client.Do(request)
if nil != err {
if err != nil {
io.WriteString(w, err.Error())
return
}
Expand Down Expand Up @@ -252,7 +252,7 @@ func main() {
newrelic.ConfigFromEnvironment(),
newrelic.ConfigDebugLogger(os.Stdout),
)
if nil != err {
if err != nil {
fmt.Println(err)
os.Exit(1)
}
Expand Down
2 changes: 1 addition & 1 deletion v3/integrations/nrelasticsearch-v7/example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func main() {
newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
newrelic.ConfigDebugLogger(os.Stdout),
)
if nil != err {
if err != nil {
panic(err)
}
app.WaitForConnection(5 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion v3/integrations/nrgraphqlgo/example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func main() {
newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
newrelic.ConfigDebugLogger(os.Stdout),
)
if nil != err {
if err != nil {
fmt.Println(err)
os.Exit(1)
}
Expand Down
21 changes: 9 additions & 12 deletions v3/integrations/nrgrpc/example/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@ import (

func doUnaryUnary(ctx context.Context, client sampleapp.SampleApplicationClient) {
msg, err := client.DoUnaryUnary(ctx, &sampleapp.Message{Text: "Hello DoUnaryUnary"})
if nil != err {
if err != nil {
panic(err)
}
fmt.Println(msg.Text)
}

func doUnaryStream(ctx context.Context, client sampleapp.SampleApplicationClient) {
stream, err := client.DoUnaryStream(ctx, &sampleapp.Message{Text: "Hello DoUnaryStream"})
if nil != err {
if err != nil {
panic(err)
}
for {
msg, err := stream.Recv()
if err == io.EOF {
break
}
if nil != err {
if err != nil {
panic(err)
}
fmt.Println(msg.Text)
Expand All @@ -43,27 +43,27 @@ func doUnaryStream(ctx context.Context, client sampleapp.SampleApplicationClient

func doStreamUnary(ctx context.Context, client sampleapp.SampleApplicationClient) {
stream, err := client.DoStreamUnary(ctx)
if nil != err {
if err != nil {
panic(err)
}
for i := 0; i < 3; i++ {
if err := stream.Send(&sampleapp.Message{Text: "Hello DoStreamUnary"}); nil != err {
if err := stream.Send(&sampleapp.Message{Text: "Hello DoStreamUnary"}); err != nil {
if err == io.EOF {
break
}
panic(err)
}
}
msg, err := stream.CloseAndRecv()
if nil != err {
if err != nil {
panic(err)
}
fmt.Println(msg.Text)
}

func doStreamStream(ctx context.Context, client sampleapp.SampleApplicationClient) {
stream, err := client.DoStreamStream(ctx)
if nil != err {
if err != nil {
panic(err)
}
waitc := make(chan struct{})
Expand Down Expand Up @@ -95,15 +95,12 @@ func main() {
newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
newrelic.ConfigDebugLogger(os.Stdout),
)
if nil != err {
panic(err)
}
err = app.WaitForConnection(10 * time.Second)
if nil != err {
if err != nil {
panic(err)
}
defer app.Shutdown(10 * time.Second)

app.WaitForConnection(10 * time.Second)
txn := app.StartTransaction("main")
defer txn.End()

Expand Down
6 changes: 3 additions & 3 deletions v3/integrations/nrgrpc/example/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (

"github.com/newrelic/go-agent/v3/integrations/nrgrpc"
sampleapp "github.com/newrelic/go-agent/v3/integrations/nrgrpc/example/sampleapp"
newrelic "github.com/newrelic/go-agent/v3/newrelic"
"github.com/newrelic/go-agent/v3/newrelic"
"google.golang.org/grpc"
)

Expand Down Expand Up @@ -77,7 +77,7 @@ func main() {
newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
newrelic.ConfigDebugLogger(os.Stdout),
)
if nil != err {
if err != nil {
panic(err)
}

Expand All @@ -86,10 +86,10 @@ func main() {
panic(err)
}
grpcServer := grpc.NewServer(
// Add the New Relic gRPC server instrumentation
grpc.UnaryInterceptor(nrgrpc.UnaryServerInterceptor(app)),
grpc.StreamInterceptor(nrgrpc.StreamServerInterceptor(app)),
)
sampleapp.RegisterSampleApplicationServer(grpcServer, &Server{})
grpcServer.Serve(lis)

}
36 changes: 35 additions & 1 deletion v3/integrations/nrredis-v8/example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
package main

import (
"bufio"
"context"
"fmt"
"os"
"strconv"
"strings"
"time"

redis "github.com/go-redis/redis/v8"
Expand All @@ -20,10 +23,15 @@ func main() {
newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
newrelic.ConfigDebugLogger(os.Stdout),
)
if nil != err {
if err != nil {
panic(err)
}

// normally, production code wouldn't require the WaitForConnection call,
// but for an extremely short-lived script, we want to be sure we are
// connected before we've already exited.
app.WaitForConnection(10 * time.Second)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this one-shot redis example work without that WaitForConnection in here?


txn := app.StartTransaction("ping txn")

opts := &redis.Options{
Expand All @@ -47,6 +55,32 @@ func main() {
_, err = pipe.Exec(ctx)
fmt.Println(incr.Val(), err)

result, err := client.Do(ctx, "INFO", "STATS").Result()
if err != nil {
panic(err)
}
hits := 0
misses := 0
if stats, ok := result.(string); ok {
sc := bufio.NewScanner(strings.NewReader(stats))
for sc.Scan() {
fields := strings.Split(sc.Text(), ":")
if len(fields) == 2 {
if v, err := strconv.Atoi(fields[1]); err == nil {
switch fields[0] {
case "keyspace_hits":
hits = v
case "keyspace_misses":
misses = v
}
}
}
}
}
if hits+misses > 0 {
app.RecordCustomMetric("Custom/RedisCache/HitRatio", float64(hits)/(float64(hits+misses)))
}

txn.End()
app.Shutdown(5 * time.Second)
}
29 changes: 24 additions & 5 deletions v3/integrations/nrsqlite3/example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func main() {
if err != nil {
panic(err)
}

defer db.Close()

db.Exec("CREATE TABLE zaps ( zap_num INTEGER )")
Expand All @@ -29,19 +30,37 @@ func main() {
newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
newrelic.ConfigDebugLogger(os.Stdout),
)
if nil != err {
if err != nil {
panic(err)
}
app.WaitForConnection(5 * time.Second)
txn := app.StartTransaction("sqliteQuery")

app.WaitForConnection(10 * time.Second)
txn := app.StartTransaction("sqliteQuery")
ctx := newrelic.NewContext(context.Background(), txn)
row := db.QueryRowContext(ctx, "SELECT count(*) from zaps")
var count int
row.Scan(&count)
txn.End()

txn = app.StartTransaction("CustomSQLQuery")
s := newrelic.DatastoreSegment{
Product: newrelic.DatastoreMySQL,
Collection: "users",
Operation: "INSERT",
ParameterizedQuery: "INSERT INTO users (name, age) VALUES ($1, $2)",
QueryParameters: map[string]interface{}{
"name": "Dracula",
"age": 439,
},
Host: "mysql-server-1",
PortPathOrID: "3306",
DatabaseName: "my_database",
}
s.StartTime = txn.StartSegmentNow()
// ... do the operation
s.End()
txn.End()
app.Shutdown(5 * time.Second)

fmt.Println("number of entries in table", count)
app.Shutdown(5 * time.Second)
fmt.Printf("number of elements in table: %v\n", count)
}
10 changes: 10 additions & 0 deletions v3/internal/connect_reply.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ func DefaultEventHarvestConfig(maxTxnEvents int) EventHarvestConfig {
return cfg
}

// DefaultEventHarvestConfigWithDT is an extended version of DefaultEventHarvestConfig,
// with the addition that it takes into account distributed tracer span event harvest limits.
func DefaultEventHarvestConfigWithDT(maxTxnEvents int, dtEnabled bool, spanEventLimit int) EventHarvestConfig {
cfg := DefaultEventHarvestConfig(maxTxnEvents)
if dtEnabled {
cfg.Limits.SpanEvents = uintPtr(uint(spanEventLimit))
}
return cfg
}

// TrustedAccountSet is used for CAT.
type TrustedAccountSet map[int]struct{}

Expand Down
18 changes: 12 additions & 6 deletions v3/newrelic/app_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func newAppRun(config config, reply *internal.ConnectReply) *appRun {
reply.SamplingTarget,
time.Now())

if "" != run.Reply.RunID {
if run.Reply.RunID != "" {
js, _ := json.Marshal(settings(run.Config.Config))
run.Config.Logger.Debug("final configuration", map[string]interface{}{
"config": jsonString(js),
Expand Down Expand Up @@ -148,13 +148,13 @@ func newServerlessConnectReply(config config) *internal.ConnectReply {
reply.TrustedAccountKey = config.ServerlessMode.TrustedAccountKey
reply.PrimaryAppID = config.ServerlessMode.PrimaryAppID

if "" == reply.TrustedAccountKey {
if reply.TrustedAccountKey == "" {
// The trust key does not need to be provided by customers whose
// account ID is the same as the trust key.
reply.TrustedAccountKey = reply.AccountID
}

if "" == reply.PrimaryAppID {
if reply.PrimaryAppID == "" {
reply.PrimaryAppID = serverlessDefaultPrimaryAppID
}

Expand Down Expand Up @@ -197,10 +197,16 @@ func (run *appRun) MaxCustomEvents() int {
func (run *appRun) MaxErrorEvents() int {
return run.limit(internal.MaxErrorEvents, run.ptrErrorEvents)
}
func (run *appRun) MaxSpanEvents() int { return run.limit(maxSpanEvents, run.ptrSpanEvents) }

// MaxSpanEvents returns the reservoir limit for collected span events,
// which will be the default or the user's configured size (if any), but
// may be capped to the maximum allowed by the collector.
func (run *appRun) MaxSpanEvents() int {
return run.limit(run.Config.DistributedTracer.ReservoirLimit, run.ptrSpanEvents)
}

func (run *appRun) limit(dflt int, field func() *uint) int {
if nil != field() {
if field() != nil {
return int(*field())
}
return dflt
Expand All @@ -216,7 +222,7 @@ func (run *appRun) ReportPeriods() map[harvestTypes]time.Duration {
harvestErrorEvents: run.ptrErrorEvents,
harvestSpanEvents: run.ptrSpanEvents,
} {
if nil != run && fn() != nil {
if run != nil && fn() != nil {
configurable |= tp
} else {
fixed |= tp
Expand Down
Loading