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,744 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Development Process Logger for UnrealOn SDK
|
|
3
|
-
|
|
4
|
-
Enterprise-grade development logging system for tracking SDK development process,
|
|
5
|
-
performance metrics, debugging information, and compliance with development standards.
|
|
6
|
-
Following KISS methodology and 100% Pydantic v2 compliance.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import logging
|
|
10
|
-
import json
|
|
11
|
-
import asyncio
|
|
12
|
-
from typing import Optional, List, Any, Dict
|
|
13
|
-
from datetime import datetime, timezone
|
|
14
|
-
from enum import Enum
|
|
15
|
-
from dataclasses import dataclass
|
|
16
|
-
import threading
|
|
17
|
-
import traceback
|
|
18
|
-
import sys
|
|
19
|
-
import os
|
|
20
|
-
|
|
21
|
-
# Pydantic v2 for all data models
|
|
22
|
-
from pydantic import BaseModel, Field, ConfigDict
|
|
23
|
-
|
|
24
|
-
# Auto-generated models from the API
|
|
25
|
-
# Import from centralized logging service
|
|
26
|
-
from unrealon_sdk.src.enterprise.logging.service import LogLevel, LogEntryMessage
|
|
27
|
-
|
|
28
|
-
# DTO models for development logging
|
|
29
|
-
from unrealon_sdk.src.dto.logging import SDKEventType, SDKSeverity, SDKContext, SDKDevelopmentEvent
|
|
30
|
-
|
|
31
|
-
# Core SDK components
|
|
32
|
-
from unrealon_sdk.src.core.exceptions import LoggingError
|
|
33
|
-
from unrealon_sdk.src.utils import generate_correlation_id
|
|
34
|
-
|
|
35
|
-
# Import cleanup module at module level to avoid inline imports
|
|
36
|
-
from unrealon_sdk.src.enterprise.logging.cleanup import clear_development_logs, sdk_startup_cleanup
|
|
37
|
-
|
|
38
|
-
# Direct import needed for return type
|
|
39
|
-
try:
|
|
40
|
-
from unrealon_sdk.src.core.metadata import DevelopmentLoggerStatistics
|
|
41
|
-
except ImportError:
|
|
42
|
-
# Fallback for circular import issues
|
|
43
|
-
from typing import Any as DevelopmentLoggerStatistics
|
|
44
|
-
|
|
45
|
-
logger = logging.getLogger(__name__)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
class DevelopmentLogger:
|
|
49
|
-
"""
|
|
50
|
-
Enterprise-grade development logging system for UnrealOn SDK.
|
|
51
|
-
|
|
52
|
-
Features:
|
|
53
|
-
- Structured development event logging
|
|
54
|
-
- Real-time WebSocket streaming
|
|
55
|
-
- Performance metrics tracking
|
|
56
|
-
- Code quality monitoring
|
|
57
|
-
- Layer-based development tracking (Skyscraper Architecture)
|
|
58
|
-
- Type-safe logging with Pydantic v2
|
|
59
|
-
- Thread-safe operations
|
|
60
|
-
- Memory-efficient buffering
|
|
61
|
-
"""
|
|
62
|
-
|
|
63
|
-
def __init__(
|
|
64
|
-
self,
|
|
65
|
-
session_id: Optional[str] = None,
|
|
66
|
-
log_level: SDKSeverity = SDKSeverity.INFO,
|
|
67
|
-
enable_console: bool = True,
|
|
68
|
-
enable_websocket: bool = True,
|
|
69
|
-
buffer_size: int = 50,
|
|
70
|
-
flush_interval_seconds: float = 2.0,
|
|
71
|
-
):
|
|
72
|
-
"""Initialize development logger."""
|
|
73
|
-
self.session_id = session_id or generate_correlation_id()
|
|
74
|
-
self.log_level = log_level
|
|
75
|
-
self.enable_console = enable_console
|
|
76
|
-
self.enable_websocket = enable_websocket
|
|
77
|
-
|
|
78
|
-
# WebSocket client for real-time streaming (will be injected)
|
|
79
|
-
self._websocket_client = None
|
|
80
|
-
|
|
81
|
-
# Buffering for performance
|
|
82
|
-
self._buffer: List[SDKDevelopmentEvent] = []
|
|
83
|
-
self._buffer_lock = threading.Lock()
|
|
84
|
-
self._buffer_size = buffer_size
|
|
85
|
-
self._flush_interval = flush_interval_seconds
|
|
86
|
-
self._flush_task: Optional[asyncio.Task[None]] = None
|
|
87
|
-
|
|
88
|
-
# Statistics
|
|
89
|
-
self._events_logged = 0
|
|
90
|
-
self._events_by_type: Dict[SDKEventType, int] = {}
|
|
91
|
-
self._events_by_severity = {severity: 0 for severity in SDKSeverity}
|
|
92
|
-
self._errors_count = 0
|
|
93
|
-
self._warnings_count = 0
|
|
94
|
-
|
|
95
|
-
# Context tracking
|
|
96
|
-
self._current_layer: Optional[str] = None
|
|
97
|
-
self._current_component: Optional[str] = None
|
|
98
|
-
self._active_operations: Dict[str, datetime] = {}
|
|
99
|
-
|
|
100
|
-
# Standard logger for console output
|
|
101
|
-
self._setup_console_logger()
|
|
102
|
-
|
|
103
|
-
# Perform automatic log cleanup for development logs
|
|
104
|
-
self._cleanup_development_logs()
|
|
105
|
-
|
|
106
|
-
# State
|
|
107
|
-
self._initialized = True
|
|
108
|
-
self._shutdown = False
|
|
109
|
-
|
|
110
|
-
self.log_info(
|
|
111
|
-
SDKEventType.SDK_INITIALIZED,
|
|
112
|
-
f"DevelopmentLogger initialized for session {self.session_id}",
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
def _cleanup_development_logs(self) -> None:
|
|
116
|
-
"""Cleanup old development logs on startup."""
|
|
117
|
-
try:
|
|
118
|
-
# Use sdk_startup_cleanup to ensure it happens only once
|
|
119
|
-
sdk_startup_cleanup()
|
|
120
|
-
except Exception as e:
|
|
121
|
-
# Don't fail logger initialization due to cleanup issues
|
|
122
|
-
print(f"⚠️ SDK: Development log cleanup failed: {e}")
|
|
123
|
-
|
|
124
|
-
def _setup_console_logger(self) -> None:
|
|
125
|
-
"""Setup console logging with structured formatting."""
|
|
126
|
-
if not self.enable_console:
|
|
127
|
-
return
|
|
128
|
-
|
|
129
|
-
self.console_logger = logging.getLogger(f"sdk_dev_{self.session_id}")
|
|
130
|
-
self.console_logger.setLevel(self._severity_to_logging_level(self.log_level))
|
|
131
|
-
|
|
132
|
-
# Clear existing handlers
|
|
133
|
-
self.console_logger.handlers.clear()
|
|
134
|
-
|
|
135
|
-
# Custom formatter for development logs
|
|
136
|
-
formatter = logging.Formatter(
|
|
137
|
-
"%(asctime)s | SDK-DEV | %(levelname)s | %(message)s", datefmt="%H:%M:%S"
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
console_handler = logging.StreamHandler(sys.stdout)
|
|
141
|
-
console_handler.setFormatter(formatter)
|
|
142
|
-
self.console_logger.addHandler(console_handler)
|
|
143
|
-
|
|
144
|
-
# Prevent propagation to avoid duplicate logs
|
|
145
|
-
self.console_logger.propagate = False
|
|
146
|
-
|
|
147
|
-
async def initialize_websocket(self, websocket_client) -> None:
|
|
148
|
-
"""Initialize WebSocket client for real-time log streaming."""
|
|
149
|
-
self._websocket_client = websocket_client
|
|
150
|
-
|
|
151
|
-
if self.enable_websocket and self._flush_task is None:
|
|
152
|
-
self._flush_task = asyncio.create_task(self._auto_flush_loop())
|
|
153
|
-
|
|
154
|
-
self.log_info(
|
|
155
|
-
SDKEventType.LOGGING_SERVICE_INITIALIZED,
|
|
156
|
-
"WebSocket client initialized for development logging",
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
async def shutdown(self) -> None:
|
|
160
|
-
"""Shutdown logger and flush remaining events."""
|
|
161
|
-
self._shutdown = True
|
|
162
|
-
|
|
163
|
-
if self._flush_task:
|
|
164
|
-
self._flush_task.cancel()
|
|
165
|
-
try:
|
|
166
|
-
await self._flush_task
|
|
167
|
-
except asyncio.CancelledError:
|
|
168
|
-
pass
|
|
169
|
-
|
|
170
|
-
# Final flush
|
|
171
|
-
await self._flush_buffer()
|
|
172
|
-
|
|
173
|
-
self.log_info(
|
|
174
|
-
SDKEventType.SDK_SHUTDOWN,
|
|
175
|
-
f"DevelopmentLogger shutdown complete. Total events: {self._events_logged}",
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
# Context Management
|
|
179
|
-
def set_layer_context(self, layer_name: str) -> None:
|
|
180
|
-
"""Set current development layer context."""
|
|
181
|
-
self._current_layer = layer_name
|
|
182
|
-
self.log_info(
|
|
183
|
-
SDKEventType.LAYER_STARTED,
|
|
184
|
-
f"Entering development layer: {layer_name}",
|
|
185
|
-
context=SDKContext(layer_name=layer_name),
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
def set_component_context(self, component_name: str) -> None:
|
|
189
|
-
"""Set current component context."""
|
|
190
|
-
self._current_component = component_name
|
|
191
|
-
self.log_debug(
|
|
192
|
-
SDKEventType.COMPONENT_CREATED,
|
|
193
|
-
f"Working on component: {component_name}",
|
|
194
|
-
context=SDKContext(component_name=component_name, layer_name=self._current_layer),
|
|
195
|
-
)
|
|
196
|
-
|
|
197
|
-
def start_operation(self, operation_id: str, description: str) -> None:
|
|
198
|
-
"""Start tracking a long-running operation."""
|
|
199
|
-
self._active_operations[operation_id] = datetime.now(timezone.utc)
|
|
200
|
-
self.log_debug(
|
|
201
|
-
SDKEventType.DEBUG_CHECKPOINT,
|
|
202
|
-
f"Started operation: {description}",
|
|
203
|
-
context=SDKContext(correlation_id=operation_id),
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
def complete_operation(self, operation_id: str, description: str, success: bool = True) -> None:
|
|
207
|
-
"""Complete a tracked operation."""
|
|
208
|
-
if operation_id in self._active_operations:
|
|
209
|
-
start_time = self._active_operations.pop(operation_id)
|
|
210
|
-
duration = (datetime.now(timezone.utc) - start_time).total_seconds() * 1000
|
|
211
|
-
|
|
212
|
-
self.log_info(
|
|
213
|
-
SDKEventType.COMPONENT_INTEGRATED if success else SDKEventType.COMPONENT_DEPRECATED,
|
|
214
|
-
f"Completed operation: {description}",
|
|
215
|
-
success=success,
|
|
216
|
-
context=SDKContext(correlation_id=operation_id, execution_time_ms=duration),
|
|
217
|
-
duration_ms=duration,
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
# Logging Methods
|
|
221
|
-
def log_trace(
|
|
222
|
-
self,
|
|
223
|
-
event_type: SDKEventType,
|
|
224
|
-
message: str,
|
|
225
|
-
context: Optional[SDKContext] = None,
|
|
226
|
-
details: Optional[Any] = None,
|
|
227
|
-
) -> None:
|
|
228
|
-
"""Log trace-level event."""
|
|
229
|
-
self._log_event(
|
|
230
|
-
event_type=event_type,
|
|
231
|
-
message=message,
|
|
232
|
-
severity=SDKSeverity.TRACE,
|
|
233
|
-
success=True,
|
|
234
|
-
context=context,
|
|
235
|
-
details=details,
|
|
236
|
-
)
|
|
237
|
-
|
|
238
|
-
def log_debug(
|
|
239
|
-
self,
|
|
240
|
-
event_type: SDKEventType,
|
|
241
|
-
message: str,
|
|
242
|
-
context: Optional[SDKContext] = None,
|
|
243
|
-
details: Optional[Any] = None,
|
|
244
|
-
) -> None:
|
|
245
|
-
"""Log debug-level event."""
|
|
246
|
-
self._log_event(
|
|
247
|
-
event_type=event_type,
|
|
248
|
-
message=message,
|
|
249
|
-
severity=SDKSeverity.DEBUG,
|
|
250
|
-
success=True,
|
|
251
|
-
context=context,
|
|
252
|
-
details=details,
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
def log_info(
|
|
256
|
-
self,
|
|
257
|
-
event_type: SDKEventType,
|
|
258
|
-
message: str,
|
|
259
|
-
context: Optional[SDKContext] = None,
|
|
260
|
-
details: Optional[Any] = None,
|
|
261
|
-
success: bool = True,
|
|
262
|
-
duration_ms: Optional[float] = None,
|
|
263
|
-
) -> None:
|
|
264
|
-
"""Log info-level event."""
|
|
265
|
-
self._log_event(
|
|
266
|
-
event_type=event_type,
|
|
267
|
-
message=message,
|
|
268
|
-
severity=SDKSeverity.INFO,
|
|
269
|
-
success=success,
|
|
270
|
-
context=context,
|
|
271
|
-
details=details,
|
|
272
|
-
duration_ms=duration_ms,
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
def log_warning(
|
|
276
|
-
self,
|
|
277
|
-
event_type: SDKEventType,
|
|
278
|
-
message: str,
|
|
279
|
-
context: Optional[SDKContext] = None,
|
|
280
|
-
details: Optional[Any] = None,
|
|
281
|
-
error_message: Optional[str] = None,
|
|
282
|
-
) -> None:
|
|
283
|
-
"""Log warning-level event."""
|
|
284
|
-
self._log_event(
|
|
285
|
-
event_type=event_type,
|
|
286
|
-
message=message,
|
|
287
|
-
severity=SDKSeverity.WARNING,
|
|
288
|
-
success=False,
|
|
289
|
-
context=context,
|
|
290
|
-
details=details,
|
|
291
|
-
error_message=error_message,
|
|
292
|
-
)
|
|
293
|
-
self._warnings_count += 1
|
|
294
|
-
|
|
295
|
-
def log_error(
|
|
296
|
-
self,
|
|
297
|
-
event_type: SDKEventType,
|
|
298
|
-
message: str,
|
|
299
|
-
context: Optional[SDKContext] = None,
|
|
300
|
-
details: Optional[Any] = None,
|
|
301
|
-
error_code: Optional[str] = None,
|
|
302
|
-
error_message: Optional[str] = None,
|
|
303
|
-
exception: Optional[Exception] = None,
|
|
304
|
-
) -> None:
|
|
305
|
-
"""Log error-level event."""
|
|
306
|
-
# Include exception details if provided
|
|
307
|
-
if exception:
|
|
308
|
-
error_details = {
|
|
309
|
-
**(details or {}),
|
|
310
|
-
"exception_type": type(exception).__name__,
|
|
311
|
-
"exception_str": str(exception),
|
|
312
|
-
"stack_trace": traceback.format_exc(),
|
|
313
|
-
}
|
|
314
|
-
else:
|
|
315
|
-
error_details = details
|
|
316
|
-
|
|
317
|
-
self._log_event(
|
|
318
|
-
event_type=event_type,
|
|
319
|
-
message=message,
|
|
320
|
-
severity=SDKSeverity.ERROR,
|
|
321
|
-
success=False,
|
|
322
|
-
context=context,
|
|
323
|
-
details=error_details,
|
|
324
|
-
error_code=error_code,
|
|
325
|
-
error_message=error_message,
|
|
326
|
-
)
|
|
327
|
-
self._errors_count += 1
|
|
328
|
-
|
|
329
|
-
def log_critical(
|
|
330
|
-
self,
|
|
331
|
-
event_type: SDKEventType,
|
|
332
|
-
message: str,
|
|
333
|
-
context: Optional[SDKContext] = None,
|
|
334
|
-
details: Optional[Any] = None,
|
|
335
|
-
error_code: Optional[str] = None,
|
|
336
|
-
error_message: Optional[str] = None,
|
|
337
|
-
exception: Optional[Exception] = None,
|
|
338
|
-
) -> None:
|
|
339
|
-
"""Log critical-level event."""
|
|
340
|
-
# Include exception details if provided
|
|
341
|
-
if exception:
|
|
342
|
-
error_details = {
|
|
343
|
-
**(details or {}),
|
|
344
|
-
"exception_type": type(exception).__name__,
|
|
345
|
-
"exception_str": str(exception),
|
|
346
|
-
"stack_trace": traceback.format_exc(),
|
|
347
|
-
}
|
|
348
|
-
else:
|
|
349
|
-
error_details = details
|
|
350
|
-
|
|
351
|
-
self._log_event(
|
|
352
|
-
event_type=event_type,
|
|
353
|
-
message=message,
|
|
354
|
-
severity=SDKSeverity.CRITICAL,
|
|
355
|
-
success=False,
|
|
356
|
-
context=context,
|
|
357
|
-
details=error_details,
|
|
358
|
-
error_code=error_code,
|
|
359
|
-
error_message=error_message,
|
|
360
|
-
)
|
|
361
|
-
self._errors_count += 1
|
|
362
|
-
|
|
363
|
-
# Specialized Logging Methods
|
|
364
|
-
def log_performance_metric(
|
|
365
|
-
self,
|
|
366
|
-
metric_name: str,
|
|
367
|
-
value: float,
|
|
368
|
-
unit: str,
|
|
369
|
-
threshold: Optional[float] = None,
|
|
370
|
-
context: Optional[SDKContext] = None,
|
|
371
|
-
) -> None:
|
|
372
|
-
"""Log performance metric."""
|
|
373
|
-
exceeded = threshold is not None and value > threshold
|
|
374
|
-
|
|
375
|
-
details = {
|
|
376
|
-
"metric_name": metric_name,
|
|
377
|
-
"value": value,
|
|
378
|
-
"unit": unit,
|
|
379
|
-
"threshold": threshold,
|
|
380
|
-
"threshold_exceeded": exceeded,
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
severity = SDKSeverity.WARNING if exceeded else SDKSeverity.DEBUG
|
|
384
|
-
event_type = (
|
|
385
|
-
SDKEventType.PERFORMANCE_THRESHOLD_EXCEEDED
|
|
386
|
-
if exceeded
|
|
387
|
-
else SDKEventType.PERFORMANCE_METRIC_COLLECTED
|
|
388
|
-
)
|
|
389
|
-
|
|
390
|
-
self._log_event(
|
|
391
|
-
event_type=event_type,
|
|
392
|
-
message=f"Performance metric {metric_name}: {value} {unit}",
|
|
393
|
-
severity=severity,
|
|
394
|
-
success=not exceeded,
|
|
395
|
-
context=context,
|
|
396
|
-
details=details,
|
|
397
|
-
)
|
|
398
|
-
|
|
399
|
-
def log_api_call(
|
|
400
|
-
self,
|
|
401
|
-
method: str,
|
|
402
|
-
url: str,
|
|
403
|
-
status_code: Optional[int] = None,
|
|
404
|
-
duration_ms: Optional[float] = None,
|
|
405
|
-
success: bool = True,
|
|
406
|
-
error_message: Optional[str] = None,
|
|
407
|
-
) -> None:
|
|
408
|
-
"""Log API call event."""
|
|
409
|
-
details = {
|
|
410
|
-
"method": method,
|
|
411
|
-
"url": url,
|
|
412
|
-
"status_code": status_code,
|
|
413
|
-
"duration_ms": duration_ms,
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
event_type = SDKEventType.API_CALL_COMPLETED if success else SDKEventType.API_CALL_FAILED
|
|
417
|
-
severity = SDKSeverity.DEBUG if success else SDKSeverity.ERROR
|
|
418
|
-
|
|
419
|
-
self._log_event(
|
|
420
|
-
event_type=event_type,
|
|
421
|
-
message=f"{method} {url} - {status_code or 'No Response'}",
|
|
422
|
-
severity=severity,
|
|
423
|
-
success=success,
|
|
424
|
-
details=details,
|
|
425
|
-
error_message=error_message,
|
|
426
|
-
duration_ms=duration_ms,
|
|
427
|
-
)
|
|
428
|
-
|
|
429
|
-
def log_layer_validation(
|
|
430
|
-
self,
|
|
431
|
-
layer_name: str,
|
|
432
|
-
checklist_items: List[str],
|
|
433
|
-
passed_items: List[str],
|
|
434
|
-
failed_items: List[str],
|
|
435
|
-
) -> None:
|
|
436
|
-
"""Log layer validation results (Skyscraper Architecture)."""
|
|
437
|
-
success = len(failed_items) == 0
|
|
438
|
-
|
|
439
|
-
details = {
|
|
440
|
-
"layer_name": layer_name,
|
|
441
|
-
"total_items": len(checklist_items),
|
|
442
|
-
"passed_items": len(passed_items),
|
|
443
|
-
"failed_items": len(failed_items),
|
|
444
|
-
"passed_list": passed_items,
|
|
445
|
-
"failed_list": failed_items,
|
|
446
|
-
"success_rate": len(passed_items) / len(checklist_items) * 100,
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
event_type = SDKEventType.LAYER_COMPLETED if success else SDKEventType.LAYER_FAILED
|
|
450
|
-
severity = SDKSeverity.INFO if success else SDKSeverity.ERROR
|
|
451
|
-
|
|
452
|
-
self._log_event(
|
|
453
|
-
event_type=event_type,
|
|
454
|
-
message=f"Layer {layer_name} validation: {len(passed_items)}/{len(checklist_items)} items passed",
|
|
455
|
-
severity=severity,
|
|
456
|
-
success=success,
|
|
457
|
-
context=SDKContext(layer_name=layer_name),
|
|
458
|
-
details=details,
|
|
459
|
-
)
|
|
460
|
-
|
|
461
|
-
# Internal Methods
|
|
462
|
-
def _log_event(
|
|
463
|
-
self,
|
|
464
|
-
event_type: SDKEventType,
|
|
465
|
-
message: str,
|
|
466
|
-
severity: SDKSeverity,
|
|
467
|
-
success: bool = True,
|
|
468
|
-
context: Optional[SDKContext] = None,
|
|
469
|
-
details: Optional[Any] = None,
|
|
470
|
-
error_code: Optional[str] = None,
|
|
471
|
-
error_message: Optional[str] = None,
|
|
472
|
-
duration_ms: Optional[float] = None,
|
|
473
|
-
) -> None:
|
|
474
|
-
"""Internal method to log structured development event."""
|
|
475
|
-
try:
|
|
476
|
-
# Skip if below log level
|
|
477
|
-
if not self._should_log(severity):
|
|
478
|
-
return
|
|
479
|
-
|
|
480
|
-
# Enhance context with current state
|
|
481
|
-
enhanced_context = context or SDKContext()
|
|
482
|
-
if not enhanced_context.layer_name:
|
|
483
|
-
enhanced_context.layer_name = self._current_layer
|
|
484
|
-
if not enhanced_context.component_name:
|
|
485
|
-
enhanced_context.component_name = self._current_component
|
|
486
|
-
if not enhanced_context.thread_id:
|
|
487
|
-
enhanced_context.thread_id = str(threading.get_ident())
|
|
488
|
-
if not enhanced_context.correlation_id:
|
|
489
|
-
enhanced_context.correlation_id = generate_correlation_id()
|
|
490
|
-
|
|
491
|
-
# Create event
|
|
492
|
-
event = SDKDevelopmentEvent(
|
|
493
|
-
event_type=event_type,
|
|
494
|
-
severity=severity,
|
|
495
|
-
message=message,
|
|
496
|
-
success=success,
|
|
497
|
-
context=enhanced_context,
|
|
498
|
-
details=details or {},
|
|
499
|
-
error_code=error_code,
|
|
500
|
-
error_message=error_message,
|
|
501
|
-
duration_ms=duration_ms,
|
|
502
|
-
)
|
|
503
|
-
|
|
504
|
-
# Update statistics
|
|
505
|
-
self._events_logged += 1
|
|
506
|
-
self._events_by_severity[severity] += 1
|
|
507
|
-
self._events_by_type[event_type] = self._events_by_type.get(event_type, 0) + 1
|
|
508
|
-
|
|
509
|
-
# Console logging
|
|
510
|
-
if self.enable_console:
|
|
511
|
-
self._log_to_console(event)
|
|
512
|
-
|
|
513
|
-
# Buffer for WebSocket streaming
|
|
514
|
-
if self.enable_websocket:
|
|
515
|
-
with self._buffer_lock:
|
|
516
|
-
self._buffer.append(event)
|
|
517
|
-
|
|
518
|
-
# Auto-flush if buffer is full
|
|
519
|
-
if len(self._buffer) >= self._buffer_size:
|
|
520
|
-
try:
|
|
521
|
-
loop = asyncio.get_running_loop()
|
|
522
|
-
loop.create_task(self._flush_buffer())
|
|
523
|
-
except RuntimeError:
|
|
524
|
-
# No event loop running, skip async flush
|
|
525
|
-
pass
|
|
526
|
-
|
|
527
|
-
except Exception as e:
|
|
528
|
-
# Never let logging break the application
|
|
529
|
-
if self.enable_console:
|
|
530
|
-
print(f"DevelopmentLogger error: {e}", file=sys.stderr)
|
|
531
|
-
|
|
532
|
-
def _should_log(self, severity: SDKSeverity) -> bool:
|
|
533
|
-
"""Check if event should be logged based on level."""
|
|
534
|
-
severity_order = {
|
|
535
|
-
SDKSeverity.TRACE: 0,
|
|
536
|
-
SDKSeverity.DEBUG: 1,
|
|
537
|
-
SDKSeverity.INFO: 2,
|
|
538
|
-
SDKSeverity.WARNING: 3,
|
|
539
|
-
SDKSeverity.ERROR: 4,
|
|
540
|
-
SDKSeverity.CRITICAL: 5,
|
|
541
|
-
SDKSeverity.FATAL: 6,
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
return severity_order.get(severity, 2) >= severity_order.get(self.log_level, 2)
|
|
545
|
-
|
|
546
|
-
def _log_to_console(self, event: SDKDevelopmentEvent) -> None:
|
|
547
|
-
"""Log event to console with structured formatting."""
|
|
548
|
-
try:
|
|
549
|
-
# Format message with context
|
|
550
|
-
context_info = []
|
|
551
|
-
if event.context.layer_name:
|
|
552
|
-
context_info.append(f"Layer:{event.context.layer_name}")
|
|
553
|
-
if event.context.component_name:
|
|
554
|
-
context_info.append(f"Component:{event.context.component_name}")
|
|
555
|
-
if event.duration_ms:
|
|
556
|
-
context_info.append(f"{event.duration_ms:.2f}ms")
|
|
557
|
-
|
|
558
|
-
context_str = f" [{', '.join(context_info)}]" if context_info else ""
|
|
559
|
-
formatted_message = f"{event.event_type.value.upper()}: {event.message}{context_str}"
|
|
560
|
-
|
|
561
|
-
# Add error details
|
|
562
|
-
if not event.success and event.error_message:
|
|
563
|
-
formatted_message += f" | Error: {event.error_message}"
|
|
564
|
-
|
|
565
|
-
# Log at appropriate level
|
|
566
|
-
log_level = self._severity_to_logging_level(event.severity)
|
|
567
|
-
self.console_logger.log(log_level, formatted_message)
|
|
568
|
-
|
|
569
|
-
except Exception as e:
|
|
570
|
-
print(f"Console logging error: {e}", file=sys.stderr)
|
|
571
|
-
|
|
572
|
-
def _severity_to_logging_level(self, severity: SDKSeverity) -> int:
|
|
573
|
-
"""Convert SDK severity to Python logging level."""
|
|
574
|
-
mapping = {
|
|
575
|
-
SDKSeverity.TRACE: logging.DEBUG,
|
|
576
|
-
SDKSeverity.DEBUG: logging.DEBUG,
|
|
577
|
-
SDKSeverity.INFO: logging.INFO,
|
|
578
|
-
SDKSeverity.WARNING: logging.WARNING,
|
|
579
|
-
SDKSeverity.ERROR: logging.ERROR,
|
|
580
|
-
SDKSeverity.CRITICAL: logging.CRITICAL,
|
|
581
|
-
SDKSeverity.FATAL: logging.CRITICAL,
|
|
582
|
-
}
|
|
583
|
-
return mapping.get(severity, logging.INFO)
|
|
584
|
-
|
|
585
|
-
async def _auto_flush_loop(self) -> None:
|
|
586
|
-
"""Background task for auto-flushing buffer."""
|
|
587
|
-
while not self._shutdown:
|
|
588
|
-
try:
|
|
589
|
-
await asyncio.sleep(self._flush_interval)
|
|
590
|
-
await self._flush_buffer()
|
|
591
|
-
except asyncio.CancelledError:
|
|
592
|
-
break
|
|
593
|
-
except Exception as e:
|
|
594
|
-
if self.enable_console:
|
|
595
|
-
print(f"Auto-flush error: {e}", file=sys.stderr)
|
|
596
|
-
|
|
597
|
-
async def _flush_buffer(self) -> None:
|
|
598
|
-
"""Flush buffer to WebSocket."""
|
|
599
|
-
if not self._websocket_client or not self.enable_websocket:
|
|
600
|
-
return
|
|
601
|
-
|
|
602
|
-
events_to_flush = []
|
|
603
|
-
with self._buffer_lock:
|
|
604
|
-
if self._buffer:
|
|
605
|
-
events_to_flush = self._buffer.copy()
|
|
606
|
-
self._buffer.clear()
|
|
607
|
-
|
|
608
|
-
if not events_to_flush:
|
|
609
|
-
return
|
|
610
|
-
|
|
611
|
-
try:
|
|
612
|
-
# Send WebSocket events with timeout to prevent blocking
|
|
613
|
-
send_tasks = []
|
|
614
|
-
for event in events_to_flush:
|
|
615
|
-
ws_message = event.to_websocket_message(self.session_id)
|
|
616
|
-
task = asyncio.create_task(self._websocket_client.send_log(ws_message))
|
|
617
|
-
send_tasks.append(task)
|
|
618
|
-
|
|
619
|
-
# Wait for all sends with timeout to prevent blocking
|
|
620
|
-
if send_tasks:
|
|
621
|
-
await asyncio.wait_for(
|
|
622
|
-
asyncio.gather(*send_tasks, return_exceptions=True),
|
|
623
|
-
timeout=2.0 # 2 second timeout for all sends
|
|
624
|
-
)
|
|
625
|
-
|
|
626
|
-
if self.enable_console and len(events_to_flush) > 1:
|
|
627
|
-
self.console_logger.debug(f"Flushed {len(events_to_flush)} events to WebSocket")
|
|
628
|
-
|
|
629
|
-
except asyncio.TimeoutError:
|
|
630
|
-
if self.enable_console:
|
|
631
|
-
self.console_logger.warning(f"WebSocket flush timeout - sent {len(events_to_flush)} events")
|
|
632
|
-
except Exception as e:
|
|
633
|
-
if self.enable_console:
|
|
634
|
-
self.console_logger.error(f"Failed to flush events to WebSocket: {e}")
|
|
635
|
-
|
|
636
|
-
# Statistics and Monitoring
|
|
637
|
-
def get_statistics(self) -> DevelopmentLoggerStatistics:
|
|
638
|
-
"""Get development logger statistics."""
|
|
639
|
-
return DevelopmentLoggerStatistics(
|
|
640
|
-
total_events=self._events_logged,
|
|
641
|
-
events_by_type=dict(self._events_by_type),
|
|
642
|
-
events_by_severity=dict(self._events_by_severity),
|
|
643
|
-
buffer_size=len(self._buffer),
|
|
644
|
-
websocket_connected=self.enable_websocket and self.websocket_client is not None,
|
|
645
|
-
startup_time=getattr(self, "_startup_time", datetime.now(timezone.utc)),
|
|
646
|
-
)
|
|
647
|
-
|
|
648
|
-
def get_active_operations(self) -> Dict[str, float]:
|
|
649
|
-
"""Get currently active operations with durations."""
|
|
650
|
-
now = datetime.now(timezone.utc)
|
|
651
|
-
return {
|
|
652
|
-
op_id: (now - start_time).total_seconds()
|
|
653
|
-
for op_id, start_time in self._active_operations.items()
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
# Global development logger instance
|
|
658
|
-
_dev_logger: Optional[DevelopmentLogger] = None
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
def initialize_development_logger(
|
|
662
|
-
session_id: Optional[str] = None,
|
|
663
|
-
log_level: SDKSeverity = SDKSeverity.INFO,
|
|
664
|
-
enable_console: bool = True,
|
|
665
|
-
enable_websocket: bool = True,
|
|
666
|
-
) -> DevelopmentLogger:
|
|
667
|
-
"""Initialize global development logger."""
|
|
668
|
-
global _dev_logger
|
|
669
|
-
_dev_logger = DevelopmentLogger(
|
|
670
|
-
session_id=session_id,
|
|
671
|
-
log_level=log_level,
|
|
672
|
-
enable_console=enable_console,
|
|
673
|
-
enable_websocket=enable_websocket,
|
|
674
|
-
)
|
|
675
|
-
return _dev_logger
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
def get_development_logger() -> Optional[DevelopmentLogger]:
|
|
679
|
-
"""Get global development logger instance."""
|
|
680
|
-
return _dev_logger
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
# Convenience decorator for automatic operation tracking
|
|
684
|
-
def track_development_operation(
|
|
685
|
-
operation_name: str, event_type: SDKEventType = SDKEventType.DEBUG_CHECKPOINT
|
|
686
|
-
):
|
|
687
|
-
"""Decorator to automatically track development operations."""
|
|
688
|
-
|
|
689
|
-
def decorator(func):
|
|
690
|
-
async def async_wrapper(*args, **kwargs):
|
|
691
|
-
dev_logger = get_development_logger()
|
|
692
|
-
if not dev_logger:
|
|
693
|
-
return await func(*args, **kwargs)
|
|
694
|
-
|
|
695
|
-
operation_id = generate_correlation_id()
|
|
696
|
-
dev_logger.start_operation(operation_id, f"{operation_name}: {func.__name__}")
|
|
697
|
-
|
|
698
|
-
try:
|
|
699
|
-
result = await func(*args, **kwargs)
|
|
700
|
-
dev_logger.complete_operation(
|
|
701
|
-
operation_id, f"{operation_name}: {func.__name__}", success=True
|
|
702
|
-
)
|
|
703
|
-
return result
|
|
704
|
-
except Exception as e:
|
|
705
|
-
dev_logger.complete_operation(
|
|
706
|
-
operation_id, f"{operation_name}: {func.__name__}", success=False
|
|
707
|
-
)
|
|
708
|
-
dev_logger.log_error(
|
|
709
|
-
event_type,
|
|
710
|
-
f"Operation failed: {operation_name}",
|
|
711
|
-
exception=e,
|
|
712
|
-
context=SDKContext(method_name=func.__name__),
|
|
713
|
-
)
|
|
714
|
-
raise
|
|
715
|
-
|
|
716
|
-
def sync_wrapper(*args, **kwargs):
|
|
717
|
-
dev_logger = get_development_logger()
|
|
718
|
-
if not dev_logger:
|
|
719
|
-
return func(*args, **kwargs)
|
|
720
|
-
|
|
721
|
-
operation_id = generate_correlation_id()
|
|
722
|
-
dev_logger.start_operation(operation_id, f"{operation_name}: {func.__name__}")
|
|
723
|
-
|
|
724
|
-
try:
|
|
725
|
-
result = func(*args, **kwargs)
|
|
726
|
-
dev_logger.complete_operation(
|
|
727
|
-
operation_id, f"{operation_name}: {func.__name__}", success=True
|
|
728
|
-
)
|
|
729
|
-
return result
|
|
730
|
-
except Exception as e:
|
|
731
|
-
dev_logger.complete_operation(
|
|
732
|
-
operation_id, f"{operation_name}: {func.__name__}", success=False
|
|
733
|
-
)
|
|
734
|
-
dev_logger.log_error(
|
|
735
|
-
event_type,
|
|
736
|
-
f"Operation failed: {operation_name}",
|
|
737
|
-
exception=e,
|
|
738
|
-
context=SDKContext(method_name=func.__name__),
|
|
739
|
-
)
|
|
740
|
-
raise
|
|
741
|
-
|
|
742
|
-
return async_wrapper if asyncio.iscoroutinefunction(func) else sync_wrapper
|
|
743
|
-
|
|
744
|
-
return decorator
|