@@ -5,6 +5,8 @@ package nroci
55import (
66 "context"
77 "fmt"
8+ "net/url"
9+ "strings"
810 "time"
911
1012 "github.com/newrelic/go-agent/v3/newrelic"
@@ -58,6 +60,7 @@ type ConfigWrapper struct {
5860
5961type ClientWrapper struct {
6062 Client OCIClient
63+ Config * nosqldb.Config
6164}
6265
6366type ClientResponseWrapper [T any ] struct {
@@ -78,14 +81,59 @@ func NRCreateClient(cfg *ConfigWrapper) (*ClientWrapper, error) {
7881 }
7982 return & ClientWrapper {
8083 Client : client ,
84+ Config : cfg .Config ,
8185 }, nil
8286}
8387
88+ // extractOperation extracts the operation type from a statement
89+ // if the the statement is empty, or no word is found, then return "UNKNOWN"
90+ func extractOperation (statement string ) string {
91+ if statement == "" {
92+ return "UNKNOWN"
93+ }
94+
95+ words := strings .Fields (strings .ToUpper (statement ))
96+ if len (words ) == 0 {
97+ return "UNKNOWN"
98+ }
99+
100+ return words [0 ]
101+ }
102+
103+ // extractHostPort extracts host and port from an endpoint URL
104+ func extractHostPort (endpoint string ) (host , port string ) {
105+ if endpoint == "" {
106+ return "" , ""
107+ }
108+
109+ // Parse the endpoint URL
110+ parsedURL , err := url .Parse (endpoint )
111+ if err != nil {
112+ return "" , ""
113+ }
114+
115+ host = parsedURL .Hostname ()
116+ port = parsedURL .Port ()
117+
118+ // Set default ports if not specified
119+ if port == "" {
120+ switch parsedURL .Scheme {
121+ case "https" :
122+ port = "443"
123+ case "http" :
124+ port = "80"
125+ }
126+ }
127+
128+ return host , port
129+ }
130+
84131// executeWithDatastoreSegment is a generic helper function that executes a query with a given function from the
85132// OCI Client. It takes a type parameter T as any because of the different response types that are used within the
86133// OCI Client. This function will take the transaction from the context (if it exists) and create a Datastore Segment.
87134// It will then call whatever client function has been passed in.
88135func executeWithDatastoreSegment [T any ](
136+ cw * ClientWrapper ,
89137 ctx context.Context ,
90138 req * nosqldb.TableRequest ,
91139 fn func () (T , error ),
@@ -96,12 +144,18 @@ func executeWithDatastoreSegment[T any](
96144 return nil , fmt .Errorf ("error executing DoTableRequest, no transaction" )
97145 }
98146
147+ // Extract host and port from config endpoint
148+ host , port := extractHostPort (cw .Config .Endpoint )
149+
99150 sgmt := newrelic.DatastoreSegment {
100- StartTime : txn .StartSegmentNow (),
101- Product : newrelic .DatastoreOracle ,
102- Collection : req .TableName ,
103- Operation : req .Namespace ,
104- DatabaseName : req .Namespace ,
151+ StartTime : txn .StartSegmentNow (),
152+ Product : newrelic .DatastoreOracle ,
153+ Collection : req .TableName ,
154+ Operation : extractOperation (req .Statement ),
155+ DatabaseName : req .Namespace ,
156+ ParameterizedQuery : req .Statement ,
157+ Host : host ,
158+ PortPathOrID : port ,
105159 }
106160
107161 responseWrapper := ClientResponseWrapper [T ]{}
@@ -110,24 +164,24 @@ func executeWithDatastoreSegment[T any](
110164 if err != nil {
111165 return & responseWrapper , fmt .Errorf ("error making request: %s" , err .Error ())
112166 }
113- // 4. End segment
167+
114168 sgmt .End ()
115- // 5. Return result
169+
116170 return & responseWrapper , nil
117171}
118172
119173// Wrapper for nosqldb.Client.DoTableRequest. Provide the ClientWrapper and Context as parameters in addition to the nosqldbTableRequest.
120174// Returns a ClientResponseWrapper[*nosqldbTableResult] and error.
121175func NRDoTableRequest (cw * ClientWrapper , ctx context.Context , req * nosqldb.TableRequest ) (* ClientResponseWrapper [* nosqldb.TableResult ], error ) {
122- return executeWithDatastoreSegment (ctx , req , func () (* nosqldb.TableResult , error ) {
176+ return executeWithDatastoreSegment (cw , ctx , req , func () (* nosqldb.TableResult , error ) {
123177 return cw .Client .DoTableRequest (req )
124178 })
125179}
126180
127181// Wrapper for nosqldb.Client.DoTableRequestWait. Provide the ClientWrapper and Context as parameters in addition to the nosqldbTableRequest,
128182// timeout, and pollInterval. Returns a ClientResponseWrapper[*nosqldbTableResult] and error.
129183func NRDoTableRequestAndWait (cw * ClientWrapper , ctx context.Context , req * nosqldb.TableRequest , timeout time.Duration , pollInterval time.Duration ) (* ClientResponseWrapper [* nosqldb.TableResult ], error ) {
130- return executeWithDatastoreSegment (ctx , req , func () (* nosqldb.TableResult , error ) {
184+ return executeWithDatastoreSegment (cw , ctx , req , func () (* nosqldb.TableResult , error ) {
131185 return cw .Client .DoTableRequestAndWait (req , timeout , pollInterval )
132186 })
133187}
0 commit comments