holmesgpt 0.11.5__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/.git_archival.json +7 -0
- holmes/__init__.py +76 -0
- holmes/__init__.py.bak +76 -0
- holmes/clients/robusta_client.py +24 -0
- holmes/common/env_vars.py +47 -0
- holmes/config.py +526 -0
- holmes/core/__init__.py +0 -0
- holmes/core/conversations.py +578 -0
- holmes/core/investigation.py +152 -0
- holmes/core/investigation_structured_output.py +264 -0
- holmes/core/issue.py +54 -0
- holmes/core/llm.py +250 -0
- holmes/core/models.py +157 -0
- holmes/core/openai_formatting.py +51 -0
- holmes/core/performance_timing.py +72 -0
- holmes/core/prompt.py +42 -0
- holmes/core/resource_instruction.py +17 -0
- holmes/core/runbooks.py +26 -0
- holmes/core/safeguards.py +120 -0
- holmes/core/supabase_dal.py +540 -0
- holmes/core/tool_calling_llm.py +798 -0
- holmes/core/tools.py +566 -0
- holmes/core/tools_utils/__init__.py +0 -0
- holmes/core/tools_utils/tool_executor.py +65 -0
- holmes/core/tools_utils/toolset_utils.py +52 -0
- holmes/core/toolset_manager.py +418 -0
- holmes/interactive.py +229 -0
- holmes/main.py +1041 -0
- holmes/plugins/__init__.py +0 -0
- holmes/plugins/destinations/__init__.py +6 -0
- holmes/plugins/destinations/slack/__init__.py +2 -0
- holmes/plugins/destinations/slack/plugin.py +163 -0
- holmes/plugins/interfaces.py +32 -0
- holmes/plugins/prompts/__init__.py +48 -0
- holmes/plugins/prompts/_current_date_time.jinja2 +1 -0
- holmes/plugins/prompts/_default_log_prompt.jinja2 +11 -0
- holmes/plugins/prompts/_fetch_logs.jinja2 +36 -0
- holmes/plugins/prompts/_general_instructions.jinja2 +86 -0
- holmes/plugins/prompts/_global_instructions.jinja2 +12 -0
- holmes/plugins/prompts/_runbook_instructions.jinja2 +13 -0
- holmes/plugins/prompts/_toolsets_instructions.jinja2 +56 -0
- holmes/plugins/prompts/generic_ask.jinja2 +36 -0
- holmes/plugins/prompts/generic_ask_conversation.jinja2 +32 -0
- holmes/plugins/prompts/generic_ask_for_issue_conversation.jinja2 +50 -0
- holmes/plugins/prompts/generic_investigation.jinja2 +42 -0
- holmes/plugins/prompts/generic_post_processing.jinja2 +13 -0
- holmes/plugins/prompts/generic_ticket.jinja2 +12 -0
- holmes/plugins/prompts/investigation_output_format.jinja2 +32 -0
- holmes/plugins/prompts/kubernetes_workload_ask.jinja2 +84 -0
- holmes/plugins/prompts/kubernetes_workload_chat.jinja2 +39 -0
- holmes/plugins/runbooks/README.md +22 -0
- holmes/plugins/runbooks/__init__.py +100 -0
- holmes/plugins/runbooks/catalog.json +14 -0
- holmes/plugins/runbooks/jira.yaml +12 -0
- holmes/plugins/runbooks/kube-prometheus-stack.yaml +10 -0
- holmes/plugins/runbooks/networking/dns_troubleshooting_instructions.md +66 -0
- holmes/plugins/runbooks/upgrade/upgrade_troubleshooting_instructions.md +44 -0
- holmes/plugins/sources/github/__init__.py +77 -0
- holmes/plugins/sources/jira/__init__.py +123 -0
- holmes/plugins/sources/opsgenie/__init__.py +93 -0
- holmes/plugins/sources/pagerduty/__init__.py +147 -0
- holmes/plugins/sources/prometheus/__init__.py +0 -0
- holmes/plugins/sources/prometheus/models.py +104 -0
- holmes/plugins/sources/prometheus/plugin.py +154 -0
- holmes/plugins/toolsets/__init__.py +171 -0
- holmes/plugins/toolsets/aks-node-health.yaml +65 -0
- holmes/plugins/toolsets/aks.yaml +86 -0
- holmes/plugins/toolsets/argocd.yaml +70 -0
- holmes/plugins/toolsets/atlas_mongodb/instructions.jinja2 +8 -0
- holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py +307 -0
- holmes/plugins/toolsets/aws.yaml +76 -0
- holmes/plugins/toolsets/azure_sql/__init__.py +0 -0
- holmes/plugins/toolsets/azure_sql/apis/alert_monitoring_api.py +600 -0
- holmes/plugins/toolsets/azure_sql/apis/azure_sql_api.py +309 -0
- holmes/plugins/toolsets/azure_sql/apis/connection_failure_api.py +445 -0
- holmes/plugins/toolsets/azure_sql/apis/connection_monitoring_api.py +251 -0
- holmes/plugins/toolsets/azure_sql/apis/storage_analysis_api.py +317 -0
- holmes/plugins/toolsets/azure_sql/azure_base_toolset.py +55 -0
- holmes/plugins/toolsets/azure_sql/azure_sql_instructions.jinja2 +137 -0
- holmes/plugins/toolsets/azure_sql/azure_sql_toolset.py +183 -0
- holmes/plugins/toolsets/azure_sql/install.md +66 -0
- holmes/plugins/toolsets/azure_sql/tools/__init__.py +1 -0
- holmes/plugins/toolsets/azure_sql/tools/analyze_connection_failures.py +324 -0
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_connections.py +243 -0
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_health_status.py +205 -0
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_performance.py +249 -0
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_storage.py +373 -0
- holmes/plugins/toolsets/azure_sql/tools/get_active_alerts.py +237 -0
- holmes/plugins/toolsets/azure_sql/tools/get_slow_queries.py +172 -0
- holmes/plugins/toolsets/azure_sql/tools/get_top_cpu_queries.py +170 -0
- holmes/plugins/toolsets/azure_sql/tools/get_top_data_io_queries.py +188 -0
- holmes/plugins/toolsets/azure_sql/tools/get_top_log_io_queries.py +180 -0
- holmes/plugins/toolsets/azure_sql/utils.py +83 -0
- holmes/plugins/toolsets/bash/__init__.py +0 -0
- holmes/plugins/toolsets/bash/bash_instructions.jinja2 +14 -0
- holmes/plugins/toolsets/bash/bash_toolset.py +208 -0
- holmes/plugins/toolsets/bash/common/bash.py +52 -0
- holmes/plugins/toolsets/bash/common/config.py +14 -0
- holmes/plugins/toolsets/bash/common/stringify.py +25 -0
- holmes/plugins/toolsets/bash/common/validators.py +24 -0
- holmes/plugins/toolsets/bash/grep/__init__.py +52 -0
- holmes/plugins/toolsets/bash/kubectl/__init__.py +100 -0
- holmes/plugins/toolsets/bash/kubectl/constants.py +96 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_describe.py +66 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_events.py +88 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_get.py +108 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_logs.py +20 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_run.py +46 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_top.py +81 -0
- holmes/plugins/toolsets/bash/parse_command.py +103 -0
- holmes/plugins/toolsets/confluence.yaml +19 -0
- holmes/plugins/toolsets/consts.py +5 -0
- holmes/plugins/toolsets/coralogix/api.py +158 -0
- holmes/plugins/toolsets/coralogix/toolset_coralogix_logs.py +103 -0
- holmes/plugins/toolsets/coralogix/utils.py +181 -0
- holmes/plugins/toolsets/datadog.py +153 -0
- holmes/plugins/toolsets/docker.yaml +46 -0
- holmes/plugins/toolsets/git.py +756 -0
- holmes/plugins/toolsets/grafana/__init__.py +0 -0
- holmes/plugins/toolsets/grafana/base_grafana_toolset.py +54 -0
- holmes/plugins/toolsets/grafana/common.py +68 -0
- holmes/plugins/toolsets/grafana/grafana_api.py +31 -0
- holmes/plugins/toolsets/grafana/loki_api.py +89 -0
- holmes/plugins/toolsets/grafana/tempo_api.py +124 -0
- holmes/plugins/toolsets/grafana/toolset_grafana.py +102 -0
- holmes/plugins/toolsets/grafana/toolset_grafana_loki.py +102 -0
- holmes/plugins/toolsets/grafana/toolset_grafana_tempo.jinja2 +10 -0
- holmes/plugins/toolsets/grafana/toolset_grafana_tempo.py +299 -0
- holmes/plugins/toolsets/grafana/trace_parser.py +195 -0
- holmes/plugins/toolsets/helm.yaml +42 -0
- holmes/plugins/toolsets/internet/internet.py +275 -0
- holmes/plugins/toolsets/internet/notion.py +137 -0
- holmes/plugins/toolsets/kafka.py +638 -0
- holmes/plugins/toolsets/kubernetes.yaml +255 -0
- holmes/plugins/toolsets/kubernetes_logs.py +426 -0
- holmes/plugins/toolsets/kubernetes_logs.yaml +42 -0
- holmes/plugins/toolsets/logging_utils/__init__.py +0 -0
- holmes/plugins/toolsets/logging_utils/logging_api.py +217 -0
- holmes/plugins/toolsets/logging_utils/types.py +0 -0
- holmes/plugins/toolsets/mcp/toolset_mcp.py +135 -0
- holmes/plugins/toolsets/newrelic.py +222 -0
- holmes/plugins/toolsets/opensearch/__init__.py +0 -0
- holmes/plugins/toolsets/opensearch/opensearch.py +245 -0
- holmes/plugins/toolsets/opensearch/opensearch_logs.py +151 -0
- holmes/plugins/toolsets/opensearch/opensearch_traces.py +211 -0
- holmes/plugins/toolsets/opensearch/opensearch_traces_instructions.jinja2 +12 -0
- holmes/plugins/toolsets/opensearch/opensearch_utils.py +166 -0
- holmes/plugins/toolsets/prometheus/prometheus.py +818 -0
- holmes/plugins/toolsets/prometheus/prometheus_instructions.jinja2 +38 -0
- holmes/plugins/toolsets/rabbitmq/api.py +398 -0
- holmes/plugins/toolsets/rabbitmq/rabbitmq_instructions.jinja2 +37 -0
- holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py +222 -0
- holmes/plugins/toolsets/robusta/__init__.py +0 -0
- holmes/plugins/toolsets/robusta/robusta.py +235 -0
- holmes/plugins/toolsets/robusta/robusta_instructions.jinja2 +24 -0
- holmes/plugins/toolsets/runbook/__init__.py +0 -0
- holmes/plugins/toolsets/runbook/runbook_fetcher.py +78 -0
- holmes/plugins/toolsets/service_discovery.py +92 -0
- holmes/plugins/toolsets/servicenow/install.md +37 -0
- holmes/plugins/toolsets/servicenow/instructions.jinja2 +3 -0
- holmes/plugins/toolsets/servicenow/servicenow.py +198 -0
- holmes/plugins/toolsets/slab.yaml +20 -0
- holmes/plugins/toolsets/utils.py +137 -0
- holmes/plugins/utils.py +14 -0
- holmes/utils/__init__.py +0 -0
- holmes/utils/cache.py +84 -0
- holmes/utils/cert_utils.py +40 -0
- holmes/utils/default_toolset_installation_guide.jinja2 +44 -0
- holmes/utils/definitions.py +13 -0
- holmes/utils/env.py +53 -0
- holmes/utils/file_utils.py +56 -0
- holmes/utils/global_instructions.py +20 -0
- holmes/utils/holmes_status.py +22 -0
- holmes/utils/holmes_sync_toolsets.py +80 -0
- holmes/utils/markdown_utils.py +55 -0
- holmes/utils/pydantic_utils.py +54 -0
- holmes/utils/robusta.py +10 -0
- holmes/utils/tags.py +97 -0
- holmesgpt-0.11.5.dist-info/LICENSE.txt +21 -0
- holmesgpt-0.11.5.dist-info/METADATA +400 -0
- holmesgpt-0.11.5.dist-info/RECORD +183 -0
- holmesgpt-0.11.5.dist-info/WHEEL +4 -0
- holmesgpt-0.11.5.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Optional, Any, cast
|
|
4
|
+
from urllib.parse import urljoin
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
import requests # type: ignore
|
|
8
|
+
|
|
9
|
+
from holmes.core.tools import Toolset
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class OpenSearchLoggingLabelsConfig(BaseModel):
|
|
13
|
+
pod: str = "kubernetes.pod_name"
|
|
14
|
+
namespace: str = "kubernetes.namespace_name"
|
|
15
|
+
timestamp: str = "@timestamp"
|
|
16
|
+
message: str = "message"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BaseOpenSearchConfig(BaseModel):
|
|
20
|
+
opensearch_url: str
|
|
21
|
+
index_pattern: str
|
|
22
|
+
opensearch_auth_header: Optional[str] = None
|
|
23
|
+
# Setting to None will disable the cache
|
|
24
|
+
fields_ttl_seconds: Optional[int] = 14400 # 4 hours
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class OpenSearchLoggingConfig(BaseOpenSearchConfig):
|
|
28
|
+
labels: OpenSearchLoggingLabelsConfig = OpenSearchLoggingLabelsConfig()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def add_auth_header(auth_header: Optional[str]) -> dict[str, Any]:
|
|
32
|
+
results = {}
|
|
33
|
+
if auth_header:
|
|
34
|
+
results["Authorization"] = auth_header
|
|
35
|
+
return results
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_search_url(config: BaseOpenSearchConfig) -> str:
|
|
39
|
+
return urljoin(config.opensearch_url, f"/{config.index_pattern}/_search")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def opensearch_health_check(config: BaseOpenSearchConfig) -> tuple[bool, str]:
|
|
43
|
+
url = get_search_url(config)
|
|
44
|
+
try:
|
|
45
|
+
headers = {"Content-Type": "application/json"}
|
|
46
|
+
headers.update(add_auth_header(config.opensearch_auth_header))
|
|
47
|
+
health_response = requests.get(
|
|
48
|
+
url=url,
|
|
49
|
+
verify=True,
|
|
50
|
+
data=json.dumps({"size": 1}),
|
|
51
|
+
headers=headers,
|
|
52
|
+
)
|
|
53
|
+
health_response.raise_for_status()
|
|
54
|
+
return True, ""
|
|
55
|
+
except Exception as e:
|
|
56
|
+
logging.info("Failed to initialize opensearch toolset", exc_info=True)
|
|
57
|
+
return False, f"Failed to initialize opensearch toolset. url={url}. {str(e)}"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def format_log_to_json(log_line: Any) -> str:
|
|
61
|
+
try:
|
|
62
|
+
return json.dumps(log_line)
|
|
63
|
+
except Exception:
|
|
64
|
+
# Handle potential serialization errors (e.g., non-serializable objects)
|
|
65
|
+
return str(log_line)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def format_logs(
|
|
69
|
+
logs: list[dict[str, Any]],
|
|
70
|
+
config: OpenSearchLoggingConfig,
|
|
71
|
+
) -> str:
|
|
72
|
+
if not logs or not isinstance(logs, list):
|
|
73
|
+
return ""
|
|
74
|
+
|
|
75
|
+
# Get field names from config or use defaults
|
|
76
|
+
message_field = config.labels.message
|
|
77
|
+
|
|
78
|
+
formatted_lines = []
|
|
79
|
+
|
|
80
|
+
for hit in logs:
|
|
81
|
+
# Ensure hit is a dictionary and has _source
|
|
82
|
+
if not isinstance(hit, dict):
|
|
83
|
+
formatted_lines.append(format_log_to_json(hit))
|
|
84
|
+
continue
|
|
85
|
+
source = hit.get("_source")
|
|
86
|
+
if not isinstance(source, dict):
|
|
87
|
+
formatted_lines.append(format_log_to_json(hit))
|
|
88
|
+
continue
|
|
89
|
+
|
|
90
|
+
message = source.get(message_field, None)
|
|
91
|
+
|
|
92
|
+
if message and not isinstance(message, str):
|
|
93
|
+
message = str(message) # Convert non-strings
|
|
94
|
+
|
|
95
|
+
if message:
|
|
96
|
+
formatted_lines.append(message)
|
|
97
|
+
else:
|
|
98
|
+
# fallback displaying the logs line as-is
|
|
99
|
+
formatted_lines.append(format_log_to_json(hit))
|
|
100
|
+
|
|
101
|
+
return "\n".join(formatted_lines)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def build_query(
|
|
105
|
+
config: OpenSearchLoggingConfig,
|
|
106
|
+
namespace: str,
|
|
107
|
+
pod_name: str,
|
|
108
|
+
start_time: Optional[str] = None,
|
|
109
|
+
end_time: Optional[str] = None,
|
|
110
|
+
match: Optional[str] = None,
|
|
111
|
+
limit: Optional[int] = None,
|
|
112
|
+
) -> dict[str, Any]:
|
|
113
|
+
size = limit if limit else 5000
|
|
114
|
+
|
|
115
|
+
pod_field = config.labels.pod
|
|
116
|
+
namespace_field = config.labels.namespace
|
|
117
|
+
timestamp_field = config.labels.timestamp
|
|
118
|
+
message_field = config.labels.message
|
|
119
|
+
|
|
120
|
+
must_constraints: list[dict] = [
|
|
121
|
+
{"term": {f"{pod_field}.keyword": pod_name}},
|
|
122
|
+
{"term": {f"{namespace_field}.keyword": namespace}},
|
|
123
|
+
]
|
|
124
|
+
|
|
125
|
+
query = {
|
|
126
|
+
"size": size,
|
|
127
|
+
"sort": [{timestamp_field: {"order": "asc"}}],
|
|
128
|
+
"query": {"bool": {"must": must_constraints}},
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# Add timestamp range if provided
|
|
132
|
+
if start_time or end_time:
|
|
133
|
+
range_query: dict = {"range": {timestamp_field: {}}}
|
|
134
|
+
if start_time:
|
|
135
|
+
range_query["range"][timestamp_field]["gte"] = start_time
|
|
136
|
+
if end_time:
|
|
137
|
+
range_query["range"][timestamp_field]["lte"] = end_time
|
|
138
|
+
|
|
139
|
+
must_constraints.append(range_query)
|
|
140
|
+
|
|
141
|
+
# Add message filter if provided
|
|
142
|
+
if match:
|
|
143
|
+
must_constraints.append({"match_phrase": {message_field: match}})
|
|
144
|
+
|
|
145
|
+
return query
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class BaseOpenSearchToolset(Toolset):
|
|
149
|
+
def get_example_config(self) -> dict[str, Any]:
|
|
150
|
+
example_config = BaseOpenSearchConfig(
|
|
151
|
+
opensearch_url="YOUR OPENSEARCH URL",
|
|
152
|
+
index_pattern="YOUR OPENSEARCH INDEX NAME",
|
|
153
|
+
opensearch_auth_header="YOUR OPENSEARCH AUTH HEADER (Optional)",
|
|
154
|
+
)
|
|
155
|
+
return example_config.model_dump()
|
|
156
|
+
|
|
157
|
+
def prerequisites_callable(self, config: dict[str, Any]) -> tuple[bool, str]:
|
|
158
|
+
if not config:
|
|
159
|
+
return False, "Missing opensearch traces URL. Check your config"
|
|
160
|
+
else:
|
|
161
|
+
self.config = BaseOpenSearchConfig(**config)
|
|
162
|
+
return opensearch_health_check(self.config)
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def opensearch_config(self) -> BaseOpenSearchConfig:
|
|
166
|
+
return cast(BaseOpenSearchConfig, self.config)
|