Skip to content

Commit 4c18d7b

Browse files
Avi-RobustaSheeproidmershal
authored
Newrelic traces improvement (#985)
Co-authored-by: Tomer Keshet <[email protected]> Co-authored-by: mershal <[email protected]>
1 parent 723c118 commit 4c18d7b

File tree

7 files changed

+50
-5
lines changed

7 files changed

+50
-5
lines changed

holmes/core/supabase_dal.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ def extract_relevant_issues(self, evidence):
342342
self.unzip_evidence_file(enrich)
343343
for enrich in evidence.data
344344
if enrich.get("enrichment_type") == "text_file"
345+
or enrich.get("enrichment_type") == "alert_raw_data"
345346
]
346347

347348
data.extend(unzipped_files)

holmes/plugins/toolsets/newrelic/newrelic.jinja2

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,12 @@ Note: Use `SHOW EVENT TYPES` to see all event types in the account, in addition
3131

3232
### 3. Metrics/graphs
3333
- You always need to embed the partial result in your response. Include the "tool_name" and "random_key". For example: << {"type": "newrelicql", "tool_name": "execute_prometheus_range_query", "random_key": "92jf2hf"} >>
34+
35+
### Instructions for Handling Query Results
36+
- If you query DistributedTraceSummary:
37+
- ALWAYS use the filter `WHERE root.span.eventType = 'Span'`
38+
- When querying without aggregations (e.g. without count(*), average(attribute), sum(attribute), min(attribute), etc.):
39+
- ALWAYS include an embed, and don't include the raw results as plain text, for example << {"type": "traces-summary", "tool_name": "newrelic_execute_nrql_query", "random_key": "928js0l"} >>. "random_key" should always be replaced with the "random_key" from the tool's output.
40+
- ALWAYS start by querying all fields using `SELECT * FROM DistributedTraceSummary`. We need as much fields as possible to visualize the traces to the user. However, the trade-off is that we might exceed the context size. In that case, if you need to narrow down your search, follow this strategy: First, select only the essential fields: trace.id, spanCount, root.entity.accountId, root.entity.guid, root.entity.name, root.span.name, timestamp, duration.ms. These are the absolute minimum fields required for the visualization. If that's still failing, add the `LIMIT` keyword to the query. `LIMIT` should always be the second option, we prefer to show the user as much traces as we can.
41+
- When querying with aggregations, NEVER use embeds.
42+
- If you query any other even type (like Span or Transaction), don't use any embeds - return the results as is.

holmes/plugins/toolsets/newrelic/newrelic.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from holmes.plugins.toolsets.newrelic.new_relic_api import NewRelicAPI
1616
import yaml
1717
import json
18+
from holmes.utils.keygen_utils import generate_random_key
1819

1920

2021
class ExecuteNRQLQuery(Tool):
@@ -109,7 +110,21 @@ def _invoke(
109110
result: List[Dict[str, Any]] = api.execute_nrql_query(query)
110111

111112
qtype = params.get("query_type", "").lower()
112-
if qtype == "logs":
113+
114+
if qtype == "traces":
115+
response_data = {
116+
"random_key": generate_random_key(),
117+
"tool_name": self.name,
118+
"query": query,
119+
"data": result,
120+
"is_eu": self._toolset.is_eu_datacenter,
121+
}
122+
return StructuredToolResult(
123+
status=StructuredToolResultStatus.SUCCESS,
124+
data=json.dumps(response_data, indent=2),
125+
params=params,
126+
)
127+
elif qtype == "logs":
113128
formatted = self.format_logs(result)
114129
# For logs we keep your existing YAML output (unchanged)
115130
return StructuredToolResult(

tests/llm/fixtures/test_ask_holmes/117_new_relic_tracing/instrumentation.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
apiVersion: newrelic.com/v1alpha2
1+
# https://docs.newrelic.com/docs/kubernetes-pixie/kubernetes-integration/installation/k8s-agent-operator/
2+
# https://github.com/newrelic/k8s-agents-operator/blob/main/local/instrumentation.yaml
3+
apiVersion: newrelic.com/v1beta2
24
kind: Instrumentation
35
metadata:
46
name: nr-node-app-117
@@ -13,7 +15,7 @@ spec:
1315
operator: "In"
1416
values: ["app-117"]
1517
---
16-
apiVersion: newrelic.com/v1alpha2
18+
apiVersion: newrelic.com/v1beta2
1719
kind: Instrumentation
1820
metadata:
1921
name: nr-python-app-117

tests/llm/fixtures/test_ask_holmes/117_new_relic_tracing/setup.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
kubectl create namespace app-117
1+
kubectl apply -f instrumentation.yaml -n newrelic
22

3-
kubectl apply -f instrumentation.yaml
3+
kubectl create namespace app-117
44

55
kubectl -n app-117 create secret generic checkout-src \
66
--from-file=server.js=checkout/server.js \
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
user_prompt:
2+
- Show me traces for do-fra1-tomer and do-fra1-shahal clusters
3+
4+
expected_output:
5+
- 'The answer should include something similar to << { "type": "traces-summary", "tool_name": "newrelic_execute_nrql_query", "random_key": "<alphanumeric_characters>" } >>. Both tool_name and random_key MUST absolutely be present and the same as mentioned here.'
6+
7+
tags:
8+
- chain-of-causation
9+
- traces
10+
- newrelic
11+
- network
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
toolsets:
2+
newrelic:
3+
enabled: true
4+
config:
5+
nr_account_id: "{{env.NEW_RELIC_ACCOUNT_ID}}"
6+
nr_api_key: "{{env.NEW_RELIC_API_KEY}}"
7+
is_eu_datacenter: false # set "{{env.NEW_RELIC_IS_EU}}" with true to use eu

0 commit comments

Comments
 (0)