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.

Files changed (183) hide show
  1. holmes/.git_archival.json +7 -0
  2. holmes/__init__.py +76 -0
  3. holmes/__init__.py.bak +76 -0
  4. holmes/clients/robusta_client.py +24 -0
  5. holmes/common/env_vars.py +47 -0
  6. holmes/config.py +526 -0
  7. holmes/core/__init__.py +0 -0
  8. holmes/core/conversations.py +578 -0
  9. holmes/core/investigation.py +152 -0
  10. holmes/core/investigation_structured_output.py +264 -0
  11. holmes/core/issue.py +54 -0
  12. holmes/core/llm.py +250 -0
  13. holmes/core/models.py +157 -0
  14. holmes/core/openai_formatting.py +51 -0
  15. holmes/core/performance_timing.py +72 -0
  16. holmes/core/prompt.py +42 -0
  17. holmes/core/resource_instruction.py +17 -0
  18. holmes/core/runbooks.py +26 -0
  19. holmes/core/safeguards.py +120 -0
  20. holmes/core/supabase_dal.py +540 -0
  21. holmes/core/tool_calling_llm.py +798 -0
  22. holmes/core/tools.py +566 -0
  23. holmes/core/tools_utils/__init__.py +0 -0
  24. holmes/core/tools_utils/tool_executor.py +65 -0
  25. holmes/core/tools_utils/toolset_utils.py +52 -0
  26. holmes/core/toolset_manager.py +418 -0
  27. holmes/interactive.py +229 -0
  28. holmes/main.py +1041 -0
  29. holmes/plugins/__init__.py +0 -0
  30. holmes/plugins/destinations/__init__.py +6 -0
  31. holmes/plugins/destinations/slack/__init__.py +2 -0
  32. holmes/plugins/destinations/slack/plugin.py +163 -0
  33. holmes/plugins/interfaces.py +32 -0
  34. holmes/plugins/prompts/__init__.py +48 -0
  35. holmes/plugins/prompts/_current_date_time.jinja2 +1 -0
  36. holmes/plugins/prompts/_default_log_prompt.jinja2 +11 -0
  37. holmes/plugins/prompts/_fetch_logs.jinja2 +36 -0
  38. holmes/plugins/prompts/_general_instructions.jinja2 +86 -0
  39. holmes/plugins/prompts/_global_instructions.jinja2 +12 -0
  40. holmes/plugins/prompts/_runbook_instructions.jinja2 +13 -0
  41. holmes/plugins/prompts/_toolsets_instructions.jinja2 +56 -0
  42. holmes/plugins/prompts/generic_ask.jinja2 +36 -0
  43. holmes/plugins/prompts/generic_ask_conversation.jinja2 +32 -0
  44. holmes/plugins/prompts/generic_ask_for_issue_conversation.jinja2 +50 -0
  45. holmes/plugins/prompts/generic_investigation.jinja2 +42 -0
  46. holmes/plugins/prompts/generic_post_processing.jinja2 +13 -0
  47. holmes/plugins/prompts/generic_ticket.jinja2 +12 -0
  48. holmes/plugins/prompts/investigation_output_format.jinja2 +32 -0
  49. holmes/plugins/prompts/kubernetes_workload_ask.jinja2 +84 -0
  50. holmes/plugins/prompts/kubernetes_workload_chat.jinja2 +39 -0
  51. holmes/plugins/runbooks/README.md +22 -0
  52. holmes/plugins/runbooks/__init__.py +100 -0
  53. holmes/plugins/runbooks/catalog.json +14 -0
  54. holmes/plugins/runbooks/jira.yaml +12 -0
  55. holmes/plugins/runbooks/kube-prometheus-stack.yaml +10 -0
  56. holmes/plugins/runbooks/networking/dns_troubleshooting_instructions.md +66 -0
  57. holmes/plugins/runbooks/upgrade/upgrade_troubleshooting_instructions.md +44 -0
  58. holmes/plugins/sources/github/__init__.py +77 -0
  59. holmes/plugins/sources/jira/__init__.py +123 -0
  60. holmes/plugins/sources/opsgenie/__init__.py +93 -0
  61. holmes/plugins/sources/pagerduty/__init__.py +147 -0
  62. holmes/plugins/sources/prometheus/__init__.py +0 -0
  63. holmes/plugins/sources/prometheus/models.py +104 -0
  64. holmes/plugins/sources/prometheus/plugin.py +154 -0
  65. holmes/plugins/toolsets/__init__.py +171 -0
  66. holmes/plugins/toolsets/aks-node-health.yaml +65 -0
  67. holmes/plugins/toolsets/aks.yaml +86 -0
  68. holmes/plugins/toolsets/argocd.yaml +70 -0
  69. holmes/plugins/toolsets/atlas_mongodb/instructions.jinja2 +8 -0
  70. holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py +307 -0
  71. holmes/plugins/toolsets/aws.yaml +76 -0
  72. holmes/plugins/toolsets/azure_sql/__init__.py +0 -0
  73. holmes/plugins/toolsets/azure_sql/apis/alert_monitoring_api.py +600 -0
  74. holmes/plugins/toolsets/azure_sql/apis/azure_sql_api.py +309 -0
  75. holmes/plugins/toolsets/azure_sql/apis/connection_failure_api.py +445 -0
  76. holmes/plugins/toolsets/azure_sql/apis/connection_monitoring_api.py +251 -0
  77. holmes/plugins/toolsets/azure_sql/apis/storage_analysis_api.py +317 -0
  78. holmes/plugins/toolsets/azure_sql/azure_base_toolset.py +55 -0
  79. holmes/plugins/toolsets/azure_sql/azure_sql_instructions.jinja2 +137 -0
  80. holmes/plugins/toolsets/azure_sql/azure_sql_toolset.py +183 -0
  81. holmes/plugins/toolsets/azure_sql/install.md +66 -0
  82. holmes/plugins/toolsets/azure_sql/tools/__init__.py +1 -0
  83. holmes/plugins/toolsets/azure_sql/tools/analyze_connection_failures.py +324 -0
  84. holmes/plugins/toolsets/azure_sql/tools/analyze_database_connections.py +243 -0
  85. holmes/plugins/toolsets/azure_sql/tools/analyze_database_health_status.py +205 -0
  86. holmes/plugins/toolsets/azure_sql/tools/analyze_database_performance.py +249 -0
  87. holmes/plugins/toolsets/azure_sql/tools/analyze_database_storage.py +373 -0
  88. holmes/plugins/toolsets/azure_sql/tools/get_active_alerts.py +237 -0
  89. holmes/plugins/toolsets/azure_sql/tools/get_slow_queries.py +172 -0
  90. holmes/plugins/toolsets/azure_sql/tools/get_top_cpu_queries.py +170 -0
  91. holmes/plugins/toolsets/azure_sql/tools/get_top_data_io_queries.py +188 -0
  92. holmes/plugins/toolsets/azure_sql/tools/get_top_log_io_queries.py +180 -0
  93. holmes/plugins/toolsets/azure_sql/utils.py +83 -0
  94. holmes/plugins/toolsets/bash/__init__.py +0 -0
  95. holmes/plugins/toolsets/bash/bash_instructions.jinja2 +14 -0
  96. holmes/plugins/toolsets/bash/bash_toolset.py +208 -0
  97. holmes/plugins/toolsets/bash/common/bash.py +52 -0
  98. holmes/plugins/toolsets/bash/common/config.py +14 -0
  99. holmes/plugins/toolsets/bash/common/stringify.py +25 -0
  100. holmes/plugins/toolsets/bash/common/validators.py +24 -0
  101. holmes/plugins/toolsets/bash/grep/__init__.py +52 -0
  102. holmes/plugins/toolsets/bash/kubectl/__init__.py +100 -0
  103. holmes/plugins/toolsets/bash/kubectl/constants.py +96 -0
  104. holmes/plugins/toolsets/bash/kubectl/kubectl_describe.py +66 -0
  105. holmes/plugins/toolsets/bash/kubectl/kubectl_events.py +88 -0
  106. holmes/plugins/toolsets/bash/kubectl/kubectl_get.py +108 -0
  107. holmes/plugins/toolsets/bash/kubectl/kubectl_logs.py +20 -0
  108. holmes/plugins/toolsets/bash/kubectl/kubectl_run.py +46 -0
  109. holmes/plugins/toolsets/bash/kubectl/kubectl_top.py +81 -0
  110. holmes/plugins/toolsets/bash/parse_command.py +103 -0
  111. holmes/plugins/toolsets/confluence.yaml +19 -0
  112. holmes/plugins/toolsets/consts.py +5 -0
  113. holmes/plugins/toolsets/coralogix/api.py +158 -0
  114. holmes/plugins/toolsets/coralogix/toolset_coralogix_logs.py +103 -0
  115. holmes/plugins/toolsets/coralogix/utils.py +181 -0
  116. holmes/plugins/toolsets/datadog.py +153 -0
  117. holmes/plugins/toolsets/docker.yaml +46 -0
  118. holmes/plugins/toolsets/git.py +756 -0
  119. holmes/plugins/toolsets/grafana/__init__.py +0 -0
  120. holmes/plugins/toolsets/grafana/base_grafana_toolset.py +54 -0
  121. holmes/plugins/toolsets/grafana/common.py +68 -0
  122. holmes/plugins/toolsets/grafana/grafana_api.py +31 -0
  123. holmes/plugins/toolsets/grafana/loki_api.py +89 -0
  124. holmes/plugins/toolsets/grafana/tempo_api.py +124 -0
  125. holmes/plugins/toolsets/grafana/toolset_grafana.py +102 -0
  126. holmes/plugins/toolsets/grafana/toolset_grafana_loki.py +102 -0
  127. holmes/plugins/toolsets/grafana/toolset_grafana_tempo.jinja2 +10 -0
  128. holmes/plugins/toolsets/grafana/toolset_grafana_tempo.py +299 -0
  129. holmes/plugins/toolsets/grafana/trace_parser.py +195 -0
  130. holmes/plugins/toolsets/helm.yaml +42 -0
  131. holmes/plugins/toolsets/internet/internet.py +275 -0
  132. holmes/plugins/toolsets/internet/notion.py +137 -0
  133. holmes/plugins/toolsets/kafka.py +638 -0
  134. holmes/plugins/toolsets/kubernetes.yaml +255 -0
  135. holmes/plugins/toolsets/kubernetes_logs.py +426 -0
  136. holmes/plugins/toolsets/kubernetes_logs.yaml +42 -0
  137. holmes/plugins/toolsets/logging_utils/__init__.py +0 -0
  138. holmes/plugins/toolsets/logging_utils/logging_api.py +217 -0
  139. holmes/plugins/toolsets/logging_utils/types.py +0 -0
  140. holmes/plugins/toolsets/mcp/toolset_mcp.py +135 -0
  141. holmes/plugins/toolsets/newrelic.py +222 -0
  142. holmes/plugins/toolsets/opensearch/__init__.py +0 -0
  143. holmes/plugins/toolsets/opensearch/opensearch.py +245 -0
  144. holmes/plugins/toolsets/opensearch/opensearch_logs.py +151 -0
  145. holmes/plugins/toolsets/opensearch/opensearch_traces.py +211 -0
  146. holmes/plugins/toolsets/opensearch/opensearch_traces_instructions.jinja2 +12 -0
  147. holmes/plugins/toolsets/opensearch/opensearch_utils.py +166 -0
  148. holmes/plugins/toolsets/prometheus/prometheus.py +818 -0
  149. holmes/plugins/toolsets/prometheus/prometheus_instructions.jinja2 +38 -0
  150. holmes/plugins/toolsets/rabbitmq/api.py +398 -0
  151. holmes/plugins/toolsets/rabbitmq/rabbitmq_instructions.jinja2 +37 -0
  152. holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py +222 -0
  153. holmes/plugins/toolsets/robusta/__init__.py +0 -0
  154. holmes/plugins/toolsets/robusta/robusta.py +235 -0
  155. holmes/plugins/toolsets/robusta/robusta_instructions.jinja2 +24 -0
  156. holmes/plugins/toolsets/runbook/__init__.py +0 -0
  157. holmes/plugins/toolsets/runbook/runbook_fetcher.py +78 -0
  158. holmes/plugins/toolsets/service_discovery.py +92 -0
  159. holmes/plugins/toolsets/servicenow/install.md +37 -0
  160. holmes/plugins/toolsets/servicenow/instructions.jinja2 +3 -0
  161. holmes/plugins/toolsets/servicenow/servicenow.py +198 -0
  162. holmes/plugins/toolsets/slab.yaml +20 -0
  163. holmes/plugins/toolsets/utils.py +137 -0
  164. holmes/plugins/utils.py +14 -0
  165. holmes/utils/__init__.py +0 -0
  166. holmes/utils/cache.py +84 -0
  167. holmes/utils/cert_utils.py +40 -0
  168. holmes/utils/default_toolset_installation_guide.jinja2 +44 -0
  169. holmes/utils/definitions.py +13 -0
  170. holmes/utils/env.py +53 -0
  171. holmes/utils/file_utils.py +56 -0
  172. holmes/utils/global_instructions.py +20 -0
  173. holmes/utils/holmes_status.py +22 -0
  174. holmes/utils/holmes_sync_toolsets.py +80 -0
  175. holmes/utils/markdown_utils.py +55 -0
  176. holmes/utils/pydantic_utils.py +54 -0
  177. holmes/utils/robusta.py +10 -0
  178. holmes/utils/tags.py +97 -0
  179. holmesgpt-0.11.5.dist-info/LICENSE.txt +21 -0
  180. holmesgpt-0.11.5.dist-info/METADATA +400 -0
  181. holmesgpt-0.11.5.dist-info/RECORD +183 -0
  182. holmesgpt-0.11.5.dist-info/WHEEL +4 -0
  183. 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)