From 10634f3341c740db713c7140b34c0c9f623a0b27 Mon Sep 17 00:00:00 2001 From: mirackara Date: Fri, 1 Mar 2024 13:44:23 -0600 Subject: [PATCH 1/3] Add Config Settings --- v3/newrelic/config.go | 12 +++++++++++- v3/newrelic/config_options.go | 10 ++++++++++ v3/newrelic/config_test.go | 12 ++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/v3/newrelic/config.go b/v3/newrelic/config.go index 5d79bf8fa..a74add79c 100644 --- a/v3/newrelic/config.go +++ b/v3/newrelic/config.go @@ -235,6 +235,15 @@ type Config struct { DynoNamePrefixesToShorten []string } + // AIMonitoring controls the behavior of AI monitoring features. + AIMonitoring struct { + Enabled bool + // Indicates whether streams will be instrumented + Streaming struct { + Enabled bool + } + } + // CrossApplicationTracer controls behavior relating to cross application // tracing (CAT). In the case where CrossApplicationTracer and // DistributedTracer are both enabled, DistributedTracer takes precedence. @@ -666,7 +675,8 @@ func defaultConfig() Config { c.Heroku.UseDynoNames = true c.Heroku.DynoNamePrefixesToShorten = []string{"scheduler", "run"} - + c.AIMonitoring.Enabled = false + c.AIMonitoring.Streaming.Enabled = true c.InfiniteTracing.TraceObserver.Port = 443 c.InfiniteTracing.SpanEvents.QueueSize = 10000 diff --git a/v3/newrelic/config_options.go b/v3/newrelic/config_options.go index 5b9261e17..2ccc65fe1 100644 --- a/v3/newrelic/config_options.go +++ b/v3/newrelic/config_options.go @@ -236,6 +236,16 @@ func ConfigAppLogDecoratingEnabled(enabled bool) ConfigOption { } } +func ConfigAIMonitoringEnabled(enabled bool) ConfigOption { + return func(cfg *Config) { + if enabled && !cfg.HighSecurity { + cfg.AIMonitoring.Enabled = true + } else { + cfg.AIMonitoring.Enabled = false + } + } +} + // ConfigAppLogMetricsEnabled enables or disables the collection of metrics // data for logs seen by an instrumented logging framework // default: true diff --git a/v3/newrelic/config_test.go b/v3/newrelic/config_test.go index 37eb88159..10b64dfb1 100644 --- a/v3/newrelic/config_test.go +++ b/v3/newrelic/config_test.go @@ -130,6 +130,12 @@ func TestCopyConfigReferenceFieldsPresent(t *testing.T) { "agent_version":"0.2.2", "host":"my-hostname", "settings":{ + "AIMonitoring": { + "Enabled": false, + "Streaming": { + "Enabled": true + } + }, "AppName":"my appname", "ApplicationLogging": { "Enabled": true, @@ -326,6 +332,12 @@ func TestCopyConfigReferenceFieldsAbsent(t *testing.T) { "agent_version":"0.2.2", "host":"my-hostname", "settings":{ + "AIMonitoring": { + "Enabled": false, + "Streaming": { + "Enabled": true + } + }, "AppName":"my appname", "ApplicationLogging": { "Enabled": true, From 03ee380e99808a4556c3879b83ac8b4d4d5f429d Mon Sep 17 00:00:00 2001 From: mirackara Date: Fri, 1 Mar 2024 13:47:01 -0600 Subject: [PATCH 2/3] Add RecordLLMFeedbackEvent --- v3/newrelic/application.go | 27 ++++++++++++++++++++++++++- v3/newrelic/internal_test.go | 20 ++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/v3/newrelic/application.go b/v3/newrelic/application.go index 0249c738f..f7bdf0058 100644 --- a/v3/newrelic/application.go +++ b/v3/newrelic/application.go @@ -48,6 +48,32 @@ func (app *Application) RecordCustomEvent(eventType string, params map[string]in } } +// RecordLlmFeedbackEvent adds a LLM Feedback event. +// An error is logged if eventType or params is invalid. +func (app *Application) RecordLLMFeedbackEvent(trace_id string, rating any, category string, message string, metadata map[string]interface{}) { + if app == nil || app.app == nil { + return + } + CustomEventData := map[string]interface{}{ + "trace_id": trace_id, + "rating": rating, + "category": category, + "message": message, + "ingest_source": "Go", + } + for k, v := range metadata { + CustomEventData[k] = v + } + // if rating is an int or string, record the event + err := app.app.RecordCustomEvent("LlmFeedbackMessage", CustomEventData) + if err != nil { + app.app.Error("unable to record custom event", map[string]interface{}{ + "event-type": "LlmFeedbackMessage", + "reason": err.Error(), + }) + } +} + // RecordCustomMetric records a custom metric. The metric name you // provide will be prefixed by "Custom/". Custom metrics are not // currently supported in serverless mode. @@ -136,7 +162,6 @@ func (app *Application) Shutdown(timeout time.Duration) { // a boolean true value is returned as the second return value. If it is // false, then the Config data returned is the standard default configuration. // This usually occurs if the Application is not yet fully initialized. -// func (app *Application) Config() (Config, bool) { if app == nil || app.app == nil { return defaultConfig(), false diff --git a/v3/newrelic/internal_test.go b/v3/newrelic/internal_test.go index 994ce2c2b..8c44a4e61 100644 --- a/v3/newrelic/internal_test.go +++ b/v3/newrelic/internal_test.go @@ -289,6 +289,26 @@ func testApp(replyfn func(*internal.ConnectReply), cfgfn func(*Config), t testin } } +func TestRecordLLMFeedbackEventSuccess(t *testing.T) { + app := testApp(nil, nil, t) + app.RecordLlmFeedbackEvent("traceid", "5", "informative", "message", validParams) + app.expectNoLoggedErrors(t) + app.ExpectCustomEvents(t, []internal.WantEvent{{ + Intrinsics: map[string]interface{}{ + "type": "LlmFeedbackMessage", + "timestamp": internal.MatchAnything, + }, + UserAttributes: map[string]interface{}{ + "trace_id": "traceid", + "rating": "5", + "category": "informative", + "message": "message", + "ingest_source": "Go", + "zip": 1, + "zap": 2, + }, + }}) +} func TestRecordCustomEventSuccess(t *testing.T) { app := testApp(nil, nil, t) app.RecordCustomEvent("myType", validParams) From 4796c885a742eded99042691aeaa28cc3788f2a4 Mon Sep 17 00:00:00 2001 From: mirackara Date: Fri, 8 Mar 2024 12:36:26 -0600 Subject: [PATCH 3/3] Added support for RecordContent config setting --- v3/newrelic/config.go | 4 ++++ v3/newrelic/config_options.go | 6 ++++++ v3/newrelic/config_test.go | 6 ++++++ v3/newrelic/internal_test.go | 2 +- 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/v3/newrelic/config.go b/v3/newrelic/config.go index a74add79c..3c6f6b6ce 100644 --- a/v3/newrelic/config.go +++ b/v3/newrelic/config.go @@ -242,6 +242,9 @@ type Config struct { Streaming struct { Enabled bool } + RecordContent struct { + Enabled bool + } } // CrossApplicationTracer controls behavior relating to cross application @@ -677,6 +680,7 @@ func defaultConfig() Config { c.Heroku.DynoNamePrefixesToShorten = []string{"scheduler", "run"} c.AIMonitoring.Enabled = false c.AIMonitoring.Streaming.Enabled = true + c.AIMonitoring.RecordContent.Enabled = true c.InfiniteTracing.TraceObserver.Port = 443 c.InfiniteTracing.SpanEvents.QueueSize = 10000 diff --git a/v3/newrelic/config_options.go b/v3/newrelic/config_options.go index 2ccc65fe1..91ba00b59 100644 --- a/v3/newrelic/config_options.go +++ b/v3/newrelic/config_options.go @@ -246,6 +246,12 @@ func ConfigAIMonitoringEnabled(enabled bool) ConfigOption { } } +func ConfigAIMonitoringRecordContentEnabled(enabled bool) ConfigOption { + return func(cfg *Config) { + cfg.AIMonitoring.RecordContent.Enabled = enabled + } +} + // ConfigAppLogMetricsEnabled enables or disables the collection of metrics // data for logs seen by an instrumented logging framework // default: true diff --git a/v3/newrelic/config_test.go b/v3/newrelic/config_test.go index 10b64dfb1..9400a4e20 100644 --- a/v3/newrelic/config_test.go +++ b/v3/newrelic/config_test.go @@ -132,6 +132,9 @@ func TestCopyConfigReferenceFieldsPresent(t *testing.T) { "settings":{ "AIMonitoring": { "Enabled": false, + "RecordContent": { + "Enabled": true + }, "Streaming": { "Enabled": true } @@ -334,6 +337,9 @@ func TestCopyConfigReferenceFieldsAbsent(t *testing.T) { "settings":{ "AIMonitoring": { "Enabled": false, + "RecordContent": { + "Enabled": true + }, "Streaming": { "Enabled": true } diff --git a/v3/newrelic/internal_test.go b/v3/newrelic/internal_test.go index 8c44a4e61..a1deb7878 100644 --- a/v3/newrelic/internal_test.go +++ b/v3/newrelic/internal_test.go @@ -291,7 +291,7 @@ func testApp(replyfn func(*internal.ConnectReply), cfgfn func(*Config), t testin func TestRecordLLMFeedbackEventSuccess(t *testing.T) { app := testApp(nil, nil, t) - app.RecordLlmFeedbackEvent("traceid", "5", "informative", "message", validParams) + app.RecordLLMFeedbackEvent("traceid", "5", "informative", "message", validParams) app.expectNoLoggedErrors(t) app.ExpectCustomEvents(t, []internal.WantEvent{{ Intrinsics: map[string]interface{}{