unrealon 1.0.9__py3-none-any.whl → 1.1.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.
- unrealon/__init__.py +23 -21
- unrealon-1.1.1.dist-info/METADATA +722 -0
- unrealon-1.1.1.dist-info/RECORD +82 -0
- {unrealon-1.0.9.dist-info → unrealon-1.1.1.dist-info}/WHEEL +1 -1
- unrealon-1.1.1.dist-info/entry_points.txt +9 -0
- {unrealon-1.0.9.dist-info → unrealon-1.1.1.dist-info/licenses}/LICENSE +1 -1
- unrealon_bridge/__init__.py +114 -0
- unrealon_bridge/cli.py +316 -0
- unrealon_bridge/client/__init__.py +93 -0
- unrealon_bridge/client/base.py +78 -0
- unrealon_bridge/client/commands.py +89 -0
- unrealon_bridge/client/connection.py +90 -0
- unrealon_bridge/client/events.py +65 -0
- unrealon_bridge/client/health.py +38 -0
- unrealon_bridge/client/html_parser.py +146 -0
- unrealon_bridge/client/logging.py +139 -0
- unrealon_bridge/client/proxy.py +70 -0
- unrealon_bridge/client/scheduler.py +450 -0
- unrealon_bridge/client/session.py +70 -0
- unrealon_bridge/configs/__init__.py +14 -0
- unrealon_bridge/configs/bridge_config.py +212 -0
- unrealon_bridge/configs/bridge_config.yaml +39 -0
- unrealon_bridge/models/__init__.py +138 -0
- unrealon_bridge/models/base.py +28 -0
- unrealon_bridge/models/command.py +41 -0
- unrealon_bridge/models/events.py +40 -0
- unrealon_bridge/models/html_parser.py +79 -0
- unrealon_bridge/models/logging.py +55 -0
- unrealon_bridge/models/parser.py +63 -0
- unrealon_bridge/models/proxy.py +41 -0
- unrealon_bridge/models/requests.py +95 -0
- unrealon_bridge/models/responses.py +88 -0
- unrealon_bridge/models/scheduler.py +592 -0
- unrealon_bridge/models/session.py +28 -0
- unrealon_bridge/server/__init__.py +91 -0
- unrealon_bridge/server/base.py +171 -0
- unrealon_bridge/server/handlers/__init__.py +23 -0
- unrealon_bridge/server/handlers/command.py +110 -0
- unrealon_bridge/server/handlers/html_parser.py +139 -0
- unrealon_bridge/server/handlers/logging.py +95 -0
- unrealon_bridge/server/handlers/parser.py +95 -0
- unrealon_bridge/server/handlers/proxy.py +75 -0
- unrealon_bridge/server/handlers/scheduler.py +545 -0
- unrealon_bridge/server/handlers/session.py +66 -0
- unrealon_browser/__init__.py +61 -18
- unrealon_browser/{src/cli → cli}/browser_cli.py +6 -13
- unrealon_browser/{src/cli → cli}/cookies_cli.py +5 -1
- unrealon_browser/{src/core → core}/browser_manager.py +2 -2
- unrealon_browser/{src/managers → managers}/captcha.py +1 -1
- unrealon_browser/{src/managers → managers}/cookies.py +1 -1
- unrealon_browser/managers/logger_bridge.py +231 -0
- unrealon_browser/{src/managers → managers}/profile.py +1 -1
- unrealon_driver/__init__.py +73 -19
- unrealon_driver/browser/__init__.py +8 -0
- unrealon_driver/browser/config.py +74 -0
- unrealon_driver/browser/manager.py +416 -0
- unrealon_driver/exceptions.py +28 -0
- unrealon_driver/parser/__init__.py +55 -0
- unrealon_driver/parser/cli_manager.py +141 -0
- unrealon_driver/parser/daemon_manager.py +227 -0
- unrealon_driver/parser/managers/__init__.py +46 -0
- unrealon_driver/parser/managers/browser.py +51 -0
- unrealon_driver/parser/managers/config.py +281 -0
- unrealon_driver/parser/managers/error.py +412 -0
- unrealon_driver/parser/managers/html.py +732 -0
- unrealon_driver/parser/managers/logging.py +609 -0
- unrealon_driver/parser/managers/result.py +321 -0
- unrealon_driver/parser/parser_manager.py +628 -0
- unrealon/sdk_config.py +0 -88
- unrealon-1.0.9.dist-info/METADATA +0 -810
- unrealon-1.0.9.dist-info/RECORD +0 -246
- unrealon_browser/pyproject.toml +0 -182
- unrealon_browser/src/__init__.py +0 -62
- unrealon_browser/src/managers/logger_bridge.py +0 -395
- unrealon_driver/README.md +0 -204
- unrealon_driver/pyproject.toml +0 -187
- unrealon_driver/src/__init__.py +0 -90
- unrealon_driver/src/cli/__init__.py +0 -10
- unrealon_driver/src/cli/main.py +0 -66
- unrealon_driver/src/cli/simple.py +0 -510
- unrealon_driver/src/config/__init__.py +0 -11
- unrealon_driver/src/config/auto_config.py +0 -478
- unrealon_driver/src/core/__init__.py +0 -18
- unrealon_driver/src/core/exceptions.py +0 -289
- unrealon_driver/src/core/parser.py +0 -638
- unrealon_driver/src/dto/__init__.py +0 -66
- unrealon_driver/src/dto/cli.py +0 -119
- unrealon_driver/src/dto/config.py +0 -18
- unrealon_driver/src/dto/events.py +0 -237
- unrealon_driver/src/dto/execution.py +0 -313
- unrealon_driver/src/dto/services.py +0 -311
- unrealon_driver/src/execution/__init__.py +0 -23
- unrealon_driver/src/execution/daemon_mode.py +0 -317
- unrealon_driver/src/execution/interactive_mode.py +0 -88
- unrealon_driver/src/execution/modes.py +0 -45
- unrealon_driver/src/execution/scheduled_mode.py +0 -209
- unrealon_driver/src/execution/test_mode.py +0 -250
- unrealon_driver/src/logging/__init__.py +0 -24
- unrealon_driver/src/logging/driver_logger.py +0 -512
- unrealon_driver/src/services/__init__.py +0 -24
- unrealon_driver/src/services/browser_service.py +0 -726
- unrealon_driver/src/services/llm/__init__.py +0 -15
- unrealon_driver/src/services/llm/browser_llm_service.py +0 -363
- unrealon_driver/src/services/llm/llm.py +0 -195
- unrealon_driver/src/services/logger_service.py +0 -232
- unrealon_driver/src/services/metrics_service.py +0 -185
- unrealon_driver/src/services/scheduler_service.py +0 -489
- unrealon_driver/src/services/websocket_service.py +0 -362
- unrealon_driver/src/utils/__init__.py +0 -16
- unrealon_driver/src/utils/service_factory.py +0 -317
- unrealon_driver/src/utils/time_formatter.py +0 -338
- unrealon_llm/README.md +0 -44
- unrealon_llm/__init__.py +0 -26
- unrealon_llm/pyproject.toml +0 -154
- unrealon_llm/src/__init__.py +0 -228
- unrealon_llm/src/cli/__init__.py +0 -0
- unrealon_llm/src/core/__init__.py +0 -11
- unrealon_llm/src/core/smart_client.py +0 -438
- unrealon_llm/src/dto/__init__.py +0 -155
- unrealon_llm/src/dto/models/__init__.py +0 -0
- unrealon_llm/src/dto/models/config.py +0 -343
- unrealon_llm/src/dto/models/core.py +0 -328
- unrealon_llm/src/dto/models/enums.py +0 -123
- unrealon_llm/src/dto/models/html_analysis.py +0 -345
- unrealon_llm/src/dto/models/statistics.py +0 -473
- unrealon_llm/src/dto/models/translation.py +0 -383
- unrealon_llm/src/dto/models/type_conversion.py +0 -462
- unrealon_llm/src/dto/schemas/__init__.py +0 -0
- unrealon_llm/src/exceptions.py +0 -392
- unrealon_llm/src/llm_config/__init__.py +0 -20
- unrealon_llm/src/llm_config/logging_config.py +0 -178
- unrealon_llm/src/llm_logging/__init__.py +0 -42
- unrealon_llm/src/llm_logging/llm_events.py +0 -107
- unrealon_llm/src/llm_logging/llm_logger.py +0 -466
- unrealon_llm/src/managers/__init__.py +0 -15
- unrealon_llm/src/managers/cache_manager.py +0 -67
- unrealon_llm/src/managers/cost_manager.py +0 -107
- unrealon_llm/src/managers/request_manager.py +0 -298
- unrealon_llm/src/modules/__init__.py +0 -0
- unrealon_llm/src/modules/html_processor/__init__.py +0 -25
- unrealon_llm/src/modules/html_processor/base_processor.py +0 -415
- unrealon_llm/src/modules/html_processor/details_processor.py +0 -85
- unrealon_llm/src/modules/html_processor/listing_processor.py +0 -91
- unrealon_llm/src/modules/html_processor/models/__init__.py +0 -20
- unrealon_llm/src/modules/html_processor/models/processing_models.py +0 -40
- unrealon_llm/src/modules/html_processor/models/universal_model.py +0 -56
- unrealon_llm/src/modules/html_processor/processor.py +0 -102
- unrealon_llm/src/modules/llm/__init__.py +0 -0
- unrealon_llm/src/modules/translator/__init__.py +0 -0
- unrealon_llm/src/provider.py +0 -116
- unrealon_llm/src/utils/__init__.py +0 -95
- unrealon_llm/src/utils/common.py +0 -64
- unrealon_llm/src/utils/data_extractor.py +0 -188
- unrealon_llm/src/utils/html_cleaner.py +0 -767
- unrealon_llm/src/utils/language_detector.py +0 -308
- unrealon_llm/src/utils/models_cache.py +0 -592
- unrealon_llm/src/utils/smart_counter.py +0 -229
- unrealon_llm/src/utils/token_counter.py +0 -189
- unrealon_sdk/README.md +0 -25
- unrealon_sdk/__init__.py +0 -30
- unrealon_sdk/pyproject.toml +0 -231
- unrealon_sdk/src/__init__.py +0 -150
- unrealon_sdk/src/cli/__init__.py +0 -12
- unrealon_sdk/src/cli/commands/__init__.py +0 -22
- unrealon_sdk/src/cli/commands/benchmark.py +0 -42
- unrealon_sdk/src/cli/commands/diagnostics.py +0 -573
- unrealon_sdk/src/cli/commands/health.py +0 -46
- unrealon_sdk/src/cli/commands/integration.py +0 -498
- unrealon_sdk/src/cli/commands/reports.py +0 -43
- unrealon_sdk/src/cli/commands/security.py +0 -36
- unrealon_sdk/src/cli/commands/server.py +0 -483
- unrealon_sdk/src/cli/commands/servers.py +0 -56
- unrealon_sdk/src/cli/commands/tests.py +0 -55
- unrealon_sdk/src/cli/main.py +0 -126
- unrealon_sdk/src/cli/utils/reporter.py +0 -519
- unrealon_sdk/src/clients/openapi.yaml +0 -3347
- unrealon_sdk/src/clients/python_http/__init__.py +0 -3
- unrealon_sdk/src/clients/python_http/api_config.py +0 -228
- unrealon_sdk/src/clients/python_http/models/BaseModel.py +0 -12
- unrealon_sdk/src/clients/python_http/models/BroadcastDeliveryStats.py +0 -33
- unrealon_sdk/src/clients/python_http/models/BroadcastMessage.py +0 -17
- unrealon_sdk/src/clients/python_http/models/BroadcastMessageRequest.py +0 -35
- unrealon_sdk/src/clients/python_http/models/BroadcastPriority.py +0 -10
- unrealon_sdk/src/clients/python_http/models/BroadcastResponse.py +0 -21
- unrealon_sdk/src/clients/python_http/models/BroadcastResultResponse.py +0 -33
- unrealon_sdk/src/clients/python_http/models/BroadcastTarget.py +0 -11
- unrealon_sdk/src/clients/python_http/models/ConnectionStats.py +0 -27
- unrealon_sdk/src/clients/python_http/models/ConnectionsResponse.py +0 -21
- unrealon_sdk/src/clients/python_http/models/DeveloperMessageResponse.py +0 -23
- unrealon_sdk/src/clients/python_http/models/ErrorResponse.py +0 -25
- unrealon_sdk/src/clients/python_http/models/HTTPValidationError.py +0 -16
- unrealon_sdk/src/clients/python_http/models/HealthResponse.py +0 -23
- unrealon_sdk/src/clients/python_http/models/HealthStatus.py +0 -33
- unrealon_sdk/src/clients/python_http/models/LogLevel.py +0 -10
- unrealon_sdk/src/clients/python_http/models/LoggingRequest.py +0 -27
- unrealon_sdk/src/clients/python_http/models/LoggingResponse.py +0 -23
- unrealon_sdk/src/clients/python_http/models/MaintenanceMode.py +0 -9
- unrealon_sdk/src/clients/python_http/models/MaintenanceModeRequest.py +0 -33
- unrealon_sdk/src/clients/python_http/models/MaintenanceStatusResponse.py +0 -39
- unrealon_sdk/src/clients/python_http/models/ParserCommandRequest.py +0 -25
- unrealon_sdk/src/clients/python_http/models/ParserMessageResponse.py +0 -21
- unrealon_sdk/src/clients/python_http/models/ParserRegistrationRequest.py +0 -28
- unrealon_sdk/src/clients/python_http/models/ParserRegistrationResponse.py +0 -25
- unrealon_sdk/src/clients/python_http/models/ParserType.py +0 -10
- unrealon_sdk/src/clients/python_http/models/ProxyBlockRequest.py +0 -19
- unrealon_sdk/src/clients/python_http/models/ProxyEndpointResponse.py +0 -20
- unrealon_sdk/src/clients/python_http/models/ProxyListResponse.py +0 -19
- unrealon_sdk/src/clients/python_http/models/ProxyProvider.py +0 -10
- unrealon_sdk/src/clients/python_http/models/ProxyPurchaseRequest.py +0 -25
- unrealon_sdk/src/clients/python_http/models/ProxyResponse.py +0 -47
- unrealon_sdk/src/clients/python_http/models/ProxyRotationRequest.py +0 -23
- unrealon_sdk/src/clients/python_http/models/ProxyStatus.py +0 -10
- unrealon_sdk/src/clients/python_http/models/ProxyUsageRequest.py +0 -19
- unrealon_sdk/src/clients/python_http/models/ProxyUsageStatsResponse.py +0 -26
- unrealon_sdk/src/clients/python_http/models/ServiceRegistrationDto.py +0 -23
- unrealon_sdk/src/clients/python_http/models/ServiceStatsResponse.py +0 -31
- unrealon_sdk/src/clients/python_http/models/SessionStartRequest.py +0 -23
- unrealon_sdk/src/clients/python_http/models/SuccessResponse.py +0 -25
- unrealon_sdk/src/clients/python_http/models/SystemNotificationResponse.py +0 -23
- unrealon_sdk/src/clients/python_http/models/ValidationError.py +0 -18
- unrealon_sdk/src/clients/python_http/models/ValidationErrorResponse.py +0 -21
- unrealon_sdk/src/clients/python_http/models/WebSocketMetrics.py +0 -21
- unrealon_sdk/src/clients/python_http/models/__init__.py +0 -44
- unrealon_sdk/src/clients/python_http/services/None_service.py +0 -35
- unrealon_sdk/src/clients/python_http/services/ParserManagement_service.py +0 -190
- unrealon_sdk/src/clients/python_http/services/ProxyManagement_service.py +0 -289
- unrealon_sdk/src/clients/python_http/services/SocketLogging_service.py +0 -187
- unrealon_sdk/src/clients/python_http/services/SystemHealth_service.py +0 -119
- unrealon_sdk/src/clients/python_http/services/WebSocketAPI_service.py +0 -198
- unrealon_sdk/src/clients/python_http/services/__init__.py +0 -0
- unrealon_sdk/src/clients/python_http/services/admin_service.py +0 -125
- unrealon_sdk/src/clients/python_http/services/async_None_service.py +0 -35
- unrealon_sdk/src/clients/python_http/services/async_ParserManagement_service.py +0 -190
- unrealon_sdk/src/clients/python_http/services/async_ProxyManagement_service.py +0 -289
- unrealon_sdk/src/clients/python_http/services/async_SocketLogging_service.py +0 -189
- unrealon_sdk/src/clients/python_http/services/async_SystemHealth_service.py +0 -123
- unrealon_sdk/src/clients/python_http/services/async_WebSocketAPI_service.py +0 -200
- unrealon_sdk/src/clients/python_http/services/async_admin_service.py +0 -125
- unrealon_sdk/src/clients/python_websocket/__init__.py +0 -28
- unrealon_sdk/src/clients/python_websocket/client.py +0 -490
- unrealon_sdk/src/clients/python_websocket/events.py +0 -732
- unrealon_sdk/src/clients/python_websocket/example.py +0 -136
- unrealon_sdk/src/clients/python_websocket/types.py +0 -871
- unrealon_sdk/src/core/__init__.py +0 -64
- unrealon_sdk/src/core/client.py +0 -556
- unrealon_sdk/src/core/config.py +0 -465
- unrealon_sdk/src/core/exceptions.py +0 -239
- unrealon_sdk/src/core/metadata.py +0 -191
- unrealon_sdk/src/core/models.py +0 -142
- unrealon_sdk/src/core/types.py +0 -68
- unrealon_sdk/src/dto/__init__.py +0 -268
- unrealon_sdk/src/dto/authentication.py +0 -108
- unrealon_sdk/src/dto/cache.py +0 -208
- unrealon_sdk/src/dto/common.py +0 -19
- unrealon_sdk/src/dto/concurrency.py +0 -393
- unrealon_sdk/src/dto/events.py +0 -108
- unrealon_sdk/src/dto/health.py +0 -339
- unrealon_sdk/src/dto/load_balancing.py +0 -336
- unrealon_sdk/src/dto/logging.py +0 -230
- unrealon_sdk/src/dto/performance.py +0 -165
- unrealon_sdk/src/dto/rate_limiting.py +0 -295
- unrealon_sdk/src/dto/resource_pooling.py +0 -128
- unrealon_sdk/src/dto/structured_logging.py +0 -112
- unrealon_sdk/src/dto/task_scheduling.py +0 -121
- unrealon_sdk/src/dto/websocket.py +0 -55
- unrealon_sdk/src/enterprise/__init__.py +0 -59
- unrealon_sdk/src/enterprise/authentication.py +0 -401
- unrealon_sdk/src/enterprise/cache_manager.py +0 -578
- unrealon_sdk/src/enterprise/error_recovery.py +0 -494
- unrealon_sdk/src/enterprise/event_system.py +0 -549
- unrealon_sdk/src/enterprise/health_monitor.py +0 -747
- unrealon_sdk/src/enterprise/load_balancer.py +0 -964
- unrealon_sdk/src/enterprise/logging/__init__.py +0 -68
- unrealon_sdk/src/enterprise/logging/cleanup.py +0 -156
- unrealon_sdk/src/enterprise/logging/development.py +0 -744
- unrealon_sdk/src/enterprise/logging/service.py +0 -410
- unrealon_sdk/src/enterprise/multithreading_manager.py +0 -853
- unrealon_sdk/src/enterprise/performance_monitor.py +0 -539
- unrealon_sdk/src/enterprise/proxy_manager.py +0 -696
- unrealon_sdk/src/enterprise/rate_limiter.py +0 -652
- unrealon_sdk/src/enterprise/resource_pool.py +0 -763
- unrealon_sdk/src/enterprise/task_scheduler.py +0 -709
- unrealon_sdk/src/internal/__init__.py +0 -10
- unrealon_sdk/src/internal/command_router.py +0 -497
- unrealon_sdk/src/internal/connection_manager.py +0 -397
- unrealon_sdk/src/internal/http_client.py +0 -446
- unrealon_sdk/src/internal/websocket_client.py +0 -420
- unrealon_sdk/src/provider.py +0 -471
- unrealon_sdk/src/utils.py +0 -234
- /unrealon_browser/{src/cli → cli}/__init__.py +0 -0
- /unrealon_browser/{src/cli → cli}/interactive_mode.py +0 -0
- /unrealon_browser/{src/cli → cli}/main.py +0 -0
- /unrealon_browser/{src/core → core}/__init__.py +0 -0
- /unrealon_browser/{src/dto → dto}/__init__.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/config.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/core.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/dataclasses.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/detection.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/enums.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/statistics.py +0 -0
- /unrealon_browser/{src/managers → managers}/__init__.py +0 -0
- /unrealon_browser/{src/managers → managers}/stealth.py +0 -0
|
@@ -1,539 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Performance Monitor - Layer 3 Infrastructure Service
|
|
3
|
-
|
|
4
|
-
Real-time metrics collection, trend analysis, and performance monitoring
|
|
5
|
-
for UnrealOn SDK components. Provides comprehensive observability with
|
|
6
|
-
automatic alerting, statistical analysis, and performance regression detection.
|
|
7
|
-
|
|
8
|
-
Features:
|
|
9
|
-
- Real-time metrics collection with configurable sampling
|
|
10
|
-
- Statistical trend analysis and anomaly detection
|
|
11
|
-
- Performance baseline establishment and drift detection
|
|
12
|
-
- Memory, CPU, and network utilization monitoring
|
|
13
|
-
- WebSocket/HTTP operation performance tracking
|
|
14
|
-
- Automatic alerting for performance degradation
|
|
15
|
-
- Historical data retention and aggregation
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
import asyncio
|
|
19
|
-
import logging
|
|
20
|
-
import time
|
|
21
|
-
import psutil
|
|
22
|
-
import threading
|
|
23
|
-
from typing import Dict, List, Optional, Any, Callable, Union, NamedTuple
|
|
24
|
-
from datetime import datetime, timezone, timedelta
|
|
25
|
-
from enum import Enum
|
|
26
|
-
from dataclasses import dataclass, field
|
|
27
|
-
from collections import defaultdict, deque
|
|
28
|
-
import statistics
|
|
29
|
-
import json
|
|
30
|
-
|
|
31
|
-
# Pydantic v2 for all data models
|
|
32
|
-
from pydantic import BaseModel, Field, ConfigDict
|
|
33
|
-
|
|
34
|
-
# Core SDK components
|
|
35
|
-
from unrealon_sdk.src.core.config import AdapterConfig
|
|
36
|
-
from unrealon_sdk.src.utils import generate_correlation_id
|
|
37
|
-
|
|
38
|
-
# DTO models
|
|
39
|
-
from unrealon_sdk.src.dto.logging import SDKEventType, SDKSeverity
|
|
40
|
-
from unrealon_sdk.src.dto.performance import (
|
|
41
|
-
MetricType,
|
|
42
|
-
AlertSeverity,
|
|
43
|
-
MetricUnit,
|
|
44
|
-
MetricValue,
|
|
45
|
-
MetricThreshold,
|
|
46
|
-
PerformanceMetric,
|
|
47
|
-
PerformanceAlert,
|
|
48
|
-
PerformanceReport,
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
# Development logging
|
|
52
|
-
from typing import TYPE_CHECKING
|
|
53
|
-
|
|
54
|
-
if TYPE_CHECKING:
|
|
55
|
-
from unrealon_sdk.src.enterprise.logging import DevelopmentLogger
|
|
56
|
-
|
|
57
|
-
logger = logging.getLogger(__name__)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
class PerformanceMonitor:
|
|
61
|
-
"""
|
|
62
|
-
Enterprise-grade performance monitoring system.
|
|
63
|
-
|
|
64
|
-
Provides real-time metrics collection, trend analysis, and alerting
|
|
65
|
-
for comprehensive observability of SDK performance.
|
|
66
|
-
"""
|
|
67
|
-
|
|
68
|
-
def __init__(
|
|
69
|
-
self,
|
|
70
|
-
config: AdapterConfig,
|
|
71
|
-
collection_interval: float = 1.0,
|
|
72
|
-
retention_hours: int = 24,
|
|
73
|
-
max_samples_per_metric: int = 10000,
|
|
74
|
-
dev_logger: Optional["DevelopmentLogger"] = None,
|
|
75
|
-
):
|
|
76
|
-
"""Initialize performance monitor."""
|
|
77
|
-
self.config = config
|
|
78
|
-
self.collection_interval = collection_interval
|
|
79
|
-
self.retention_hours = retention_hours
|
|
80
|
-
self.max_samples_per_metric = max_samples_per_metric
|
|
81
|
-
self.dev_logger = dev_logger
|
|
82
|
-
|
|
83
|
-
# Metrics storage
|
|
84
|
-
self.metrics: Dict[str, PerformanceMetric] = {}
|
|
85
|
-
self.metric_values: Dict[str, deque[MetricValue]] = defaultdict(
|
|
86
|
-
lambda: deque(maxlen=max_samples_per_metric)
|
|
87
|
-
)
|
|
88
|
-
self.metric_thresholds: Dict[str, MetricThreshold] = {}
|
|
89
|
-
|
|
90
|
-
# Alerts
|
|
91
|
-
self.active_alerts: Dict[str, PerformanceAlert] = {}
|
|
92
|
-
self.alert_history: List[PerformanceAlert] = []
|
|
93
|
-
self.alert_callbacks: List[Callable[[PerformanceAlert], None]] = []
|
|
94
|
-
|
|
95
|
-
# Background tasks
|
|
96
|
-
self._collection_task: Optional[asyncio.Task[None]] = None
|
|
97
|
-
self._cleanup_task: Optional[asyncio.Task[None]] = None
|
|
98
|
-
self._shutdown = False
|
|
99
|
-
|
|
100
|
-
# Thread safety
|
|
101
|
-
self._lock = threading.Lock()
|
|
102
|
-
|
|
103
|
-
# Built-in system metrics
|
|
104
|
-
self._register_system_metrics()
|
|
105
|
-
|
|
106
|
-
self._log_info("Performance monitor initialized")
|
|
107
|
-
|
|
108
|
-
def _register_system_metrics(self) -> None:
|
|
109
|
-
"""Register built-in system performance metrics."""
|
|
110
|
-
self.register_metric(
|
|
111
|
-
"system.cpu.percent",
|
|
112
|
-
MetricType.GAUGE,
|
|
113
|
-
MetricUnit.PERCENT,
|
|
114
|
-
"CPU usage percentage",
|
|
115
|
-
MetricThreshold(warning_threshold=70.0, error_threshold=85.0, critical_threshold=95.0),
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
self.register_metric(
|
|
119
|
-
"system.memory.used_mb",
|
|
120
|
-
MetricType.GAUGE,
|
|
121
|
-
MetricUnit.MEGABYTES,
|
|
122
|
-
"Memory usage in megabytes",
|
|
123
|
-
MetricThreshold(
|
|
124
|
-
warning_threshold=1024.0, error_threshold=2048.0, critical_threshold=4096.0
|
|
125
|
-
),
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
self.register_metric(
|
|
129
|
-
"system.memory.percent",
|
|
130
|
-
MetricType.GAUGE,
|
|
131
|
-
MetricUnit.PERCENT,
|
|
132
|
-
"Memory usage percentage",
|
|
133
|
-
MetricThreshold(warning_threshold=70.0, error_threshold=85.0, critical_threshold=95.0),
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
self.register_metric(
|
|
137
|
-
"sdk.operations.total",
|
|
138
|
-
MetricType.COUNTER,
|
|
139
|
-
MetricUnit.COUNT,
|
|
140
|
-
"Total SDK operations performed",
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
self.register_metric(
|
|
144
|
-
"sdk.operations.duration_ms",
|
|
145
|
-
MetricType.HISTOGRAM,
|
|
146
|
-
MetricUnit.MILLISECONDS,
|
|
147
|
-
"SDK operation duration",
|
|
148
|
-
MetricThreshold(
|
|
149
|
-
warning_threshold=1000.0, error_threshold=5000.0, critical_threshold=10000.0
|
|
150
|
-
),
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
self.register_metric(
|
|
154
|
-
"sdk.errors.total", MetricType.COUNTER, MetricUnit.COUNT, "Total SDK errors"
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
self.register_metric(
|
|
158
|
-
"sdk.errors.rate_per_minute",
|
|
159
|
-
MetricType.RATE,
|
|
160
|
-
MetricUnit.PER_MINUTE,
|
|
161
|
-
"SDK error rate per minute",
|
|
162
|
-
MetricThreshold(warning_threshold=10.0, error_threshold=50.0, critical_threshold=100.0),
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
async def start(self) -> None:
|
|
166
|
-
"""Start performance monitoring."""
|
|
167
|
-
if self._collection_task is None:
|
|
168
|
-
self._collection_task = asyncio.create_task(self._collection_loop())
|
|
169
|
-
self._cleanup_task = asyncio.create_task(self._cleanup_loop())
|
|
170
|
-
|
|
171
|
-
self._log_info("Performance monitoring started")
|
|
172
|
-
|
|
173
|
-
async def stop(self) -> None:
|
|
174
|
-
"""Stop performance monitoring."""
|
|
175
|
-
self._shutdown = True
|
|
176
|
-
|
|
177
|
-
if self._collection_task:
|
|
178
|
-
self._collection_task.cancel()
|
|
179
|
-
try:
|
|
180
|
-
await self._collection_task
|
|
181
|
-
except asyncio.CancelledError:
|
|
182
|
-
pass
|
|
183
|
-
|
|
184
|
-
if self._cleanup_task:
|
|
185
|
-
self._cleanup_task.cancel()
|
|
186
|
-
try:
|
|
187
|
-
await self._cleanup_task
|
|
188
|
-
except asyncio.CancelledError:
|
|
189
|
-
pass
|
|
190
|
-
|
|
191
|
-
self._log_info("Performance monitoring stopped")
|
|
192
|
-
|
|
193
|
-
def register_metric(
|
|
194
|
-
self,
|
|
195
|
-
name: str,
|
|
196
|
-
metric_type: MetricType,
|
|
197
|
-
unit: MetricUnit,
|
|
198
|
-
description: str,
|
|
199
|
-
threshold: Optional[MetricThreshold] = None,
|
|
200
|
-
tags: Optional[Dict[str, str]] = None,
|
|
201
|
-
) -> None:
|
|
202
|
-
"""Register a new performance metric."""
|
|
203
|
-
with self._lock:
|
|
204
|
-
self.metrics[name] = PerformanceMetric(
|
|
205
|
-
name=name,
|
|
206
|
-
metric_type=metric_type,
|
|
207
|
-
unit=unit,
|
|
208
|
-
description=description,
|
|
209
|
-
tags=tags or {},
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
if threshold:
|
|
213
|
-
self.metric_thresholds[name] = threshold
|
|
214
|
-
|
|
215
|
-
self._log_info(f"Registered metric: {name} ({metric_type.value})")
|
|
216
|
-
|
|
217
|
-
def record_value(
|
|
218
|
-
self,
|
|
219
|
-
metric_name: str,
|
|
220
|
-
value: Union[int, float],
|
|
221
|
-
labels: Optional[Dict[str, str]] = None,
|
|
222
|
-
) -> None:
|
|
223
|
-
"""Record a metric value."""
|
|
224
|
-
if metric_name not in self.metrics:
|
|
225
|
-
logger.warning(f"Unknown metric: {metric_name}")
|
|
226
|
-
return
|
|
227
|
-
|
|
228
|
-
timestamp = datetime.now(timezone.utc)
|
|
229
|
-
metric_value = MetricValue(timestamp=timestamp, value=float(value), labels=labels or {})
|
|
230
|
-
|
|
231
|
-
with self._lock:
|
|
232
|
-
# Add to values
|
|
233
|
-
self.metric_values[metric_name].append(metric_value)
|
|
234
|
-
|
|
235
|
-
# Update metric statistics
|
|
236
|
-
metric = self.metrics[metric_name]
|
|
237
|
-
metric.current_value = float(value)
|
|
238
|
-
metric.total_samples += 1
|
|
239
|
-
metric.last_updated = timestamp
|
|
240
|
-
|
|
241
|
-
# Update min/max/avg
|
|
242
|
-
values = [mv.value for mv in self.metric_values[metric_name]]
|
|
243
|
-
metric.min_value = min(values)
|
|
244
|
-
metric.max_value = max(values)
|
|
245
|
-
metric.avg_value = statistics.mean(values)
|
|
246
|
-
|
|
247
|
-
# Check thresholds
|
|
248
|
-
self._check_thresholds(metric_name, float(value))
|
|
249
|
-
|
|
250
|
-
def increment_counter(
|
|
251
|
-
self,
|
|
252
|
-
metric_name: str,
|
|
253
|
-
increment: Union[int, float] = 1,
|
|
254
|
-
labels: Optional[Dict[str, str]] = None,
|
|
255
|
-
) -> None:
|
|
256
|
-
"""Increment a counter metric."""
|
|
257
|
-
if metric_name not in self.metrics:
|
|
258
|
-
logger.warning(f"Unknown metric: {metric_name}")
|
|
259
|
-
return
|
|
260
|
-
|
|
261
|
-
metric = self.metrics[metric_name]
|
|
262
|
-
if metric.metric_type != MetricType.COUNTER:
|
|
263
|
-
logger.warning(f"Metric {metric_name} is not a counter")
|
|
264
|
-
return
|
|
265
|
-
|
|
266
|
-
current_value = metric.current_value or 0
|
|
267
|
-
self.record_value(metric_name, current_value + increment, labels)
|
|
268
|
-
|
|
269
|
-
def record_timer(
|
|
270
|
-
self,
|
|
271
|
-
metric_name: str,
|
|
272
|
-
duration_ms: float,
|
|
273
|
-
labels: Optional[Dict[str, str]] = None,
|
|
274
|
-
) -> None:
|
|
275
|
-
"""Record a timer measurement."""
|
|
276
|
-
self.record_value(metric_name, duration_ms, labels)
|
|
277
|
-
|
|
278
|
-
def _check_thresholds(self, metric_name: str, value: float) -> None:
|
|
279
|
-
"""Check if metric value exceeds thresholds."""
|
|
280
|
-
if metric_name not in self.metric_thresholds:
|
|
281
|
-
return
|
|
282
|
-
|
|
283
|
-
threshold = self.metric_thresholds[metric_name]
|
|
284
|
-
severity = None
|
|
285
|
-
threshold_value = None
|
|
286
|
-
|
|
287
|
-
if threshold.critical_threshold and value >= threshold.critical_threshold:
|
|
288
|
-
severity = AlertSeverity.CRITICAL
|
|
289
|
-
threshold_value = threshold.critical_threshold
|
|
290
|
-
elif threshold.error_threshold and value >= threshold.error_threshold:
|
|
291
|
-
severity = AlertSeverity.ERROR
|
|
292
|
-
threshold_value = threshold.error_threshold
|
|
293
|
-
elif threshold.warning_threshold and value >= threshold.warning_threshold:
|
|
294
|
-
severity = AlertSeverity.WARNING
|
|
295
|
-
threshold_value = threshold.warning_threshold
|
|
296
|
-
|
|
297
|
-
if severity and threshold_value:
|
|
298
|
-
self._create_alert(metric_name, severity, threshold_value, value)
|
|
299
|
-
|
|
300
|
-
def _create_alert(
|
|
301
|
-
self,
|
|
302
|
-
metric_name: str,
|
|
303
|
-
severity: AlertSeverity,
|
|
304
|
-
threshold_value: float,
|
|
305
|
-
current_value: float,
|
|
306
|
-
) -> None:
|
|
307
|
-
"""Create performance alert."""
|
|
308
|
-
alert = PerformanceAlert(
|
|
309
|
-
metric_name=metric_name,
|
|
310
|
-
severity=severity,
|
|
311
|
-
threshold_value=threshold_value,
|
|
312
|
-
current_value=current_value,
|
|
313
|
-
message=f"Metric {metric_name} exceeded {severity.value} threshold: {current_value} >= {threshold_value}",
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
# Store alert
|
|
317
|
-
with self._lock:
|
|
318
|
-
self.active_alerts[alert.alert_id] = alert
|
|
319
|
-
self.alert_history.append(alert)
|
|
320
|
-
|
|
321
|
-
# Notify callbacks
|
|
322
|
-
for callback in self.alert_callbacks:
|
|
323
|
-
try:
|
|
324
|
-
callback(alert)
|
|
325
|
-
except Exception as e:
|
|
326
|
-
logger.error(f"Error in alert callback: {e}")
|
|
327
|
-
|
|
328
|
-
self._log_error(f"Performance alert: {alert.message}", severity=severity)
|
|
329
|
-
|
|
330
|
-
async def _collection_loop(self) -> None:
|
|
331
|
-
"""Background task for collecting system metrics."""
|
|
332
|
-
while not self._shutdown:
|
|
333
|
-
try:
|
|
334
|
-
await self._collect_system_metrics()
|
|
335
|
-
await asyncio.sleep(self.collection_interval)
|
|
336
|
-
except asyncio.CancelledError:
|
|
337
|
-
break
|
|
338
|
-
except Exception as e:
|
|
339
|
-
logger.error(f"Error in metrics collection: {e}")
|
|
340
|
-
await asyncio.sleep(self.collection_interval)
|
|
341
|
-
|
|
342
|
-
async def _collect_system_metrics(self) -> None:
|
|
343
|
-
"""Collect system performance metrics."""
|
|
344
|
-
try:
|
|
345
|
-
# CPU usage
|
|
346
|
-
cpu_percent = psutil.cpu_percent(interval=None)
|
|
347
|
-
self.record_value("system.cpu.percent", cpu_percent)
|
|
348
|
-
|
|
349
|
-
# Memory usage
|
|
350
|
-
memory = psutil.virtual_memory()
|
|
351
|
-
memory_mb = memory.used / (1024 * 1024)
|
|
352
|
-
self.record_value("system.memory.used_mb", memory_mb)
|
|
353
|
-
self.record_value("system.memory.percent", memory.percent)
|
|
354
|
-
|
|
355
|
-
except Exception as e:
|
|
356
|
-
logger.error(f"Error collecting system metrics: {e}")
|
|
357
|
-
|
|
358
|
-
async def _cleanup_loop(self) -> None:
|
|
359
|
-
"""Background task for cleaning up old data."""
|
|
360
|
-
while not self._shutdown:
|
|
361
|
-
try:
|
|
362
|
-
await asyncio.sleep(3600) # Run every hour
|
|
363
|
-
await self._cleanup_old_data()
|
|
364
|
-
except asyncio.CancelledError:
|
|
365
|
-
break
|
|
366
|
-
except Exception as e:
|
|
367
|
-
logger.error(f"Error in cleanup: {e}")
|
|
368
|
-
|
|
369
|
-
async def _cleanup_old_data(self) -> None:
|
|
370
|
-
"""Clean up old metric data and alerts."""
|
|
371
|
-
cutoff_time = datetime.now(timezone.utc) - timedelta(hours=self.retention_hours)
|
|
372
|
-
|
|
373
|
-
with self._lock:
|
|
374
|
-
# Clean old metric values
|
|
375
|
-
for metric_name, values in self.metric_values.items():
|
|
376
|
-
# Remove values older than retention period
|
|
377
|
-
while values and values[0].timestamp < cutoff_time:
|
|
378
|
-
values.popleft()
|
|
379
|
-
|
|
380
|
-
# Clean old alerts
|
|
381
|
-
self.alert_history = [
|
|
382
|
-
alert for alert in self.alert_history if alert.timestamp >= cutoff_time
|
|
383
|
-
]
|
|
384
|
-
|
|
385
|
-
self._log_info(f"Cleaned up data older than {self.retention_hours} hours")
|
|
386
|
-
|
|
387
|
-
def get_metric(self, name: str) -> Optional[PerformanceMetric]:
|
|
388
|
-
"""Get metric by name."""
|
|
389
|
-
return self.metrics.get(name)
|
|
390
|
-
|
|
391
|
-
def get_metric_values(
|
|
392
|
-
self,
|
|
393
|
-
name: str,
|
|
394
|
-
start_time: Optional[datetime] = None,
|
|
395
|
-
end_time: Optional[datetime] = None,
|
|
396
|
-
) -> List[MetricValue]:
|
|
397
|
-
"""Get metric values within time range."""
|
|
398
|
-
if name not in self.metric_values:
|
|
399
|
-
return []
|
|
400
|
-
|
|
401
|
-
values = list(self.metric_values[name])
|
|
402
|
-
|
|
403
|
-
if start_time:
|
|
404
|
-
values = [v for v in values if v.timestamp >= start_time]
|
|
405
|
-
|
|
406
|
-
if end_time:
|
|
407
|
-
values = [v for v in values if v.timestamp <= end_time]
|
|
408
|
-
|
|
409
|
-
return values
|
|
410
|
-
|
|
411
|
-
def get_active_alerts(self) -> List[PerformanceAlert]:
|
|
412
|
-
"""Get all active alerts."""
|
|
413
|
-
with self._lock:
|
|
414
|
-
return [alert for alert in self.active_alerts.values() if not alert.resolved]
|
|
415
|
-
|
|
416
|
-
def acknowledge_alert(self, alert_id: str) -> bool:
|
|
417
|
-
"""Acknowledge an alert."""
|
|
418
|
-
with self._lock:
|
|
419
|
-
if alert_id in self.active_alerts:
|
|
420
|
-
self.active_alerts[alert_id].acknowledged = True
|
|
421
|
-
return True
|
|
422
|
-
return False
|
|
423
|
-
|
|
424
|
-
def resolve_alert(self, alert_id: str) -> bool:
|
|
425
|
-
"""Resolve an alert."""
|
|
426
|
-
with self._lock:
|
|
427
|
-
if alert_id in self.active_alerts:
|
|
428
|
-
alert = self.active_alerts[alert_id]
|
|
429
|
-
alert.resolved = True
|
|
430
|
-
alert.acknowledged = True
|
|
431
|
-
return True
|
|
432
|
-
return False
|
|
433
|
-
|
|
434
|
-
def add_alert_callback(self, callback: Callable[[PerformanceAlert], None]) -> None:
|
|
435
|
-
"""Add callback for alert notifications."""
|
|
436
|
-
self.alert_callbacks.append(callback)
|
|
437
|
-
|
|
438
|
-
def generate_report(
|
|
439
|
-
self,
|
|
440
|
-
start_time: Optional[datetime] = None,
|
|
441
|
-
end_time: Optional[datetime] = None,
|
|
442
|
-
) -> PerformanceReport:
|
|
443
|
-
"""Generate comprehensive performance report."""
|
|
444
|
-
if not start_time:
|
|
445
|
-
start_time = datetime.now(timezone.utc) - timedelta(hours=1)
|
|
446
|
-
if not end_time:
|
|
447
|
-
end_time = datetime.now(timezone.utc)
|
|
448
|
-
|
|
449
|
-
# Collect metrics for report period
|
|
450
|
-
cpu_values = [
|
|
451
|
-
v.value for v in self.get_metric_values("system.cpu.percent", start_time, end_time)
|
|
452
|
-
]
|
|
453
|
-
memory_values = [
|
|
454
|
-
v.value for v in self.get_metric_values("system.memory.used_mb", start_time, end_time)
|
|
455
|
-
]
|
|
456
|
-
|
|
457
|
-
# Calculate aggregates
|
|
458
|
-
avg_cpu = statistics.mean(cpu_values) if cpu_values else 0.0
|
|
459
|
-
avg_memory = statistics.mean(memory_values) if memory_values else 0.0
|
|
460
|
-
peak_memory = max(memory_values) if memory_values else 0.0
|
|
461
|
-
|
|
462
|
-
# Count alerts in period
|
|
463
|
-
period_alerts = [
|
|
464
|
-
alert for alert in self.alert_history if start_time <= alert.timestamp <= end_time
|
|
465
|
-
]
|
|
466
|
-
|
|
467
|
-
critical_alerts = len([a for a in period_alerts if a.severity == AlertSeverity.CRITICAL])
|
|
468
|
-
unresolved_alerts = len([a for a in period_alerts if not a.resolved])
|
|
469
|
-
|
|
470
|
-
return PerformanceReport(
|
|
471
|
-
period_start=start_time,
|
|
472
|
-
period_end=end_time,
|
|
473
|
-
avg_cpu_percent=avg_cpu,
|
|
474
|
-
avg_memory_mb=avg_memory,
|
|
475
|
-
peak_memory_mb=peak_memory,
|
|
476
|
-
total_operations=0, # Would be calculated from operation metrics
|
|
477
|
-
avg_operation_time_ms=0.0,
|
|
478
|
-
error_rate_percent=0.0,
|
|
479
|
-
total_requests=0,
|
|
480
|
-
avg_response_time_ms=0.0,
|
|
481
|
-
timeout_count=0,
|
|
482
|
-
total_alerts=len(period_alerts),
|
|
483
|
-
critical_alerts=critical_alerts,
|
|
484
|
-
unresolved_alerts=unresolved_alerts,
|
|
485
|
-
)
|
|
486
|
-
|
|
487
|
-
def _log_info(self, message: str, **kwargs: Any) -> None:
|
|
488
|
-
"""Log info message."""
|
|
489
|
-
if self.dev_logger:
|
|
490
|
-
self.dev_logger.log_info(SDKEventType.PERFORMANCE_METRIC_COLLECTED, message, **kwargs)
|
|
491
|
-
else:
|
|
492
|
-
logger.info(message)
|
|
493
|
-
|
|
494
|
-
def _log_error(
|
|
495
|
-
self, message: str, severity: AlertSeverity = AlertSeverity.ERROR, **kwargs: Any
|
|
496
|
-
) -> None:
|
|
497
|
-
"""Log error message."""
|
|
498
|
-
if self.dev_logger:
|
|
499
|
-
sdk_severity = {
|
|
500
|
-
AlertSeverity.WARNING: SDKSeverity.WARNING,
|
|
501
|
-
AlertSeverity.ERROR: SDKSeverity.ERROR,
|
|
502
|
-
AlertSeverity.CRITICAL: SDKSeverity.CRITICAL,
|
|
503
|
-
}.get(severity, SDKSeverity.ERROR)
|
|
504
|
-
|
|
505
|
-
self.dev_logger.log_error(
|
|
506
|
-
SDKEventType.PERFORMANCE_THRESHOLD_EXCEEDED, message, **kwargs
|
|
507
|
-
)
|
|
508
|
-
else:
|
|
509
|
-
logger.error(message)
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
# Context manager for timing operations
|
|
513
|
-
class PerformanceTimer:
|
|
514
|
-
"""Context manager for timing operations."""
|
|
515
|
-
|
|
516
|
-
def __init__(
|
|
517
|
-
self, monitor: PerformanceMonitor, metric_name: str, labels: Optional[Dict[str, str]] = None
|
|
518
|
-
):
|
|
519
|
-
self.monitor = monitor
|
|
520
|
-
self.metric_name = metric_name
|
|
521
|
-
self.labels = labels
|
|
522
|
-
self.start_time: Optional[float] = None
|
|
523
|
-
|
|
524
|
-
def __enter__(self) -> "PerformanceTimer":
|
|
525
|
-
self.start_time = time.time()
|
|
526
|
-
return self
|
|
527
|
-
|
|
528
|
-
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
529
|
-
if self.start_time:
|
|
530
|
-
duration_ms = (time.time() - self.start_time) * 1000
|
|
531
|
-
self.monitor.record_timer(self.metric_name, duration_ms, self.labels)
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
__all__ = [
|
|
535
|
-
# Main class
|
|
536
|
-
"PerformanceMonitor",
|
|
537
|
-
# Utilities
|
|
538
|
-
"PerformanceTimer",
|
|
539
|
-
]
|