aiecs 1.5.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.
- aiecs/__init__.py +72 -0
- aiecs/__main__.py +41 -0
- aiecs/aiecs_client.py +469 -0
- aiecs/application/__init__.py +10 -0
- aiecs/application/executors/__init__.py +10 -0
- aiecs/application/executors/operation_executor.py +363 -0
- aiecs/application/knowledge_graph/__init__.py +7 -0
- aiecs/application/knowledge_graph/builder/__init__.py +37 -0
- aiecs/application/knowledge_graph/builder/document_builder.py +375 -0
- aiecs/application/knowledge_graph/builder/graph_builder.py +356 -0
- aiecs/application/knowledge_graph/builder/schema_mapping.py +531 -0
- aiecs/application/knowledge_graph/builder/structured_pipeline.py +443 -0
- aiecs/application/knowledge_graph/builder/text_chunker.py +319 -0
- aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
- aiecs/application/knowledge_graph/extractors/base.py +100 -0
- aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +327 -0
- aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +349 -0
- aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +244 -0
- aiecs/application/knowledge_graph/fusion/__init__.py +23 -0
- aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +387 -0
- aiecs/application/knowledge_graph/fusion/entity_linker.py +343 -0
- aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +580 -0
- aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +189 -0
- aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
- aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +344 -0
- aiecs/application/knowledge_graph/pattern_matching/query_executor.py +378 -0
- aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
- aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +199 -0
- aiecs/application/knowledge_graph/profiling/query_profiler.py +223 -0
- aiecs/application/knowledge_graph/reasoning/__init__.py +27 -0
- aiecs/application/knowledge_graph/reasoning/evidence_synthesis.py +347 -0
- aiecs/application/knowledge_graph/reasoning/inference_engine.py +504 -0
- aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +167 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/__init__.py +79 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_builder.py +513 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_nodes.py +630 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +654 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +477 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +390 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +217 -0
- aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +169 -0
- aiecs/application/knowledge_graph/reasoning/query_planner.py +872 -0
- aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +554 -0
- aiecs/application/knowledge_graph/retrieval/__init__.py +19 -0
- aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +596 -0
- aiecs/application/knowledge_graph/search/__init__.py +59 -0
- aiecs/application/knowledge_graph/search/hybrid_search.py +423 -0
- aiecs/application/knowledge_graph/search/reranker.py +295 -0
- aiecs/application/knowledge_graph/search/reranker_strategies.py +553 -0
- aiecs/application/knowledge_graph/search/text_similarity.py +398 -0
- aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
- aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +329 -0
- aiecs/application/knowledge_graph/traversal/path_scorer.py +269 -0
- aiecs/application/knowledge_graph/validators/__init__.py +13 -0
- aiecs/application/knowledge_graph/validators/relation_validator.py +189 -0
- aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
- aiecs/application/knowledge_graph/visualization/graph_visualizer.py +321 -0
- aiecs/common/__init__.py +9 -0
- aiecs/common/knowledge_graph/__init__.py +17 -0
- aiecs/common/knowledge_graph/runnable.py +484 -0
- aiecs/config/__init__.py +16 -0
- aiecs/config/config.py +498 -0
- aiecs/config/graph_config.py +137 -0
- aiecs/config/registry.py +23 -0
- aiecs/core/__init__.py +46 -0
- aiecs/core/interface/__init__.py +34 -0
- aiecs/core/interface/execution_interface.py +152 -0
- aiecs/core/interface/storage_interface.py +171 -0
- aiecs/domain/__init__.py +289 -0
- aiecs/domain/agent/__init__.py +189 -0
- aiecs/domain/agent/base_agent.py +697 -0
- aiecs/domain/agent/exceptions.py +103 -0
- aiecs/domain/agent/graph_aware_mixin.py +559 -0
- aiecs/domain/agent/hybrid_agent.py +490 -0
- aiecs/domain/agent/integration/__init__.py +26 -0
- aiecs/domain/agent/integration/context_compressor.py +222 -0
- aiecs/domain/agent/integration/context_engine_adapter.py +252 -0
- aiecs/domain/agent/integration/retry_policy.py +219 -0
- aiecs/domain/agent/integration/role_config.py +213 -0
- aiecs/domain/agent/knowledge_aware_agent.py +646 -0
- aiecs/domain/agent/lifecycle.py +296 -0
- aiecs/domain/agent/llm_agent.py +300 -0
- aiecs/domain/agent/memory/__init__.py +12 -0
- aiecs/domain/agent/memory/conversation.py +197 -0
- aiecs/domain/agent/migration/__init__.py +14 -0
- aiecs/domain/agent/migration/conversion.py +160 -0
- aiecs/domain/agent/migration/legacy_wrapper.py +90 -0
- aiecs/domain/agent/models.py +317 -0
- aiecs/domain/agent/observability.py +407 -0
- aiecs/domain/agent/persistence.py +289 -0
- aiecs/domain/agent/prompts/__init__.py +29 -0
- aiecs/domain/agent/prompts/builder.py +161 -0
- aiecs/domain/agent/prompts/formatters.py +189 -0
- aiecs/domain/agent/prompts/template.py +255 -0
- aiecs/domain/agent/registry.py +260 -0
- aiecs/domain/agent/tool_agent.py +257 -0
- aiecs/domain/agent/tools/__init__.py +12 -0
- aiecs/domain/agent/tools/schema_generator.py +221 -0
- aiecs/domain/community/__init__.py +155 -0
- aiecs/domain/community/agent_adapter.py +477 -0
- aiecs/domain/community/analytics.py +481 -0
- aiecs/domain/community/collaborative_workflow.py +642 -0
- aiecs/domain/community/communication_hub.py +645 -0
- aiecs/domain/community/community_builder.py +320 -0
- aiecs/domain/community/community_integration.py +800 -0
- aiecs/domain/community/community_manager.py +813 -0
- aiecs/domain/community/decision_engine.py +879 -0
- aiecs/domain/community/exceptions.py +225 -0
- aiecs/domain/community/models/__init__.py +33 -0
- aiecs/domain/community/models/community_models.py +268 -0
- aiecs/domain/community/resource_manager.py +457 -0
- aiecs/domain/community/shared_context_manager.py +603 -0
- aiecs/domain/context/__init__.py +58 -0
- aiecs/domain/context/context_engine.py +989 -0
- aiecs/domain/context/conversation_models.py +354 -0
- aiecs/domain/context/graph_memory.py +467 -0
- aiecs/domain/execution/__init__.py +12 -0
- aiecs/domain/execution/model.py +57 -0
- aiecs/domain/knowledge_graph/__init__.py +19 -0
- aiecs/domain/knowledge_graph/models/__init__.py +52 -0
- aiecs/domain/knowledge_graph/models/entity.py +130 -0
- aiecs/domain/knowledge_graph/models/evidence.py +194 -0
- aiecs/domain/knowledge_graph/models/inference_rule.py +186 -0
- aiecs/domain/knowledge_graph/models/path.py +179 -0
- aiecs/domain/knowledge_graph/models/path_pattern.py +173 -0
- aiecs/domain/knowledge_graph/models/query.py +272 -0
- aiecs/domain/knowledge_graph/models/query_plan.py +187 -0
- aiecs/domain/knowledge_graph/models/relation.py +136 -0
- aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
- aiecs/domain/knowledge_graph/schema/entity_type.py +135 -0
- aiecs/domain/knowledge_graph/schema/graph_schema.py +271 -0
- aiecs/domain/knowledge_graph/schema/property_schema.py +155 -0
- aiecs/domain/knowledge_graph/schema/relation_type.py +171 -0
- aiecs/domain/knowledge_graph/schema/schema_manager.py +496 -0
- aiecs/domain/knowledge_graph/schema/type_enums.py +205 -0
- aiecs/domain/task/__init__.py +13 -0
- aiecs/domain/task/dsl_processor.py +613 -0
- aiecs/domain/task/model.py +62 -0
- aiecs/domain/task/task_context.py +268 -0
- aiecs/infrastructure/__init__.py +24 -0
- aiecs/infrastructure/graph_storage/__init__.py +11 -0
- aiecs/infrastructure/graph_storage/base.py +601 -0
- aiecs/infrastructure/graph_storage/batch_operations.py +449 -0
- aiecs/infrastructure/graph_storage/cache.py +429 -0
- aiecs/infrastructure/graph_storage/distributed.py +226 -0
- aiecs/infrastructure/graph_storage/error_handling.py +390 -0
- aiecs/infrastructure/graph_storage/graceful_degradation.py +306 -0
- aiecs/infrastructure/graph_storage/health_checks.py +378 -0
- aiecs/infrastructure/graph_storage/in_memory.py +514 -0
- aiecs/infrastructure/graph_storage/index_optimization.py +483 -0
- aiecs/infrastructure/graph_storage/lazy_loading.py +410 -0
- aiecs/infrastructure/graph_storage/metrics.py +357 -0
- aiecs/infrastructure/graph_storage/migration.py +413 -0
- aiecs/infrastructure/graph_storage/pagination.py +471 -0
- aiecs/infrastructure/graph_storage/performance_monitoring.py +466 -0
- aiecs/infrastructure/graph_storage/postgres.py +871 -0
- aiecs/infrastructure/graph_storage/query_optimizer.py +635 -0
- aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
- aiecs/infrastructure/graph_storage/sqlite.py +623 -0
- aiecs/infrastructure/graph_storage/streaming.py +495 -0
- aiecs/infrastructure/messaging/__init__.py +13 -0
- aiecs/infrastructure/messaging/celery_task_manager.py +383 -0
- aiecs/infrastructure/messaging/websocket_manager.py +298 -0
- aiecs/infrastructure/monitoring/__init__.py +34 -0
- aiecs/infrastructure/monitoring/executor_metrics.py +174 -0
- aiecs/infrastructure/monitoring/global_metrics_manager.py +213 -0
- aiecs/infrastructure/monitoring/structured_logger.py +48 -0
- aiecs/infrastructure/monitoring/tracing_manager.py +410 -0
- aiecs/infrastructure/persistence/__init__.py +24 -0
- aiecs/infrastructure/persistence/context_engine_client.py +187 -0
- aiecs/infrastructure/persistence/database_manager.py +333 -0
- aiecs/infrastructure/persistence/file_storage.py +754 -0
- aiecs/infrastructure/persistence/redis_client.py +220 -0
- aiecs/llm/__init__.py +86 -0
- aiecs/llm/callbacks/__init__.py +11 -0
- aiecs/llm/callbacks/custom_callbacks.py +264 -0
- aiecs/llm/client_factory.py +420 -0
- aiecs/llm/clients/__init__.py +33 -0
- aiecs/llm/clients/base_client.py +193 -0
- aiecs/llm/clients/googleai_client.py +181 -0
- aiecs/llm/clients/openai_client.py +131 -0
- aiecs/llm/clients/vertex_client.py +437 -0
- aiecs/llm/clients/xai_client.py +184 -0
- aiecs/llm/config/__init__.py +51 -0
- aiecs/llm/config/config_loader.py +275 -0
- aiecs/llm/config/config_validator.py +236 -0
- aiecs/llm/config/model_config.py +151 -0
- aiecs/llm/utils/__init__.py +10 -0
- aiecs/llm/utils/validate_config.py +91 -0
- aiecs/main.py +363 -0
- aiecs/scripts/__init__.py +3 -0
- aiecs/scripts/aid/VERSION_MANAGEMENT.md +97 -0
- aiecs/scripts/aid/__init__.py +19 -0
- aiecs/scripts/aid/version_manager.py +215 -0
- aiecs/scripts/dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md +242 -0
- aiecs/scripts/dependance_check/README_DEPENDENCY_CHECKER.md +310 -0
- aiecs/scripts/dependance_check/__init__.py +17 -0
- aiecs/scripts/dependance_check/dependency_checker.py +938 -0
- aiecs/scripts/dependance_check/dependency_fixer.py +391 -0
- aiecs/scripts/dependance_check/download_nlp_data.py +396 -0
- aiecs/scripts/dependance_check/quick_dependency_check.py +270 -0
- aiecs/scripts/dependance_check/setup_nlp_data.sh +217 -0
- aiecs/scripts/dependance_patch/__init__.py +7 -0
- aiecs/scripts/dependance_patch/fix_weasel/README_WEASEL_PATCH.md +126 -0
- aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
- aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.py +128 -0
- aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.sh +82 -0
- aiecs/scripts/dependance_patch/fix_weasel/patch_weasel_library.sh +188 -0
- aiecs/scripts/dependance_patch/fix_weasel/run_weasel_patch.sh +41 -0
- aiecs/scripts/tools_develop/README.md +449 -0
- aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
- aiecs/scripts/tools_develop/__init__.py +21 -0
- aiecs/scripts/tools_develop/check_type_annotations.py +259 -0
- aiecs/scripts/tools_develop/validate_tool_schemas.py +422 -0
- aiecs/scripts/tools_develop/verify_tools.py +356 -0
- aiecs/tasks/__init__.py +1 -0
- aiecs/tasks/worker.py +172 -0
- aiecs/tools/__init__.py +299 -0
- aiecs/tools/apisource/__init__.py +99 -0
- aiecs/tools/apisource/intelligence/__init__.py +19 -0
- aiecs/tools/apisource/intelligence/data_fusion.py +381 -0
- aiecs/tools/apisource/intelligence/query_analyzer.py +413 -0
- aiecs/tools/apisource/intelligence/search_enhancer.py +388 -0
- aiecs/tools/apisource/monitoring/__init__.py +9 -0
- aiecs/tools/apisource/monitoring/metrics.py +303 -0
- aiecs/tools/apisource/providers/__init__.py +115 -0
- aiecs/tools/apisource/providers/base.py +664 -0
- aiecs/tools/apisource/providers/census.py +401 -0
- aiecs/tools/apisource/providers/fred.py +564 -0
- aiecs/tools/apisource/providers/newsapi.py +412 -0
- aiecs/tools/apisource/providers/worldbank.py +357 -0
- aiecs/tools/apisource/reliability/__init__.py +12 -0
- aiecs/tools/apisource/reliability/error_handler.py +375 -0
- aiecs/tools/apisource/reliability/fallback_strategy.py +391 -0
- aiecs/tools/apisource/tool.py +850 -0
- aiecs/tools/apisource/utils/__init__.py +9 -0
- aiecs/tools/apisource/utils/validators.py +338 -0
- aiecs/tools/base_tool.py +201 -0
- aiecs/tools/docs/__init__.py +121 -0
- aiecs/tools/docs/ai_document_orchestrator.py +599 -0
- aiecs/tools/docs/ai_document_writer_orchestrator.py +2403 -0
- aiecs/tools/docs/content_insertion_tool.py +1333 -0
- aiecs/tools/docs/document_creator_tool.py +1317 -0
- aiecs/tools/docs/document_layout_tool.py +1166 -0
- aiecs/tools/docs/document_parser_tool.py +994 -0
- aiecs/tools/docs/document_writer_tool.py +1818 -0
- aiecs/tools/knowledge_graph/__init__.py +17 -0
- aiecs/tools/knowledge_graph/graph_reasoning_tool.py +734 -0
- aiecs/tools/knowledge_graph/graph_search_tool.py +923 -0
- aiecs/tools/knowledge_graph/kg_builder_tool.py +476 -0
- aiecs/tools/langchain_adapter.py +542 -0
- aiecs/tools/schema_generator.py +275 -0
- aiecs/tools/search_tool/__init__.py +100 -0
- aiecs/tools/search_tool/analyzers.py +589 -0
- aiecs/tools/search_tool/cache.py +260 -0
- aiecs/tools/search_tool/constants.py +128 -0
- aiecs/tools/search_tool/context.py +216 -0
- aiecs/tools/search_tool/core.py +749 -0
- aiecs/tools/search_tool/deduplicator.py +123 -0
- aiecs/tools/search_tool/error_handler.py +271 -0
- aiecs/tools/search_tool/metrics.py +371 -0
- aiecs/tools/search_tool/rate_limiter.py +178 -0
- aiecs/tools/search_tool/schemas.py +277 -0
- aiecs/tools/statistics/__init__.py +80 -0
- aiecs/tools/statistics/ai_data_analysis_orchestrator.py +643 -0
- aiecs/tools/statistics/ai_insight_generator_tool.py +505 -0
- aiecs/tools/statistics/ai_report_orchestrator_tool.py +694 -0
- aiecs/tools/statistics/data_loader_tool.py +564 -0
- aiecs/tools/statistics/data_profiler_tool.py +658 -0
- aiecs/tools/statistics/data_transformer_tool.py +573 -0
- aiecs/tools/statistics/data_visualizer_tool.py +495 -0
- aiecs/tools/statistics/model_trainer_tool.py +487 -0
- aiecs/tools/statistics/statistical_analyzer_tool.py +459 -0
- aiecs/tools/task_tools/__init__.py +86 -0
- aiecs/tools/task_tools/chart_tool.py +732 -0
- aiecs/tools/task_tools/classfire_tool.py +922 -0
- aiecs/tools/task_tools/image_tool.py +447 -0
- aiecs/tools/task_tools/office_tool.py +684 -0
- aiecs/tools/task_tools/pandas_tool.py +635 -0
- aiecs/tools/task_tools/report_tool.py +635 -0
- aiecs/tools/task_tools/research_tool.py +392 -0
- aiecs/tools/task_tools/scraper_tool.py +715 -0
- aiecs/tools/task_tools/stats_tool.py +688 -0
- aiecs/tools/temp_file_manager.py +130 -0
- aiecs/tools/tool_executor/__init__.py +37 -0
- aiecs/tools/tool_executor/tool_executor.py +881 -0
- aiecs/utils/LLM_output_structor.py +445 -0
- aiecs/utils/__init__.py +34 -0
- aiecs/utils/base_callback.py +47 -0
- aiecs/utils/cache_provider.py +695 -0
- aiecs/utils/execution_utils.py +184 -0
- aiecs/utils/logging.py +1 -0
- aiecs/utils/prompt_loader.py +14 -0
- aiecs/utils/token_usage_repository.py +323 -0
- aiecs/ws/__init__.py +0 -0
- aiecs/ws/socket_server.py +52 -0
- aiecs-1.5.1.dist-info/METADATA +608 -0
- aiecs-1.5.1.dist-info/RECORD +302 -0
- aiecs-1.5.1.dist-info/WHEEL +5 -0
- aiecs-1.5.1.dist-info/entry_points.txt +10 -0
- aiecs-1.5.1.dist-info/licenses/LICENSE +225 -0
- aiecs-1.5.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Infrastructure monitoring module
|
|
2
|
+
|
|
3
|
+
Contains monitoring, metrics, and observability infrastructure.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .executor_metrics import ExecutorMetrics
|
|
7
|
+
from .tracing_manager import TracingManager
|
|
8
|
+
from .global_metrics_manager import (
|
|
9
|
+
initialize_global_metrics,
|
|
10
|
+
get_global_metrics,
|
|
11
|
+
close_global_metrics,
|
|
12
|
+
is_metrics_initialized,
|
|
13
|
+
get_metrics_summary,
|
|
14
|
+
record_operation,
|
|
15
|
+
record_duration,
|
|
16
|
+
record_operation_success,
|
|
17
|
+
record_operation_failure,
|
|
18
|
+
record_retry,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"ExecutorMetrics",
|
|
23
|
+
"TracingManager",
|
|
24
|
+
"initialize_global_metrics",
|
|
25
|
+
"get_global_metrics",
|
|
26
|
+
"close_global_metrics",
|
|
27
|
+
"is_metrics_initialized",
|
|
28
|
+
"get_metrics_summary",
|
|
29
|
+
"record_operation",
|
|
30
|
+
"record_duration",
|
|
31
|
+
"record_operation_success",
|
|
32
|
+
"record_operation_failure",
|
|
33
|
+
"record_retry",
|
|
34
|
+
]
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import functools
|
|
3
|
+
from typing import Dict, Optional, Any
|
|
4
|
+
from prometheus_client import Counter, Histogram, start_http_server
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ExecutorMetrics:
|
|
10
|
+
"""
|
|
11
|
+
Specialized handler for executor performance monitoring and metrics collection
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, enable_metrics: bool = True, metrics_port: int = 8001):
|
|
15
|
+
self.enable_metrics = enable_metrics
|
|
16
|
+
self.metrics_port = metrics_port
|
|
17
|
+
self.metrics: Dict[str, Any] = {}
|
|
18
|
+
|
|
19
|
+
if self.enable_metrics:
|
|
20
|
+
self._init_prometheus_metrics()
|
|
21
|
+
|
|
22
|
+
def _init_prometheus_metrics(self):
|
|
23
|
+
"""Initialize Prometheus metrics"""
|
|
24
|
+
try:
|
|
25
|
+
start_http_server(self.metrics_port)
|
|
26
|
+
self.metrics = {
|
|
27
|
+
"intent_latency": Histogram("intent_latency_seconds", "Latency of intent parsing"),
|
|
28
|
+
"intent_success": Counter(
|
|
29
|
+
"intent_success_total",
|
|
30
|
+
"Number of successful intent parsings",
|
|
31
|
+
),
|
|
32
|
+
"intent_retries": Counter(
|
|
33
|
+
"intent_retries_total", "Number of intent parsing retries"
|
|
34
|
+
),
|
|
35
|
+
"plan_latency": Histogram("plan_latency_seconds", "Latency of task planning"),
|
|
36
|
+
"plan_success": Counter("plan_success_total", "Number of successful plans"),
|
|
37
|
+
"plan_retries": Counter("plan_retries_total", "Number of plan retries"),
|
|
38
|
+
"execute_latency": Histogram(
|
|
39
|
+
"execute_latency_seconds",
|
|
40
|
+
"Latency of task execution",
|
|
41
|
+
["task_type"],
|
|
42
|
+
),
|
|
43
|
+
"execute_success": Counter(
|
|
44
|
+
"execute_success_total",
|
|
45
|
+
"Number of successful executions",
|
|
46
|
+
["task_type"],
|
|
47
|
+
),
|
|
48
|
+
"execute_retries": Counter(
|
|
49
|
+
"execute_retries_total",
|
|
50
|
+
"Number of execution retries",
|
|
51
|
+
["task_type"],
|
|
52
|
+
),
|
|
53
|
+
}
|
|
54
|
+
logger.info(f"Prometheus metrics server started on port {self.metrics_port}")
|
|
55
|
+
except Exception as e:
|
|
56
|
+
logger.warning(f"Failed to start metrics server: {e}")
|
|
57
|
+
self.metrics = {}
|
|
58
|
+
|
|
59
|
+
def record_operation_latency(self, operation: str, duration: float):
|
|
60
|
+
"""Record operation latency"""
|
|
61
|
+
if not self.enable_metrics or f"{operation}_latency" not in self.metrics:
|
|
62
|
+
return
|
|
63
|
+
self.metrics[f"{operation}_latency"].observe(duration)
|
|
64
|
+
|
|
65
|
+
def record_operation_success(self, operation: str, labels: Optional[Dict[str, str]] = None):
|
|
66
|
+
"""Record operation success"""
|
|
67
|
+
if not self.enable_metrics or f"{operation}_success" not in self.metrics:
|
|
68
|
+
return
|
|
69
|
+
metric = self.metrics[f"{operation}_success"]
|
|
70
|
+
if labels:
|
|
71
|
+
metric = metric.labels(**labels)
|
|
72
|
+
metric.inc()
|
|
73
|
+
|
|
74
|
+
def record_operation_failure(
|
|
75
|
+
self,
|
|
76
|
+
operation: str,
|
|
77
|
+
error_type: str,
|
|
78
|
+
labels: Optional[Dict[str, str]] = None,
|
|
79
|
+
):
|
|
80
|
+
"""Record operation failure"""
|
|
81
|
+
if not self.enable_metrics:
|
|
82
|
+
return
|
|
83
|
+
# Failure metrics can be added
|
|
84
|
+
logger.error(f"Operation {operation} failed with error type: {error_type}")
|
|
85
|
+
|
|
86
|
+
def record_retry(self, operation: str, attempt_number: int):
|
|
87
|
+
"""Record retry"""
|
|
88
|
+
if not self.enable_metrics or f"{operation}_retries" not in self.metrics:
|
|
89
|
+
return
|
|
90
|
+
if attempt_number > 1:
|
|
91
|
+
self.metrics[f"{operation}_retries"].inc()
|
|
92
|
+
|
|
93
|
+
def with_metrics(self, metric_name: str, labels: Optional[Dict[str, str]] = None):
|
|
94
|
+
"""Monitoring decorator"""
|
|
95
|
+
|
|
96
|
+
def decorator(func):
|
|
97
|
+
@functools.wraps(func)
|
|
98
|
+
async def wrapper(*args, **kwargs):
|
|
99
|
+
if not self.metrics or f"{metric_name}_latency" not in self.metrics:
|
|
100
|
+
return await func(*args, **kwargs)
|
|
101
|
+
|
|
102
|
+
labels_dict = labels or {}
|
|
103
|
+
metric = self.metrics[f"{metric_name}_latency"]
|
|
104
|
+
if labels:
|
|
105
|
+
metric = metric.labels(**labels_dict)
|
|
106
|
+
|
|
107
|
+
with metric.time():
|
|
108
|
+
try:
|
|
109
|
+
result = await func(*args, **kwargs)
|
|
110
|
+
if f"{metric_name}_success" in self.metrics:
|
|
111
|
+
success_metric = self.metrics[f"{metric_name}_success"]
|
|
112
|
+
if labels:
|
|
113
|
+
success_metric = success_metric.labels(**labels_dict)
|
|
114
|
+
success_metric.inc()
|
|
115
|
+
return result
|
|
116
|
+
except Exception as e:
|
|
117
|
+
logger.error(f"Error in {func.__name__}: {e}")
|
|
118
|
+
raise
|
|
119
|
+
|
|
120
|
+
return wrapper
|
|
121
|
+
|
|
122
|
+
return decorator
|
|
123
|
+
|
|
124
|
+
def get_metrics_summary(self) -> Dict[str, Any]:
|
|
125
|
+
"""Get metrics summary"""
|
|
126
|
+
if not self.enable_metrics:
|
|
127
|
+
return {"metrics_enabled": False}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
"metrics_enabled": True,
|
|
131
|
+
"metrics_port": self.metrics_port,
|
|
132
|
+
"available_metrics": list(self.metrics.keys()),
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
def record_operation(
|
|
136
|
+
self,
|
|
137
|
+
operation_type: str,
|
|
138
|
+
success: bool = True,
|
|
139
|
+
duration: Optional[float] = None,
|
|
140
|
+
**kwargs,
|
|
141
|
+
):
|
|
142
|
+
"""Record a general operation for metrics tracking"""
|
|
143
|
+
if not self.enable_metrics:
|
|
144
|
+
return
|
|
145
|
+
|
|
146
|
+
try:
|
|
147
|
+
# Record operation success/failure
|
|
148
|
+
if success:
|
|
149
|
+
self.record_operation_success(operation_type, kwargs.get("labels"))
|
|
150
|
+
else:
|
|
151
|
+
error_type = kwargs.get("error_type", "unknown")
|
|
152
|
+
self.record_operation_failure(operation_type, error_type, kwargs.get("labels"))
|
|
153
|
+
|
|
154
|
+
# Record operation latency if provided
|
|
155
|
+
if duration is not None:
|
|
156
|
+
self.record_operation_latency(operation_type, duration)
|
|
157
|
+
|
|
158
|
+
except Exception as e:
|
|
159
|
+
logger.warning(f"Failed to record operation metrics: {e}")
|
|
160
|
+
|
|
161
|
+
def record_duration(
|
|
162
|
+
self,
|
|
163
|
+
operation: str,
|
|
164
|
+
duration: float,
|
|
165
|
+
labels: Optional[Dict[str, str]] = None,
|
|
166
|
+
):
|
|
167
|
+
"""Record operation duration for metrics tracking"""
|
|
168
|
+
if not self.enable_metrics:
|
|
169
|
+
return
|
|
170
|
+
|
|
171
|
+
try:
|
|
172
|
+
self.record_operation_latency(operation, duration)
|
|
173
|
+
except Exception as e:
|
|
174
|
+
logger.warning(f"Failed to record duration metrics: {e}")
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Global Metrics Manager
|
|
3
|
+
|
|
4
|
+
This module provides a singleton ExecutorMetrics instance that can be shared
|
|
5
|
+
across all components in the application. It follows the same pattern as
|
|
6
|
+
other global managers in the infrastructure layer.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
# In main.py startup:
|
|
10
|
+
await initialize_global_metrics()
|
|
11
|
+
|
|
12
|
+
# In any component:
|
|
13
|
+
from aiecs.infrastructure.monitoring.global_metrics_manager import get_global_metrics
|
|
14
|
+
metrics = get_global_metrics()
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import logging
|
|
18
|
+
import asyncio
|
|
19
|
+
import os
|
|
20
|
+
from typing import Optional, Dict, Any
|
|
21
|
+
from .executor_metrics import ExecutorMetrics
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
# Global singleton instance
|
|
26
|
+
_global_metrics: Optional[ExecutorMetrics] = None
|
|
27
|
+
_initialization_lock = asyncio.Lock()
|
|
28
|
+
_initialized = False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
async def initialize_global_metrics(
|
|
32
|
+
enable_metrics: bool = True,
|
|
33
|
+
metrics_port: Optional[int] = None,
|
|
34
|
+
config: Optional[Dict[str, Any]] = None,
|
|
35
|
+
) -> Optional[ExecutorMetrics]:
|
|
36
|
+
"""
|
|
37
|
+
Initialize the global ExecutorMetrics instance.
|
|
38
|
+
|
|
39
|
+
This should be called once during application startup (in main.py lifespan).
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
enable_metrics: Whether to enable metrics collection (default: True)
|
|
43
|
+
metrics_port: Port for metrics server (default: from env or 8001)
|
|
44
|
+
config: Additional configuration options
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
The initialized ExecutorMetrics instance or None if initialization fails
|
|
48
|
+
|
|
49
|
+
Example:
|
|
50
|
+
@asynccontextmanager
|
|
51
|
+
async def lifespan(app: FastAPI):
|
|
52
|
+
# Startup
|
|
53
|
+
await initialize_global_metrics()
|
|
54
|
+
yield
|
|
55
|
+
# Shutdown
|
|
56
|
+
await close_global_metrics()
|
|
57
|
+
"""
|
|
58
|
+
global _global_metrics, _initialized
|
|
59
|
+
|
|
60
|
+
if _initialized and _global_metrics:
|
|
61
|
+
logger.info("Global metrics already initialized")
|
|
62
|
+
return _global_metrics
|
|
63
|
+
|
|
64
|
+
async with _initialization_lock:
|
|
65
|
+
# Double-check after acquiring lock
|
|
66
|
+
if _initialized and _global_metrics:
|
|
67
|
+
return _global_metrics
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
# Determine metrics port
|
|
71
|
+
if metrics_port is None:
|
|
72
|
+
metrics_port = int(os.environ.get("METRICS_PORT", "8001"))
|
|
73
|
+
|
|
74
|
+
# Check if metrics should be enabled
|
|
75
|
+
if not enable_metrics:
|
|
76
|
+
enable_metrics = os.environ.get("ENABLE_METRICS", "true").lower() == "true"
|
|
77
|
+
|
|
78
|
+
logger.info(
|
|
79
|
+
f"Initializing global metrics (port: {metrics_port}, enabled: {enable_metrics})..."
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Create metrics instance
|
|
83
|
+
_global_metrics = ExecutorMetrics(
|
|
84
|
+
enable_metrics=enable_metrics, metrics_port=metrics_port
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
_initialized = True
|
|
88
|
+
logger.info("✅ Global metrics initialized successfully")
|
|
89
|
+
return _global_metrics
|
|
90
|
+
|
|
91
|
+
except Exception as e:
|
|
92
|
+
logger.error(f"❌ Failed to initialize global metrics: {e}")
|
|
93
|
+
logger.warning("Application will continue without metrics (degraded mode)")
|
|
94
|
+
_global_metrics = None
|
|
95
|
+
_initialized = False
|
|
96
|
+
return None
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def get_global_metrics() -> Optional[ExecutorMetrics]:
|
|
100
|
+
"""
|
|
101
|
+
Get the global ExecutorMetrics instance.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
The global ExecutorMetrics instance or None if not initialized
|
|
105
|
+
|
|
106
|
+
Raises:
|
|
107
|
+
RuntimeError: If metrics are requested but not initialized
|
|
108
|
+
|
|
109
|
+
Example:
|
|
110
|
+
metrics = get_global_metrics()
|
|
111
|
+
if metrics:
|
|
112
|
+
metrics.record_operation('my_operation', 1)
|
|
113
|
+
"""
|
|
114
|
+
if _global_metrics is None:
|
|
115
|
+
logger.warning("Global metrics not initialized - call initialize_global_metrics() first")
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
return _global_metrics
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
async def close_global_metrics():
|
|
122
|
+
"""
|
|
123
|
+
Close the global metrics instance.
|
|
124
|
+
|
|
125
|
+
This should be called during application shutdown.
|
|
126
|
+
"""
|
|
127
|
+
global _global_metrics, _initialized
|
|
128
|
+
|
|
129
|
+
if _global_metrics:
|
|
130
|
+
try:
|
|
131
|
+
# ExecutorMetrics doesn't have a close method, but we can clean up
|
|
132
|
+
logger.info("Closing global metrics...")
|
|
133
|
+
_global_metrics = None
|
|
134
|
+
_initialized = False
|
|
135
|
+
logger.info("✅ Global metrics closed successfully")
|
|
136
|
+
except Exception as e:
|
|
137
|
+
logger.error(f"❌ Error closing global metrics: {e}")
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def is_metrics_initialized() -> bool:
|
|
141
|
+
"""
|
|
142
|
+
Check if global metrics are initialized.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
True if metrics are initialized, False otherwise
|
|
146
|
+
"""
|
|
147
|
+
return _initialized and _global_metrics is not None
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def get_metrics_summary() -> Dict[str, Any]:
|
|
151
|
+
"""
|
|
152
|
+
Get a summary of the global metrics status.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
Dictionary containing metrics status information
|
|
156
|
+
"""
|
|
157
|
+
if not is_metrics_initialized():
|
|
158
|
+
return {
|
|
159
|
+
"initialized": False,
|
|
160
|
+
"message": "Global metrics not initialized",
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
try:
|
|
164
|
+
return _global_metrics.get_metrics_summary()
|
|
165
|
+
except Exception as e:
|
|
166
|
+
return {
|
|
167
|
+
"initialized": True,
|
|
168
|
+
"error": str(e),
|
|
169
|
+
"message": "Failed to get metrics summary",
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
# Convenience functions for common operations
|
|
174
|
+
def record_operation(
|
|
175
|
+
operation_type: str,
|
|
176
|
+
success: bool = True,
|
|
177
|
+
duration: Optional[float] = None,
|
|
178
|
+
**kwargs,
|
|
179
|
+
):
|
|
180
|
+
"""Record an operation using global metrics."""
|
|
181
|
+
metrics = get_global_metrics()
|
|
182
|
+
if metrics:
|
|
183
|
+
metrics.record_operation(operation_type, success, duration, **kwargs)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def record_duration(operation: str, duration: float, labels: Optional[Dict[str, str]] = None):
|
|
187
|
+
"""Record operation duration using global metrics."""
|
|
188
|
+
metrics = get_global_metrics()
|
|
189
|
+
if metrics:
|
|
190
|
+
metrics.record_duration(operation, duration, labels)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def record_operation_success(operation: str, labels: Optional[Dict[str, str]] = None):
|
|
194
|
+
"""Record operation success using global metrics."""
|
|
195
|
+
metrics = get_global_metrics()
|
|
196
|
+
if metrics:
|
|
197
|
+
metrics.record_operation_success(operation, labels)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def record_operation_failure(
|
|
201
|
+
operation: str, error_type: str, labels: Optional[Dict[str, str]] = None
|
|
202
|
+
):
|
|
203
|
+
"""Record operation failure using global metrics."""
|
|
204
|
+
metrics = get_global_metrics()
|
|
205
|
+
if metrics:
|
|
206
|
+
metrics.record_operation_failure(operation, error_type, labels)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def record_retry(operation: str, attempt_number: int):
|
|
210
|
+
"""Record retry using global metrics."""
|
|
211
|
+
metrics = get_global_metrics()
|
|
212
|
+
if metrics:
|
|
213
|
+
metrics.record_retry(operation, attempt_number)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Structured logging setup for aiecs."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def setup_structured_logging(level: str = "INFO", format_type: str = "json") -> None:
|
|
8
|
+
"""
|
|
9
|
+
Setup structured logging for the application.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
|
13
|
+
format_type: Format type (json, text)
|
|
14
|
+
"""
|
|
15
|
+
# Convert string level to logging level
|
|
16
|
+
numeric_level = getattr(logging, level.upper(), logging.INFO)
|
|
17
|
+
|
|
18
|
+
# Create formatter
|
|
19
|
+
if format_type.lower() == "json":
|
|
20
|
+
# Simple JSON-like format for now
|
|
21
|
+
formatter = logging.Formatter(
|
|
22
|
+
'{"timestamp": "%(asctime)s", "level": "%(levelname)s", "module": "%(name)s", "message": "%(message)s"}'
|
|
23
|
+
)
|
|
24
|
+
else:
|
|
25
|
+
# Standard text format
|
|
26
|
+
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
|
27
|
+
|
|
28
|
+
# Setup root logger
|
|
29
|
+
root_logger = logging.getLogger()
|
|
30
|
+
root_logger.setLevel(numeric_level)
|
|
31
|
+
|
|
32
|
+
# Remove existing handlers
|
|
33
|
+
for handler in root_logger.handlers[:]:
|
|
34
|
+
root_logger.removeHandler(handler)
|
|
35
|
+
|
|
36
|
+
# Add console handler
|
|
37
|
+
console_handler = logging.StreamHandler(sys.stdout)
|
|
38
|
+
console_handler.setLevel(numeric_level)
|
|
39
|
+
console_handler.setFormatter(formatter)
|
|
40
|
+
root_logger.addHandler(console_handler)
|
|
41
|
+
|
|
42
|
+
# Set specific logger levels
|
|
43
|
+
logging.getLogger("aiecs").setLevel(numeric_level)
|
|
44
|
+
|
|
45
|
+
# Suppress noisy third-party loggers
|
|
46
|
+
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
|
47
|
+
logging.getLogger("requests").setLevel(logging.WARNING)
|
|
48
|
+
logging.getLogger("httpx").setLevel(logging.WARNING)
|