holmesgpt 0.12.6__py3-none-any.whl → 0.13.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of holmesgpt might be problematic. Click here for more details.
- holmes/__init__.py +1 -1
- holmes/clients/robusta_client.py +19 -1
- holmes/common/env_vars.py +17 -0
- holmes/config.py +69 -9
- holmes/core/conversations.py +11 -0
- holmes/core/investigation.py +16 -3
- holmes/core/investigation_structured_output.py +12 -0
- holmes/core/llm.py +13 -1
- holmes/core/models.py +9 -1
- holmes/core/openai_formatting.py +72 -12
- holmes/core/prompt.py +13 -0
- holmes/core/supabase_dal.py +3 -0
- holmes/core/todo_manager.py +88 -0
- holmes/core/tool_calling_llm.py +230 -157
- holmes/core/tools.py +10 -1
- holmes/core/tools_utils/tool_executor.py +7 -2
- holmes/core/tools_utils/toolset_utils.py +7 -2
- holmes/core/toolset_manager.py +1 -5
- holmes/core/tracing.py +4 -3
- holmes/interactive.py +1 -0
- holmes/main.py +9 -2
- holmes/plugins/prompts/__init__.py +7 -1
- holmes/plugins/prompts/_current_date_time.jinja2 +1 -0
- holmes/plugins/prompts/_default_log_prompt.jinja2 +4 -2
- holmes/plugins/prompts/_fetch_logs.jinja2 +10 -1
- holmes/plugins/prompts/_general_instructions.jinja2 +14 -0
- holmes/plugins/prompts/_permission_errors.jinja2 +1 -1
- holmes/plugins/prompts/_toolsets_instructions.jinja2 +4 -4
- holmes/plugins/prompts/generic_ask.jinja2 +4 -3
- holmes/plugins/prompts/investigation_procedure.jinja2 +210 -0
- holmes/plugins/prompts/kubernetes_workload_ask.jinja2 +2 -0
- holmes/plugins/runbooks/CLAUDE.md +85 -0
- holmes/plugins/runbooks/README.md +24 -0
- holmes/plugins/toolsets/__init__.py +19 -6
- holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py +27 -0
- holmes/plugins/toolsets/azure_sql/tools/analyze_connection_failures.py +2 -2
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_connections.py +2 -1
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_health_status.py +3 -1
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_performance.py +2 -1
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_storage.py +2 -1
- holmes/plugins/toolsets/azure_sql/tools/get_active_alerts.py +3 -1
- holmes/plugins/toolsets/azure_sql/tools/get_slow_queries.py +2 -1
- holmes/plugins/toolsets/azure_sql/tools/get_top_cpu_queries.py +2 -1
- holmes/plugins/toolsets/azure_sql/tools/get_top_data_io_queries.py +2 -1
- holmes/plugins/toolsets/azure_sql/tools/get_top_log_io_queries.py +2 -1
- holmes/plugins/toolsets/bash/argocd/__init__.py +65 -0
- holmes/plugins/toolsets/bash/argocd/constants.py +120 -0
- holmes/plugins/toolsets/bash/aws/__init__.py +66 -0
- holmes/plugins/toolsets/bash/aws/constants.py +529 -0
- holmes/plugins/toolsets/bash/azure/__init__.py +56 -0
- holmes/plugins/toolsets/bash/azure/constants.py +339 -0
- holmes/plugins/toolsets/bash/bash_instructions.jinja2 +6 -7
- holmes/plugins/toolsets/bash/bash_toolset.py +47 -13
- holmes/plugins/toolsets/bash/common/bash_command.py +131 -0
- holmes/plugins/toolsets/bash/common/stringify.py +14 -1
- holmes/plugins/toolsets/bash/common/validators.py +91 -0
- holmes/plugins/toolsets/bash/docker/__init__.py +59 -0
- holmes/plugins/toolsets/bash/docker/constants.py +255 -0
- holmes/plugins/toolsets/bash/helm/__init__.py +61 -0
- holmes/plugins/toolsets/bash/helm/constants.py +92 -0
- holmes/plugins/toolsets/bash/kubectl/__init__.py +80 -79
- holmes/plugins/toolsets/bash/kubectl/constants.py +0 -14
- holmes/plugins/toolsets/bash/kubectl/kubectl_describe.py +38 -56
- holmes/plugins/toolsets/bash/kubectl/kubectl_events.py +28 -76
- holmes/plugins/toolsets/bash/kubectl/kubectl_get.py +39 -99
- holmes/plugins/toolsets/bash/kubectl/kubectl_logs.py +34 -15
- holmes/plugins/toolsets/bash/kubectl/kubectl_run.py +1 -1
- holmes/plugins/toolsets/bash/kubectl/kubectl_top.py +38 -77
- holmes/plugins/toolsets/bash/parse_command.py +106 -32
- holmes/plugins/toolsets/bash/utilities/__init__.py +0 -0
- holmes/plugins/toolsets/bash/utilities/base64_util.py +12 -0
- holmes/plugins/toolsets/bash/utilities/cut.py +12 -0
- holmes/plugins/toolsets/bash/utilities/grep/__init__.py +10 -0
- holmes/plugins/toolsets/bash/utilities/head.py +12 -0
- holmes/plugins/toolsets/bash/utilities/jq.py +79 -0
- holmes/plugins/toolsets/bash/utilities/sed.py +164 -0
- holmes/plugins/toolsets/bash/utilities/sort.py +15 -0
- holmes/plugins/toolsets/bash/utilities/tail.py +12 -0
- holmes/plugins/toolsets/bash/utilities/tr.py +57 -0
- holmes/plugins/toolsets/bash/utilities/uniq.py +12 -0
- holmes/plugins/toolsets/bash/utilities/wc.py +12 -0
- holmes/plugins/toolsets/coralogix/api.py +6 -6
- holmes/plugins/toolsets/coralogix/toolset_coralogix_logs.py +7 -1
- holmes/plugins/toolsets/datadog/datadog_api.py +20 -8
- holmes/plugins/toolsets/datadog/datadog_metrics_instructions.jinja2 +8 -1
- holmes/plugins/toolsets/datadog/datadog_rds_instructions.jinja2 +82 -0
- holmes/plugins/toolsets/datadog/toolset_datadog_logs.py +12 -5
- holmes/plugins/toolsets/datadog/toolset_datadog_metrics.py +20 -11
- holmes/plugins/toolsets/datadog/toolset_datadog_rds.py +735 -0
- holmes/plugins/toolsets/datadog/toolset_datadog_traces.py +18 -11
- holmes/plugins/toolsets/git.py +15 -15
- holmes/plugins/toolsets/grafana/grafana_api.py +12 -1
- holmes/plugins/toolsets/grafana/toolset_grafana.py +5 -1
- holmes/plugins/toolsets/grafana/toolset_grafana_loki.py +9 -4
- holmes/plugins/toolsets/grafana/toolset_grafana_tempo.py +12 -5
- holmes/plugins/toolsets/internet/internet.py +2 -1
- holmes/plugins/toolsets/internet/notion.py +2 -1
- holmes/plugins/toolsets/investigator/__init__.py +0 -0
- holmes/plugins/toolsets/investigator/core_investigation.py +157 -0
- holmes/plugins/toolsets/investigator/investigator_instructions.jinja2 +253 -0
- holmes/plugins/toolsets/investigator/model.py +15 -0
- holmes/plugins/toolsets/kafka.py +14 -7
- holmes/plugins/toolsets/kubernetes_logs.py +454 -25
- holmes/plugins/toolsets/logging_utils/logging_api.py +115 -55
- holmes/plugins/toolsets/mcp/toolset_mcp.py +1 -1
- holmes/plugins/toolsets/newrelic.py +8 -3
- holmes/plugins/toolsets/opensearch/opensearch.py +8 -4
- holmes/plugins/toolsets/opensearch/opensearch_logs.py +9 -2
- holmes/plugins/toolsets/opensearch/opensearch_traces.py +6 -2
- holmes/plugins/toolsets/prometheus/prometheus.py +179 -44
- holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py +8 -2
- holmes/plugins/toolsets/robusta/robusta.py +4 -4
- holmes/plugins/toolsets/runbook/runbook_fetcher.py +6 -5
- holmes/plugins/toolsets/servicenow/servicenow.py +18 -3
- holmes/plugins/toolsets/utils.py +8 -1
- holmes/utils/console/logging.py +6 -1
- holmes/utils/llms.py +20 -0
- holmes/utils/stream.py +90 -0
- {holmesgpt-0.12.6.dist-info → holmesgpt-0.13.1.dist-info}/METADATA +47 -34
- {holmesgpt-0.12.6.dist-info → holmesgpt-0.13.1.dist-info}/RECORD +123 -91
- holmes/plugins/toolsets/bash/grep/__init__.py +0 -52
- holmes/utils/robusta.py +0 -9
- {holmesgpt-0.12.6.dist-info → holmesgpt-0.13.1.dist-info}/LICENSE.txt +0 -0
- {holmesgpt-0.12.6.dist-info → holmesgpt-0.13.1.dist-info}/WHEEL +0 -0
- {holmesgpt-0.12.6.dist-info → holmesgpt-0.13.1.dist-info}/entry_points.txt +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
2
|
from datetime import datetime, timedelta
|
|
3
3
|
import logging
|
|
4
|
-
from typing import Optional
|
|
4
|
+
from typing import Optional, Set
|
|
5
|
+
from enum import Enum
|
|
5
6
|
|
|
6
|
-
from pydantic import BaseModel
|
|
7
|
+
from pydantic import BaseModel, field_validator
|
|
7
8
|
from datetime import timezone
|
|
8
9
|
from holmes.core.tools import (
|
|
9
10
|
StructuredToolResult,
|
|
@@ -14,12 +15,20 @@ from holmes.core.tools import (
|
|
|
14
15
|
from holmes.plugins.toolsets.utils import get_param_or_raise
|
|
15
16
|
|
|
16
17
|
# Default values for log fetching
|
|
17
|
-
DEFAULT_LOG_LIMIT =
|
|
18
|
-
|
|
18
|
+
DEFAULT_LOG_LIMIT = 100
|
|
19
|
+
SECONDS_PER_DAY = 24 * 60 * 60
|
|
20
|
+
DEFAULT_TIME_SPAN_SECONDS = 7 * SECONDS_PER_DAY # 1 week in seconds
|
|
19
21
|
|
|
20
22
|
POD_LOGGING_TOOL_NAME = "fetch_pod_logs"
|
|
21
23
|
|
|
22
24
|
|
|
25
|
+
class LoggingCapability(str, Enum):
|
|
26
|
+
"""Optional advanced logging capabilities"""
|
|
27
|
+
|
|
28
|
+
REGEX_FILTER = "regex_filter" # If not supported, falls back to substring matching
|
|
29
|
+
EXCLUDE_FILTER = "exclude_filter" # If not supported, parameter is not shown at all
|
|
30
|
+
|
|
31
|
+
|
|
23
32
|
class LoggingConfig(BaseModel):
|
|
24
33
|
"""Base configuration for all logging backends"""
|
|
25
34
|
|
|
@@ -32,12 +41,27 @@ class FetchPodLogsParams(BaseModel):
|
|
|
32
41
|
start_time: Optional[str] = None
|
|
33
42
|
end_time: Optional[str] = None
|
|
34
43
|
filter: Optional[str] = None
|
|
44
|
+
exclude_filter: Optional[str] = None
|
|
35
45
|
limit: Optional[int] = None
|
|
36
46
|
|
|
47
|
+
@field_validator("start_time", mode="before")
|
|
48
|
+
@classmethod
|
|
49
|
+
def convert_start_time_to_string(cls, v):
|
|
50
|
+
"""Convert integer start_time values to strings."""
|
|
51
|
+
if v is not None and isinstance(v, int):
|
|
52
|
+
return str(v)
|
|
53
|
+
return v
|
|
54
|
+
|
|
37
55
|
|
|
38
56
|
class BasePodLoggingToolset(Toolset, ABC):
|
|
39
57
|
"""Base class for all logging toolsets"""
|
|
40
58
|
|
|
59
|
+
@property
|
|
60
|
+
@abstractmethod
|
|
61
|
+
def supported_capabilities(self) -> Set[LoggingCapability]:
|
|
62
|
+
"""Return the set of optional capabilities supported by this provider"""
|
|
63
|
+
pass
|
|
64
|
+
|
|
41
65
|
@abstractmethod
|
|
42
66
|
def fetch_pod_logs(self, params: FetchPodLogsParams) -> StructuredToolResult:
|
|
43
67
|
pass
|
|
@@ -50,42 +74,96 @@ class PodLoggingTool(Tool):
|
|
|
50
74
|
"""Common tool for fetching pod logs across different logging backends"""
|
|
51
75
|
|
|
52
76
|
def __init__(self, toolset: BasePodLoggingToolset):
|
|
77
|
+
# Get parameters dynamically based on what the toolset supports
|
|
78
|
+
parameters = self._get_tool_parameters(toolset)
|
|
79
|
+
|
|
80
|
+
# Build description based on capabilities
|
|
81
|
+
description = "Fetch logs for a Kubernetes pod"
|
|
82
|
+
capabilities = toolset.supported_capabilities
|
|
83
|
+
|
|
84
|
+
if (
|
|
85
|
+
LoggingCapability.REGEX_FILTER in capabilities
|
|
86
|
+
and LoggingCapability.EXCLUDE_FILTER in capabilities
|
|
87
|
+
):
|
|
88
|
+
description += " with support for regex filtering and exclusion patterns"
|
|
89
|
+
elif LoggingCapability.REGEX_FILTER in capabilities:
|
|
90
|
+
description += " with support for regex filtering"
|
|
91
|
+
|
|
92
|
+
# Add default information
|
|
93
|
+
description += f". Defaults: Fetches last {DEFAULT_TIME_SPAN_SECONDS // SECONDS_PER_DAY} days of logs, limited to {DEFAULT_LOG_LIMIT} most recent entries"
|
|
94
|
+
|
|
53
95
|
super().__init__(
|
|
54
96
|
name=POD_LOGGING_TOOL_NAME,
|
|
55
|
-
description=
|
|
56
|
-
parameters=
|
|
57
|
-
"pod_name": ToolParameter(
|
|
58
|
-
description="The exact kubernetes pod name",
|
|
59
|
-
type="string",
|
|
60
|
-
required=True,
|
|
61
|
-
),
|
|
62
|
-
"namespace": ToolParameter(
|
|
63
|
-
description="Kubernetes namespace", type="string", required=True
|
|
64
|
-
),
|
|
65
|
-
"start_time": ToolParameter(
|
|
66
|
-
description="Start time for logs. Can be an RFC3339 formatted datetime (e.g. '2023-03-01T10:30:00Z') for absolute time or a negative integer (e.g. -3600) for relative seconds before end_time.",
|
|
67
|
-
type="string",
|
|
68
|
-
required=False,
|
|
69
|
-
),
|
|
70
|
-
"end_time": ToolParameter(
|
|
71
|
-
description="End time for logs. Must be an RFC3339 formatted datetime (e.g. '2023-03-01T12:30:00Z'). If not specified, defaults to current time.",
|
|
72
|
-
type="string",
|
|
73
|
-
required=False,
|
|
74
|
-
),
|
|
75
|
-
"limit": ToolParameter(
|
|
76
|
-
description="Maximum number of logs to return",
|
|
77
|
-
type="integer",
|
|
78
|
-
required=False,
|
|
79
|
-
),
|
|
80
|
-
"filter": ToolParameter(
|
|
81
|
-
description="An optional keyword or sentence to filter the logs",
|
|
82
|
-
type="string",
|
|
83
|
-
required=False,
|
|
84
|
-
),
|
|
85
|
-
},
|
|
97
|
+
description=description,
|
|
98
|
+
parameters=parameters,
|
|
86
99
|
)
|
|
87
100
|
self._toolset = toolset
|
|
88
101
|
|
|
102
|
+
def _get_tool_parameters(self, toolset: BasePodLoggingToolset) -> dict:
|
|
103
|
+
"""Generate parameters based on what this provider supports"""
|
|
104
|
+
# Base parameters always available
|
|
105
|
+
params = {
|
|
106
|
+
"pod_name": ToolParameter(
|
|
107
|
+
description="The exact kubernetes pod name",
|
|
108
|
+
type="string",
|
|
109
|
+
required=True,
|
|
110
|
+
),
|
|
111
|
+
"namespace": ToolParameter(
|
|
112
|
+
description="Kubernetes namespace", type="string", required=True
|
|
113
|
+
),
|
|
114
|
+
"start_time": ToolParameter(
|
|
115
|
+
description=f"Start time for logs. Can be an RFC3339 formatted datetime (e.g. '2023-03-01T10:30:00Z') for absolute time or a negative string number (e.g. -3600) for relative seconds before end_time. Default: -{DEFAULT_TIME_SPAN_SECONDS} (last {DEFAULT_TIME_SPAN_SECONDS // SECONDS_PER_DAY} days)",
|
|
116
|
+
type="string",
|
|
117
|
+
required=False,
|
|
118
|
+
),
|
|
119
|
+
"end_time": ToolParameter(
|
|
120
|
+
description="End time for logs. Must be an RFC3339 formatted datetime (e.g. '2023-03-01T12:30:00Z'). If not specified, defaults to current time.",
|
|
121
|
+
type="string",
|
|
122
|
+
required=False,
|
|
123
|
+
),
|
|
124
|
+
"limit": ToolParameter(
|
|
125
|
+
description=f"Maximum number of logs to return. Default: {DEFAULT_LOG_LIMIT}",
|
|
126
|
+
type="integer",
|
|
127
|
+
required=False,
|
|
128
|
+
),
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# Add filter - description changes based on regex support
|
|
132
|
+
if LoggingCapability.REGEX_FILTER in toolset.supported_capabilities:
|
|
133
|
+
params["filter"] = ToolParameter(
|
|
134
|
+
description="""An optional filter for logs - can be a simple keyword/phrase or a regex pattern (case-insensitive).
|
|
135
|
+
Examples of useful filters:
|
|
136
|
+
- For errors: filter='err|error|fatal|critical|fail|exception|panic|crash'
|
|
137
|
+
- For warnings: filter='warn|warning|caution'
|
|
138
|
+
- For specific HTTP errors: filter='5[0-9]{2}|404|403'
|
|
139
|
+
- For Java exceptions: filter='Exception|Error|Throwable|StackTrace'
|
|
140
|
+
- For timeouts: filter='timeout|timed out|deadline exceeded'
|
|
141
|
+
If you get no results with a filter, try a broader pattern or drop the filter.""",
|
|
142
|
+
type="string",
|
|
143
|
+
required=False,
|
|
144
|
+
)
|
|
145
|
+
else:
|
|
146
|
+
params["filter"] = ToolParameter(
|
|
147
|
+
description="An optional keyword to filter logs - matches logs containing this text (case-insensitive)",
|
|
148
|
+
type="string",
|
|
149
|
+
required=False,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
# ONLY add exclude_filter if supported - otherwise it doesn't exist
|
|
153
|
+
if LoggingCapability.EXCLUDE_FILTER in toolset.supported_capabilities:
|
|
154
|
+
params["exclude_filter"] = ToolParameter(
|
|
155
|
+
description="""An optional exclusion filter - logs matching this pattern will be excluded. Can be a simple keyword or regex pattern (case-insensitive).
|
|
156
|
+
Examples of useful exclude filters:
|
|
157
|
+
- Exclude HTTP 200s: exclude_filter='GET.*200|POST.*200'
|
|
158
|
+
- Exclude health/metrics: exclude_filter='health|metrics|ping|heartbeat'
|
|
159
|
+
- Exclude specific log levels: exclude_filter='"level": "INFO"'
|
|
160
|
+
If you hit the log limit and see lots of repetitive INFO logs, use exclude_filter to remove the noise and focus on what matters.""",
|
|
161
|
+
type="string",
|
|
162
|
+
required=False,
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
return params
|
|
166
|
+
|
|
89
167
|
def _invoke(self, params: dict) -> StructuredToolResult:
|
|
90
168
|
structured_params = FetchPodLogsParams(
|
|
91
169
|
namespace=get_param_or_raise(params, "namespace"),
|
|
@@ -93,6 +171,7 @@ class PodLoggingTool(Tool):
|
|
|
93
171
|
start_time=params.get("start_time"),
|
|
94
172
|
end_time=params.get("end_time"),
|
|
95
173
|
filter=params.get("filter"),
|
|
174
|
+
exclude_filter=params.get("exclude_filter"),
|
|
96
175
|
limit=params.get("limit"),
|
|
97
176
|
)
|
|
98
177
|
|
|
@@ -107,29 +186,10 @@ class PodLoggingTool(Tool):
|
|
|
107
186
|
namespace = params.get("namespace", "unknown-namespace")
|
|
108
187
|
pod_name = params.get("pod_name", "unknown-pod")
|
|
109
188
|
|
|
110
|
-
start_time = params.get("start_time")
|
|
111
|
-
end_time = params.get("end_time")
|
|
112
|
-
filter = params.get("filter")
|
|
113
|
-
limit = params.get("limit")
|
|
114
|
-
|
|
115
|
-
extra_params_str = ""
|
|
116
|
-
|
|
117
|
-
if start_time and not end_time:
|
|
118
|
-
extra_params_str += f" start_time={start_time}"
|
|
119
|
-
elif not start_time and end_time:
|
|
120
|
-
extra_params_str += f" end_time={end_time}"
|
|
121
|
-
elif start_time and end_time:
|
|
122
|
-
extra_params_str += f" time range={start_time}/{end_time}"
|
|
123
|
-
|
|
124
|
-
if filter:
|
|
125
|
-
extra_params_str += f" filter={filter}"
|
|
126
|
-
if limit:
|
|
127
|
-
extra_params_str += f" limit={limit}"
|
|
128
|
-
|
|
129
189
|
logger_name = (
|
|
130
190
|
f"{self._toolset.logger_name()}: " if self._toolset.logger_name() else ""
|
|
131
191
|
)
|
|
132
|
-
return f"{logger_name}
|
|
192
|
+
return f"{logger_name}Fetch Logs (pod={pod_name}, namespace={namespace})"
|
|
133
193
|
|
|
134
194
|
|
|
135
195
|
def process_time_parameters(
|
|
@@ -83,7 +83,7 @@ class RemoteMCPTool(Tool):
|
|
|
83
83
|
return parameters
|
|
84
84
|
|
|
85
85
|
def get_parameterized_one_liner(self, params: Dict) -> str:
|
|
86
|
-
return f"Call
|
|
86
|
+
return f"Call MCP Server ({self.url} - {self.name})"
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
class RemoteMCPToolset(Toolset):
|
|
@@ -10,6 +10,7 @@ from holmes.core.tools import (
|
|
|
10
10
|
)
|
|
11
11
|
from pydantic import BaseModel
|
|
12
12
|
from holmes.core.tools import StructuredToolResult, ToolResultStatus
|
|
13
|
+
from holmes.plugins.toolsets.utils import toolset_name_for_one_liner
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class BaseNewRelicTool(Tool):
|
|
@@ -89,7 +90,9 @@ class GetLogs(BaseNewRelicTool):
|
|
|
89
90
|
return error(f"Error while fetching logs: {str(e)}")
|
|
90
91
|
|
|
91
92
|
def get_parameterized_one_liner(self, params) -> str:
|
|
92
|
-
|
|
93
|
+
app = params.get("app", "")
|
|
94
|
+
since = params.get("since", "")
|
|
95
|
+
return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Logs ({app} - {since})"
|
|
93
96
|
|
|
94
97
|
|
|
95
98
|
class GetTraces(BaseNewRelicTool):
|
|
@@ -171,8 +174,10 @@ class GetTraces(BaseNewRelicTool):
|
|
|
171
174
|
|
|
172
175
|
def get_parameterized_one_liner(self, params) -> str:
|
|
173
176
|
if "trace_id" in params and params["trace_id"]:
|
|
174
|
-
|
|
175
|
-
|
|
177
|
+
trace_id = params.get("trace_id", "")
|
|
178
|
+
return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Trace Details ({trace_id})"
|
|
179
|
+
duration = params.get("duration", "")
|
|
180
|
+
return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Traces (>{duration}s)"
|
|
176
181
|
|
|
177
182
|
|
|
178
183
|
class NewrelicConfig(BaseModel):
|
|
@@ -14,6 +14,7 @@ from holmes.core.tools import (
|
|
|
14
14
|
ToolsetTag,
|
|
15
15
|
)
|
|
16
16
|
from holmes.plugins.toolsets.consts import TOOLSET_CONFIG_MISSING_ERROR
|
|
17
|
+
from holmes.plugins.toolsets.utils import toolset_name_for_one_liner
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class OpenSearchHttpAuth(BaseModel):
|
|
@@ -102,7 +103,8 @@ class ListShards(BaseOpenSearchTool):
|
|
|
102
103
|
)
|
|
103
104
|
|
|
104
105
|
def get_parameterized_one_liner(self, params: Dict) -> str:
|
|
105
|
-
|
|
106
|
+
host = params.get("host", "")
|
|
107
|
+
return f"{toolset_name_for_one_liner(self.toolset.name)}: List Shards ({host})"
|
|
106
108
|
|
|
107
109
|
|
|
108
110
|
class GetClusterSettings(BaseOpenSearchTool):
|
|
@@ -132,7 +134,8 @@ class GetClusterSettings(BaseOpenSearchTool):
|
|
|
132
134
|
)
|
|
133
135
|
|
|
134
136
|
def get_parameterized_one_liner(self, params) -> str:
|
|
135
|
-
|
|
137
|
+
host = params.get("host", "")
|
|
138
|
+
return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Cluster Settings ({host})"
|
|
136
139
|
|
|
137
140
|
|
|
138
141
|
class GetClusterHealth(BaseOpenSearchTool):
|
|
@@ -160,7 +163,8 @@ class GetClusterHealth(BaseOpenSearchTool):
|
|
|
160
163
|
)
|
|
161
164
|
|
|
162
165
|
def get_parameterized_one_liner(self, params) -> str:
|
|
163
|
-
|
|
166
|
+
host = params.get("host", "")
|
|
167
|
+
return f"{toolset_name_for_one_liner(self.toolset.name)}: Check Cluster Health ({host})"
|
|
164
168
|
|
|
165
169
|
|
|
166
170
|
class ListOpenSearchHosts(BaseOpenSearchTool):
|
|
@@ -181,7 +185,7 @@ class ListOpenSearchHosts(BaseOpenSearchTool):
|
|
|
181
185
|
)
|
|
182
186
|
|
|
183
187
|
def get_parameterized_one_liner(self, params: Dict) -> str:
|
|
184
|
-
return "
|
|
188
|
+
return f"{toolset_name_for_one_liner(self.toolset.name)}: List OpenSearch Hosts"
|
|
185
189
|
|
|
186
190
|
|
|
187
191
|
class OpenSearchToolset(Toolset):
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any, Dict, Optional, Tuple
|
|
2
|
+
from typing import Any, Dict, Optional, Tuple, Set
|
|
3
3
|
|
|
4
4
|
import requests # type: ignore
|
|
5
5
|
from requests import RequestException # type: ignore
|
|
@@ -14,8 +14,10 @@ from holmes.core.tools import (
|
|
|
14
14
|
from holmes.plugins.toolsets.logging_utils.logging_api import (
|
|
15
15
|
BasePodLoggingToolset,
|
|
16
16
|
FetchPodLogsParams,
|
|
17
|
+
LoggingCapability,
|
|
17
18
|
PodLoggingTool,
|
|
18
19
|
process_time_parameters,
|
|
20
|
+
DEFAULT_TIME_SPAN_SECONDS,
|
|
19
21
|
)
|
|
20
22
|
from holmes.plugins.toolsets.opensearch.opensearch_utils import (
|
|
21
23
|
OpenSearchLoggingConfig,
|
|
@@ -31,6 +33,11 @@ LOGS_FIELDS_CACHE_KEY = "cached_logs_fields"
|
|
|
31
33
|
class OpenSearchLogsToolset(BasePodLoggingToolset):
|
|
32
34
|
"""Implementation of the unified logging API for OpenSearch logs"""
|
|
33
35
|
|
|
36
|
+
@property
|
|
37
|
+
def supported_capabilities(self) -> Set[LoggingCapability]:
|
|
38
|
+
"""OpenSearch only supports phrase matching, not regex or exclude filters"""
|
|
39
|
+
return set() # No regex support, no exclude filter
|
|
40
|
+
|
|
34
41
|
def __init__(self):
|
|
35
42
|
super().__init__(
|
|
36
43
|
name="opensearch/logs",
|
|
@@ -82,7 +89,7 @@ class OpenSearchLogsToolset(BasePodLoggingToolset):
|
|
|
82
89
|
end_time = None
|
|
83
90
|
if params.start_time or params.end_time:
|
|
84
91
|
start_time, end_time = process_time_parameters(
|
|
85
|
-
params.start_time, params.end_time
|
|
92
|
+
params.start_time, params.end_time, DEFAULT_TIME_SPAN_SECONDS
|
|
86
93
|
)
|
|
87
94
|
|
|
88
95
|
query = build_query(
|
|
@@ -20,6 +20,7 @@ from holmes.plugins.toolsets.opensearch.opensearch_utils import (
|
|
|
20
20
|
get_search_url,
|
|
21
21
|
)
|
|
22
22
|
from holmes.core.tools import StructuredToolResult, ToolResultStatus
|
|
23
|
+
from holmes.plugins.toolsets.utils import toolset_name_for_one_liner
|
|
23
24
|
|
|
24
25
|
TRACES_FIELDS_CACHE_KEY = "cached_traces_fields"
|
|
25
26
|
|
|
@@ -108,7 +109,7 @@ class GetTracesFields(Tool):
|
|
|
108
109
|
)
|
|
109
110
|
|
|
110
111
|
def get_parameterized_one_liner(self, params) -> str:
|
|
111
|
-
return "
|
|
112
|
+
return f"{toolset_name_for_one_liner(self._toolset.name)}: List Trace Fields"
|
|
112
113
|
|
|
113
114
|
|
|
114
115
|
class TracesSearchQuery(Tool):
|
|
@@ -184,7 +185,10 @@ class TracesSearchQuery(Tool):
|
|
|
184
185
|
)
|
|
185
186
|
|
|
186
187
|
def get_parameterized_one_liner(self, params) -> str:
|
|
187
|
-
|
|
188
|
+
query = params.get("query", "")
|
|
189
|
+
return (
|
|
190
|
+
f"{toolset_name_for_one_liner(self._toolset.name)}: Search Traces ({query})"
|
|
191
|
+
)
|
|
188
192
|
|
|
189
193
|
|
|
190
194
|
class OpenSearchTracesToolset(BaseOpenSearchToolset):
|