github.com/newrelic/go-agent@v3.26.0+incompatible/_integrations/nrnats/examples/main.go (about)

     1  // Copyright 2020 New Relic Corporation. All rights reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"sync"
    10  	"time"
    11  
    12  	"github.com/nats-io/nats.go"
    13  	newrelic "github.com/newrelic/go-agent"
    14  	"github.com/newrelic/go-agent/_integrations/nrnats"
    15  )
    16  
    17  var app newrelic.Application
    18  
    19  func doAsync(nc *nats.Conn, txn newrelic.Transaction) {
    20  	wg := sync.WaitGroup{}
    21  	subj := "async"
    22  
    23  	// Simple Async Subscriber
    24  	// Use the nrnats.SubWrapper to wrap the nats.MsgHandler and create a
    25  	// newrelic.Transaction with each processed nats.Msg
    26  	_, err := nc.Subscribe(subj, nrnats.SubWrapper(app, func(m *nats.Msg) {
    27  		defer wg.Done()
    28  		fmt.Println("Received async message:", string(m.Data))
    29  	}))
    30  	if nil != err {
    31  		panic(err)
    32  	}
    33  
    34  	// Simple Publisher
    35  	wg.Add(1)
    36  	// Use nrnats.StartPublishSegment to create a
    37  	// newrelic.MessageProducerSegment for the call to nc.Publish
    38  	seg := nrnats.StartPublishSegment(txn, nc, subj)
    39  	err = nc.Publish(subj, []byte("Hello World"))
    40  	seg.End()
    41  	if nil != err {
    42  		panic(err)
    43  	}
    44  
    45  	wg.Wait()
    46  }
    47  
    48  func doQueue(nc *nats.Conn, txn newrelic.Transaction) {
    49  	wg := sync.WaitGroup{}
    50  	subj := "queue"
    51  
    52  	// Queue Subscriber
    53  	// Use the nrnats.SubWrapper to wrap the nats.MsgHandler and create a
    54  	// newrelic.Transaction with each processed nats.Msg
    55  	_, err := nc.QueueSubscribe(subj, "myQueueName", nrnats.SubWrapper(app, func(m *nats.Msg) {
    56  		defer wg.Done()
    57  		fmt.Println("Received queue message:", string(m.Data))
    58  	}))
    59  	if nil != err {
    60  		panic(err)
    61  	}
    62  
    63  	wg.Add(1)
    64  	// Use nrnats.StartPublishSegment to create a
    65  	// newrelic.MessageProducerSegment for the call to nc.Publish
    66  	seg := nrnats.StartPublishSegment(txn, nc, subj)
    67  	err = nc.Publish(subj, []byte("Hello World"))
    68  	seg.End()
    69  	if nil != err {
    70  		panic(err)
    71  	}
    72  
    73  	wg.Wait()
    74  }
    75  
    76  func doSync(nc *nats.Conn, txn newrelic.Transaction) {
    77  	subj := "sync"
    78  
    79  	// Simple Sync Subscriber
    80  	sub, err := nc.SubscribeSync(subj)
    81  	if nil != err {
    82  		panic(err)
    83  	}
    84  	// Use nrnats.StartPublishSegment to create a
    85  	// newrelic.MessageProducerSegment for the call to nc.Publish
    86  	seg := nrnats.StartPublishSegment(txn, nc, subj)
    87  	err = nc.Publish(subj, []byte("Hello World"))
    88  	seg.End()
    89  	if nil != err {
    90  		panic(err)
    91  	}
    92  	m, err := sub.NextMsg(time.Second)
    93  	if nil != err {
    94  		panic(err)
    95  	}
    96  	fmt.Println("Received sync message:", string(m.Data))
    97  }
    98  
    99  func doChan(nc *nats.Conn, txn newrelic.Transaction) {
   100  	subj := "chan"
   101  
   102  	// Channel Subscriber
   103  	ch := make(chan *nats.Msg)
   104  	_, err := nc.ChanSubscribe(subj, ch)
   105  	if nil != err {
   106  		panic(err)
   107  	}
   108  
   109  	// Use nrnats.StartPublishSegment to create a
   110  	// newrelic.MessageProducerSegment for the call to nc.Publish
   111  	seg := nrnats.StartPublishSegment(txn, nc, subj)
   112  	err = nc.Publish(subj, []byte("Hello World"))
   113  	seg.End()
   114  	if nil != err {
   115  		panic(err)
   116  	}
   117  
   118  	m := <-ch
   119  	fmt.Println("Received chan message:", string(m.Data))
   120  }
   121  
   122  func doReply(nc *nats.Conn, txn newrelic.Transaction) {
   123  	subj := "reply"
   124  
   125  	// Replies
   126  	nc.Subscribe(subj, func(m *nats.Msg) {
   127  		// Use nrnats.StartPublishSegment to create a
   128  		// newrelic.MessageProducerSegment for the call to nc.Publish
   129  		seg := nrnats.StartPublishSegment(txn, nc, m.Reply)
   130  		nc.Publish(m.Reply, []byte("Hello World"))
   131  		seg.End()
   132  	})
   133  
   134  	// Requests
   135  	// Use nrnats.StartPublishSegment to create a
   136  	// newrelic.MessageProducerSegment for the call to nc.Request
   137  	seg := nrnats.StartPublishSegment(txn, nc, subj)
   138  	m, err := nc.Request(subj, []byte("request"), time.Second)
   139  	seg.End()
   140  	if nil != err {
   141  		panic(err)
   142  	}
   143  	fmt.Println("Received reply message:", string(m.Data))
   144  }
   145  
   146  func doRespond(nc *nats.Conn, txn newrelic.Transaction) {
   147  	subj := "respond"
   148  	// Respond
   149  	nc.Subscribe(subj, func(m *nats.Msg) {
   150  		// Use nrnats.StartPublishSegment to create a
   151  		// newrelic.MessageProducerSegment for the call to m.Respond
   152  		seg := nrnats.StartPublishSegment(txn, nc, m.Reply)
   153  		m.Respond([]byte("Hello World"))
   154  		seg.End()
   155  	})
   156  
   157  	// Requests
   158  	// Use nrnats.StartPublishSegment to create a
   159  	// newrelic.MessageProducerSegment for the call to nc.Request
   160  	seg := nrnats.StartPublishSegment(txn, nc, subj)
   161  	m, err := nc.Request(subj, []byte("request"), time.Second)
   162  	seg.End()
   163  	if nil != err {
   164  		panic(err)
   165  	}
   166  	fmt.Println("Received respond message:", string(m.Data))
   167  }
   168  
   169  func mustGetEnv(key string) string {
   170  	if val := os.Getenv(key); "" != val {
   171  		return val
   172  	}
   173  	panic(fmt.Sprintf("environment variable %s unset", key))
   174  }
   175  
   176  func main() {
   177  	// Initialize agent
   178  	cfg := newrelic.NewConfig("NATS App", mustGetEnv("NEW_RELIC_LICENSE_KEY"))
   179  	cfg.Logger = newrelic.NewDebugLogger(os.Stdout)
   180  	var err error
   181  	app, err = newrelic.NewApplication(cfg)
   182  	if nil != err {
   183  		panic(err)
   184  	}
   185  	defer app.Shutdown(10 * time.Second)
   186  	err = app.WaitForConnection(5 * time.Second)
   187  	if nil != err {
   188  		panic(err)
   189  	}
   190  	txn := app.StartTransaction("main", nil, nil)
   191  	defer txn.End()
   192  
   193  	// Connect to a server
   194  	nc, err := nats.Connect(nats.DefaultURL)
   195  	if nil != err {
   196  		panic(err)
   197  	}
   198  	defer nc.Drain()
   199  
   200  	doAsync(nc, txn)
   201  	doQueue(nc, txn)
   202  	doSync(nc, txn)
   203  	doChan(nc, txn)
   204  	doReply(nc, txn)
   205  	doRespond(nc, txn)
   206  }