omnibase_infra 0.2.6__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.
- omnibase_infra/__init__.py +101 -0
- omnibase_infra/adapters/adapter_onex_tool_execution.py +451 -0
- omnibase_infra/capabilities/__init__.py +15 -0
- omnibase_infra/capabilities/capability_inference_rules.py +211 -0
- omnibase_infra/capabilities/contract_capability_extractor.py +221 -0
- omnibase_infra/capabilities/intent_type_extractor.py +160 -0
- omnibase_infra/cli/__init__.py +1 -0
- omnibase_infra/cli/commands.py +216 -0
- omnibase_infra/clients/__init__.py +0 -0
- omnibase_infra/configs/widget_mapping.yaml +176 -0
- omnibase_infra/constants_topic_patterns.py +26 -0
- omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +264 -0
- omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +141 -0
- omnibase_infra/decorators/__init__.py +29 -0
- omnibase_infra/decorators/allow_any.py +109 -0
- omnibase_infra/dlq/__init__.py +90 -0
- omnibase_infra/dlq/constants_dlq.py +57 -0
- omnibase_infra/dlq/models/__init__.py +26 -0
- omnibase_infra/dlq/models/enum_replay_status.py +37 -0
- omnibase_infra/dlq/models/model_dlq_replay_record.py +135 -0
- omnibase_infra/dlq/models/model_dlq_tracking_config.py +184 -0
- omnibase_infra/dlq/service_dlq_tracking.py +611 -0
- omnibase_infra/enums/__init__.py +132 -0
- omnibase_infra/enums/enum_any_type_violation.py +104 -0
- omnibase_infra/enums/enum_backend_type.py +27 -0
- omnibase_infra/enums/enum_capture_outcome.py +42 -0
- omnibase_infra/enums/enum_capture_state.py +88 -0
- omnibase_infra/enums/enum_chain_violation_type.py +119 -0
- omnibase_infra/enums/enum_circuit_state.py +51 -0
- omnibase_infra/enums/enum_confirmation_event_type.py +27 -0
- omnibase_infra/enums/enum_consumer_group_purpose.py +92 -0
- omnibase_infra/enums/enum_contract_type.py +84 -0
- omnibase_infra/enums/enum_dedupe_strategy.py +46 -0
- omnibase_infra/enums/enum_dispatch_status.py +191 -0
- omnibase_infra/enums/enum_environment.py +46 -0
- omnibase_infra/enums/enum_execution_shape_violation.py +103 -0
- omnibase_infra/enums/enum_handler_error_type.py +111 -0
- omnibase_infra/enums/enum_handler_loader_error.py +178 -0
- omnibase_infra/enums/enum_handler_source_mode.py +86 -0
- omnibase_infra/enums/enum_handler_source_type.py +87 -0
- omnibase_infra/enums/enum_handler_type.py +77 -0
- omnibase_infra/enums/enum_handler_type_category.py +61 -0
- omnibase_infra/enums/enum_infra_transport_type.py +73 -0
- omnibase_infra/enums/enum_introspection_reason.py +154 -0
- omnibase_infra/enums/enum_kafka_acks.py +99 -0
- omnibase_infra/enums/enum_message_category.py +213 -0
- omnibase_infra/enums/enum_node_archetype.py +74 -0
- omnibase_infra/enums/enum_node_output_type.py +185 -0
- omnibase_infra/enums/enum_non_retryable_error_category.py +224 -0
- omnibase_infra/enums/enum_policy_type.py +32 -0
- omnibase_infra/enums/enum_registration_state.py +261 -0
- omnibase_infra/enums/enum_registration_status.py +33 -0
- omnibase_infra/enums/enum_registry_response_status.py +28 -0
- omnibase_infra/enums/enum_response_status.py +26 -0
- omnibase_infra/enums/enum_retry_error_category.py +98 -0
- omnibase_infra/enums/enum_security_rule_id.py +103 -0
- omnibase_infra/enums/enum_selection_strategy.py +91 -0
- omnibase_infra/enums/enum_topic_standard.py +42 -0
- omnibase_infra/enums/enum_validation_severity.py +78 -0
- omnibase_infra/errors/__init__.py +160 -0
- omnibase_infra/errors/error_architecture_violation.py +152 -0
- omnibase_infra/errors/error_binding_resolution.py +128 -0
- omnibase_infra/errors/error_chain_propagation.py +188 -0
- omnibase_infra/errors/error_compute_registry.py +95 -0
- omnibase_infra/errors/error_consul.py +132 -0
- omnibase_infra/errors/error_container_wiring.py +243 -0
- omnibase_infra/errors/error_event_bus_registry.py +105 -0
- omnibase_infra/errors/error_infra.py +610 -0
- omnibase_infra/errors/error_message_type_registry.py +101 -0
- omnibase_infra/errors/error_policy_registry.py +115 -0
- omnibase_infra/errors/error_vault.py +123 -0
- omnibase_infra/event_bus/__init__.py +72 -0
- omnibase_infra/event_bus/configs/kafka_event_bus_config.yaml +84 -0
- omnibase_infra/event_bus/event_bus_inmemory.py +797 -0
- omnibase_infra/event_bus/event_bus_kafka.py +1716 -0
- omnibase_infra/event_bus/mixin_kafka_broadcast.py +180 -0
- omnibase_infra/event_bus/mixin_kafka_dlq.py +771 -0
- omnibase_infra/event_bus/models/__init__.py +29 -0
- omnibase_infra/event_bus/models/config/__init__.py +20 -0
- omnibase_infra/event_bus/models/config/model_kafka_event_bus_config.py +693 -0
- omnibase_infra/event_bus/models/model_dlq_event.py +206 -0
- omnibase_infra/event_bus/models/model_dlq_metrics.py +304 -0
- omnibase_infra/event_bus/models/model_event_headers.py +115 -0
- omnibase_infra/event_bus/models/model_event_message.py +60 -0
- omnibase_infra/event_bus/testing/__init__.py +26 -0
- omnibase_infra/event_bus/testing/adapter_protocol_event_publisher_inmemory.py +418 -0
- omnibase_infra/event_bus/testing/model_publisher_metrics.py +64 -0
- omnibase_infra/event_bus/topic_constants.py +376 -0
- omnibase_infra/handlers/__init__.py +82 -0
- omnibase_infra/handlers/filesystem/__init__.py +48 -0
- omnibase_infra/handlers/filesystem/enum_file_system_operation.py +35 -0
- omnibase_infra/handlers/filesystem/model_file_system_request.py +298 -0
- omnibase_infra/handlers/filesystem/model_file_system_result.py +166 -0
- omnibase_infra/handlers/handler_consul.py +795 -0
- omnibase_infra/handlers/handler_db.py +1046 -0
- omnibase_infra/handlers/handler_filesystem.py +1478 -0
- omnibase_infra/handlers/handler_graph.py +2015 -0
- omnibase_infra/handlers/handler_http.py +926 -0
- omnibase_infra/handlers/handler_intent.py +387 -0
- omnibase_infra/handlers/handler_manifest_persistence.contract.yaml +184 -0
- omnibase_infra/handlers/handler_manifest_persistence.py +1539 -0
- omnibase_infra/handlers/handler_mcp.py +1430 -0
- omnibase_infra/handlers/handler_qdrant.py +1076 -0
- omnibase_infra/handlers/handler_vault.py +428 -0
- omnibase_infra/handlers/mcp/__init__.py +19 -0
- omnibase_infra/handlers/mcp/adapter_onex_to_mcp.py +446 -0
- omnibase_infra/handlers/mcp/protocols.py +178 -0
- omnibase_infra/handlers/mcp/transport_streamable_http.py +352 -0
- omnibase_infra/handlers/mixins/__init__.py +47 -0
- omnibase_infra/handlers/mixins/mixin_consul_initialization.py +349 -0
- omnibase_infra/handlers/mixins/mixin_consul_kv.py +338 -0
- omnibase_infra/handlers/mixins/mixin_consul_service.py +542 -0
- omnibase_infra/handlers/mixins/mixin_consul_topic_index.py +585 -0
- omnibase_infra/handlers/mixins/mixin_vault_initialization.py +338 -0
- omnibase_infra/handlers/mixins/mixin_vault_retry.py +412 -0
- omnibase_infra/handlers/mixins/mixin_vault_secrets.py +450 -0
- omnibase_infra/handlers/mixins/mixin_vault_token.py +365 -0
- omnibase_infra/handlers/models/__init__.py +286 -0
- omnibase_infra/handlers/models/consul/__init__.py +81 -0
- omnibase_infra/handlers/models/consul/enum_consul_operation_type.py +57 -0
- omnibase_infra/handlers/models/consul/model_consul_deregister_payload.py +51 -0
- omnibase_infra/handlers/models/consul/model_consul_handler_config.py +153 -0
- omnibase_infra/handlers/models/consul/model_consul_handler_payload.py +89 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_found_payload.py +55 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_not_found_payload.py +49 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_recurse_payload.py +50 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_item.py +33 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_put_payload.py +41 -0
- omnibase_infra/handlers/models/consul/model_consul_register_payload.py +53 -0
- omnibase_infra/handlers/models/consul/model_consul_retry_config.py +66 -0
- omnibase_infra/handlers/models/consul/model_payload_consul.py +66 -0
- omnibase_infra/handlers/models/consul/registry_payload_consul.py +214 -0
- omnibase_infra/handlers/models/graph/__init__.py +35 -0
- omnibase_infra/handlers/models/graph/enum_graph_operation_type.py +20 -0
- omnibase_infra/handlers/models/graph/model_graph_execute_payload.py +38 -0
- omnibase_infra/handlers/models/graph/model_graph_handler_config.py +54 -0
- omnibase_infra/handlers/models/graph/model_graph_handler_payload.py +44 -0
- omnibase_infra/handlers/models/graph/model_graph_query_payload.py +40 -0
- omnibase_infra/handlers/models/graph/model_graph_record.py +22 -0
- omnibase_infra/handlers/models/http/__init__.py +50 -0
- omnibase_infra/handlers/models/http/enum_http_operation_type.py +29 -0
- omnibase_infra/handlers/models/http/model_http_body_content.py +45 -0
- omnibase_infra/handlers/models/http/model_http_get_payload.py +88 -0
- omnibase_infra/handlers/models/http/model_http_handler_payload.py +90 -0
- omnibase_infra/handlers/models/http/model_http_post_payload.py +88 -0
- omnibase_infra/handlers/models/http/model_payload_http.py +66 -0
- omnibase_infra/handlers/models/http/registry_payload_http.py +212 -0
- omnibase_infra/handlers/models/mcp/__init__.py +23 -0
- omnibase_infra/handlers/models/mcp/enum_mcp_operation_type.py +24 -0
- omnibase_infra/handlers/models/mcp/model_mcp_handler_config.py +40 -0
- omnibase_infra/handlers/models/mcp/model_mcp_tool_call.py +32 -0
- omnibase_infra/handlers/models/mcp/model_mcp_tool_result.py +45 -0
- omnibase_infra/handlers/models/model_consul_handler_response.py +96 -0
- omnibase_infra/handlers/models/model_db_describe_response.py +83 -0
- omnibase_infra/handlers/models/model_db_query_payload.py +95 -0
- omnibase_infra/handlers/models/model_db_query_response.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_config.py +98 -0
- omnibase_infra/handlers/models/model_filesystem_delete_payload.py +54 -0
- omnibase_infra/handlers/models/model_filesystem_delete_result.py +77 -0
- omnibase_infra/handlers/models/model_filesystem_directory_entry.py +75 -0
- omnibase_infra/handlers/models/model_filesystem_ensure_directory_payload.py +54 -0
- omnibase_infra/handlers/models/model_filesystem_ensure_directory_result.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_list_directory_payload.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_list_directory_result.py +68 -0
- omnibase_infra/handlers/models/model_filesystem_read_payload.py +62 -0
- omnibase_infra/handlers/models/model_filesystem_read_result.py +61 -0
- omnibase_infra/handlers/models/model_filesystem_write_payload.py +70 -0
- omnibase_infra/handlers/models/model_filesystem_write_result.py +55 -0
- omnibase_infra/handlers/models/model_graph_handler_response.py +98 -0
- omnibase_infra/handlers/models/model_handler_response.py +103 -0
- omnibase_infra/handlers/models/model_http_handler_response.py +101 -0
- omnibase_infra/handlers/models/model_manifest_metadata.py +75 -0
- omnibase_infra/handlers/models/model_manifest_persistence_config.py +62 -0
- omnibase_infra/handlers/models/model_manifest_query_payload.py +90 -0
- omnibase_infra/handlers/models/model_manifest_query_result.py +97 -0
- omnibase_infra/handlers/models/model_manifest_retrieve_payload.py +44 -0
- omnibase_infra/handlers/models/model_manifest_retrieve_result.py +98 -0
- omnibase_infra/handlers/models/model_manifest_store_payload.py +47 -0
- omnibase_infra/handlers/models/model_manifest_store_result.py +67 -0
- omnibase_infra/handlers/models/model_operation_context.py +187 -0
- omnibase_infra/handlers/models/model_qdrant_handler_response.py +98 -0
- omnibase_infra/handlers/models/model_retry_state.py +162 -0
- omnibase_infra/handlers/models/model_vault_handler_response.py +98 -0
- omnibase_infra/handlers/models/qdrant/__init__.py +44 -0
- omnibase_infra/handlers/models/qdrant/enum_qdrant_operation_type.py +26 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_collection_payload.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_delete_payload.py +36 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_handler_config.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_handler_payload.py +54 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_search_payload.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_search_result.py +30 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_upsert_payload.py +36 -0
- omnibase_infra/handlers/models/vault/__init__.py +69 -0
- omnibase_infra/handlers/models/vault/enum_vault_operation_type.py +35 -0
- omnibase_infra/handlers/models/vault/model_payload_vault.py +66 -0
- omnibase_infra/handlers/models/vault/model_vault_delete_payload.py +57 -0
- omnibase_infra/handlers/models/vault/model_vault_handler_config.py +148 -0
- omnibase_infra/handlers/models/vault/model_vault_handler_payload.py +101 -0
- omnibase_infra/handlers/models/vault/model_vault_list_payload.py +58 -0
- omnibase_infra/handlers/models/vault/model_vault_renew_token_payload.py +67 -0
- omnibase_infra/handlers/models/vault/model_vault_retry_config.py +66 -0
- omnibase_infra/handlers/models/vault/model_vault_secret_payload.py +106 -0
- omnibase_infra/handlers/models/vault/model_vault_write_payload.py +66 -0
- omnibase_infra/handlers/models/vault/registry_payload_vault.py +213 -0
- omnibase_infra/handlers/registration_storage/__init__.py +43 -0
- omnibase_infra/handlers/registration_storage/handler_registration_storage_mock.py +392 -0
- omnibase_infra/handlers/registration_storage/handler_registration_storage_postgres.py +922 -0
- omnibase_infra/handlers/registration_storage/models/__init__.py +23 -0
- omnibase_infra/handlers/registration_storage/models/model_delete_registration_request.py +58 -0
- omnibase_infra/handlers/registration_storage/models/model_update_registration_request.py +73 -0
- omnibase_infra/handlers/registration_storage/protocol_registration_persistence.py +191 -0
- omnibase_infra/handlers/service_discovery/__init__.py +43 -0
- omnibase_infra/handlers/service_discovery/handler_service_discovery_consul.py +1051 -0
- omnibase_infra/handlers/service_discovery/handler_service_discovery_mock.py +258 -0
- omnibase_infra/handlers/service_discovery/models/__init__.py +22 -0
- omnibase_infra/handlers/service_discovery/models/model_discovery_result.py +64 -0
- omnibase_infra/handlers/service_discovery/models/model_registration_result.py +138 -0
- omnibase_infra/handlers/service_discovery/models/model_service_info.py +109 -0
- omnibase_infra/handlers/service_discovery/protocol_discovery_operations.py +170 -0
- omnibase_infra/idempotency/__init__.py +94 -0
- omnibase_infra/idempotency/models/__init__.py +43 -0
- omnibase_infra/idempotency/models/model_idempotency_check_result.py +85 -0
- omnibase_infra/idempotency/models/model_idempotency_guard_config.py +130 -0
- omnibase_infra/idempotency/models/model_idempotency_record.py +86 -0
- omnibase_infra/idempotency/models/model_idempotency_store_health_check_result.py +81 -0
- omnibase_infra/idempotency/models/model_idempotency_store_metrics.py +140 -0
- omnibase_infra/idempotency/models/model_postgres_idempotency_store_config.py +299 -0
- omnibase_infra/idempotency/protocol_idempotency_store.py +184 -0
- omnibase_infra/idempotency/store_inmemory.py +265 -0
- omnibase_infra/idempotency/store_postgres.py +923 -0
- omnibase_infra/infrastructure/__init__.py +0 -0
- omnibase_infra/migrations/001_create_event_ledger.sql +166 -0
- omnibase_infra/migrations/001_drop_event_ledger.sql +18 -0
- omnibase_infra/mixins/__init__.py +71 -0
- omnibase_infra/mixins/mixin_async_circuit_breaker.py +656 -0
- omnibase_infra/mixins/mixin_dict_like_accessors.py +146 -0
- omnibase_infra/mixins/mixin_envelope_extraction.py +119 -0
- omnibase_infra/mixins/mixin_node_introspection.py +2670 -0
- omnibase_infra/mixins/mixin_retry_execution.py +386 -0
- omnibase_infra/mixins/protocol_circuit_breaker_aware.py +133 -0
- omnibase_infra/models/__init__.py +144 -0
- omnibase_infra/models/bindings/__init__.py +59 -0
- omnibase_infra/models/bindings/constants.py +144 -0
- omnibase_infra/models/bindings/model_binding_resolution_result.py +103 -0
- omnibase_infra/models/bindings/model_operation_binding.py +44 -0
- omnibase_infra/models/bindings/model_operation_bindings_subcontract.py +152 -0
- omnibase_infra/models/bindings/model_parsed_binding.py +52 -0
- omnibase_infra/models/corpus/__init__.py +17 -0
- omnibase_infra/models/corpus/model_capture_config.py +133 -0
- omnibase_infra/models/corpus/model_capture_result.py +86 -0
- omnibase_infra/models/discovery/__init__.py +42 -0
- omnibase_infra/models/discovery/model_dependency_spec.py +319 -0
- omnibase_infra/models/discovery/model_discovered_capabilities.py +50 -0
- omnibase_infra/models/discovery/model_introspection_config.py +330 -0
- omnibase_infra/models/discovery/model_introspection_performance_metrics.py +169 -0
- omnibase_infra/models/discovery/model_introspection_task_config.py +116 -0
- omnibase_infra/models/dispatch/__init__.py +155 -0
- omnibase_infra/models/dispatch/model_debug_trace_snapshot.py +114 -0
- omnibase_infra/models/dispatch/model_dispatch_context.py +439 -0
- omnibase_infra/models/dispatch/model_dispatch_error.py +336 -0
- omnibase_infra/models/dispatch/model_dispatch_log_context.py +400 -0
- omnibase_infra/models/dispatch/model_dispatch_metadata.py +228 -0
- omnibase_infra/models/dispatch/model_dispatch_metrics.py +496 -0
- omnibase_infra/models/dispatch/model_dispatch_outcome.py +317 -0
- omnibase_infra/models/dispatch/model_dispatch_outputs.py +231 -0
- omnibase_infra/models/dispatch/model_dispatch_result.py +436 -0
- omnibase_infra/models/dispatch/model_dispatch_route.py +279 -0
- omnibase_infra/models/dispatch/model_dispatcher_metrics.py +275 -0
- omnibase_infra/models/dispatch/model_dispatcher_registration.py +352 -0
- omnibase_infra/models/dispatch/model_materialized_dispatch.py +141 -0
- omnibase_infra/models/dispatch/model_parsed_topic.py +135 -0
- omnibase_infra/models/dispatch/model_topic_parser.py +725 -0
- omnibase_infra/models/dispatch/model_tracing_context.py +285 -0
- omnibase_infra/models/errors/__init__.py +45 -0
- omnibase_infra/models/errors/model_handler_validation_error.py +594 -0
- omnibase_infra/models/errors/model_infra_error_context.py +99 -0
- omnibase_infra/models/errors/model_message_type_registry_error_context.py +71 -0
- omnibase_infra/models/errors/model_timeout_error_context.py +110 -0
- omnibase_infra/models/handlers/__init__.py +80 -0
- omnibase_infra/models/handlers/model_bootstrap_handler_descriptor.py +162 -0
- omnibase_infra/models/handlers/model_contract_discovery_result.py +82 -0
- omnibase_infra/models/handlers/model_handler_descriptor.py +200 -0
- omnibase_infra/models/handlers/model_handler_identifier.py +215 -0
- omnibase_infra/models/handlers/model_handler_source_config.py +220 -0
- omnibase_infra/models/health/__init__.py +9 -0
- omnibase_infra/models/health/model_health_check_result.py +40 -0
- omnibase_infra/models/lifecycle/__init__.py +39 -0
- omnibase_infra/models/logging/__init__.py +51 -0
- omnibase_infra/models/logging/model_log_context.py +756 -0
- omnibase_infra/models/mcp/__init__.py +15 -0
- omnibase_infra/models/mcp/model_mcp_contract_config.py +80 -0
- omnibase_infra/models/mcp/model_mcp_server_config.py +67 -0
- omnibase_infra/models/mcp/model_mcp_tool_definition.py +73 -0
- omnibase_infra/models/mcp/model_mcp_tool_parameter.py +35 -0
- omnibase_infra/models/model_node_identity.py +126 -0
- omnibase_infra/models/model_retry_error_classification.py +78 -0
- omnibase_infra/models/projection/__init__.py +43 -0
- omnibase_infra/models/projection/model_capability_fields.py +112 -0
- omnibase_infra/models/projection/model_registration_projection.py +434 -0
- omnibase_infra/models/projection/model_registration_snapshot.py +322 -0
- omnibase_infra/models/projection/model_sequence_info.py +182 -0
- omnibase_infra/models/projection/model_snapshot_topic_config.py +591 -0
- omnibase_infra/models/projectors/__init__.py +41 -0
- omnibase_infra/models/projectors/model_projector_column.py +289 -0
- omnibase_infra/models/projectors/model_projector_discovery_result.py +65 -0
- omnibase_infra/models/projectors/model_projector_index.py +270 -0
- omnibase_infra/models/projectors/model_projector_schema.py +415 -0
- omnibase_infra/models/projectors/model_projector_validation_error.py +63 -0
- omnibase_infra/models/projectors/util_sql_identifiers.py +115 -0
- omnibase_infra/models/registration/__init__.py +68 -0
- omnibase_infra/models/registration/commands/__init__.py +15 -0
- omnibase_infra/models/registration/commands/model_node_registration_acked.py +108 -0
- omnibase_infra/models/registration/events/__init__.py +56 -0
- omnibase_infra/models/registration/events/model_node_became_active.py +103 -0
- omnibase_infra/models/registration/events/model_node_liveness_expired.py +103 -0
- omnibase_infra/models/registration/events/model_node_registration_accepted.py +98 -0
- omnibase_infra/models/registration/events/model_node_registration_ack_received.py +98 -0
- omnibase_infra/models/registration/events/model_node_registration_ack_timed_out.py +112 -0
- omnibase_infra/models/registration/events/model_node_registration_initiated.py +107 -0
- omnibase_infra/models/registration/events/model_node_registration_rejected.py +104 -0
- omnibase_infra/models/registration/model_event_bus_topic_entry.py +59 -0
- omnibase_infra/models/registration/model_introspection_metrics.py +253 -0
- omnibase_infra/models/registration/model_node_capabilities.py +190 -0
- omnibase_infra/models/registration/model_node_event_bus_config.py +99 -0
- omnibase_infra/models/registration/model_node_heartbeat_event.py +126 -0
- omnibase_infra/models/registration/model_node_introspection_event.py +195 -0
- omnibase_infra/models/registration/model_node_metadata.py +79 -0
- omnibase_infra/models/registration/model_node_registration.py +162 -0
- omnibase_infra/models/registration/model_node_registration_record.py +162 -0
- omnibase_infra/models/registry/__init__.py +29 -0
- omnibase_infra/models/registry/model_domain_constraint.py +202 -0
- omnibase_infra/models/registry/model_message_type_entry.py +271 -0
- omnibase_infra/models/resilience/__init__.py +9 -0
- omnibase_infra/models/resilience/model_circuit_breaker_config.py +227 -0
- omnibase_infra/models/routing/__init__.py +25 -0
- omnibase_infra/models/routing/model_routing_entry.py +52 -0
- omnibase_infra/models/routing/model_routing_subcontract.py +70 -0
- omnibase_infra/models/runtime/__init__.py +49 -0
- omnibase_infra/models/runtime/model_contract_security_config.py +41 -0
- omnibase_infra/models/runtime/model_discovery_error.py +81 -0
- omnibase_infra/models/runtime/model_discovery_result.py +162 -0
- omnibase_infra/models/runtime/model_discovery_warning.py +74 -0
- omnibase_infra/models/runtime/model_failed_plugin_load.py +63 -0
- omnibase_infra/models/runtime/model_handler_contract.py +296 -0
- omnibase_infra/models/runtime/model_loaded_handler.py +129 -0
- omnibase_infra/models/runtime/model_plugin_load_context.py +93 -0
- omnibase_infra/models/runtime/model_plugin_load_summary.py +124 -0
- omnibase_infra/models/security/__init__.py +50 -0
- omnibase_infra/models/security/classification_levels.py +99 -0
- omnibase_infra/models/security/model_environment_policy.py +145 -0
- omnibase_infra/models/security/model_handler_security_policy.py +107 -0
- omnibase_infra/models/security/model_security_error.py +81 -0
- omnibase_infra/models/security/model_security_validation_result.py +328 -0
- omnibase_infra/models/security/model_security_warning.py +67 -0
- omnibase_infra/models/snapshot/__init__.py +27 -0
- omnibase_infra/models/snapshot/model_field_change.py +65 -0
- omnibase_infra/models/snapshot/model_snapshot.py +270 -0
- omnibase_infra/models/snapshot/model_snapshot_diff.py +203 -0
- omnibase_infra/models/snapshot/model_subject_ref.py +81 -0
- omnibase_infra/models/types/__init__.py +71 -0
- omnibase_infra/models/validation/__init__.py +89 -0
- omnibase_infra/models/validation/model_any_type_validation_result.py +118 -0
- omnibase_infra/models/validation/model_any_type_violation.py +141 -0
- omnibase_infra/models/validation/model_category_match_result.py +345 -0
- omnibase_infra/models/validation/model_chain_violation.py +166 -0
- omnibase_infra/models/validation/model_coverage_metrics.py +316 -0
- omnibase_infra/models/validation/model_execution_shape_rule.py +159 -0
- omnibase_infra/models/validation/model_execution_shape_validation.py +208 -0
- omnibase_infra/models/validation/model_execution_shape_validation_result.py +294 -0
- omnibase_infra/models/validation/model_execution_shape_violation.py +122 -0
- omnibase_infra/models/validation/model_localhandler_validation_result.py +139 -0
- omnibase_infra/models/validation/model_localhandler_violation.py +100 -0
- omnibase_infra/models/validation/model_output_validation_params.py +74 -0
- omnibase_infra/models/validation/model_validate_and_raise_params.py +84 -0
- omnibase_infra/models/validation/model_validation_error_params.py +84 -0
- omnibase_infra/models/validation/model_validation_outcome.py +287 -0
- omnibase_infra/nodes/__init__.py +57 -0
- omnibase_infra/nodes/architecture_validator/__init__.py +79 -0
- omnibase_infra/nodes/architecture_validator/contract.yaml +252 -0
- omnibase_infra/nodes/architecture_validator/contract_architecture_validator.yaml +203 -0
- omnibase_infra/nodes/architecture_validator/mixins/__init__.py +16 -0
- omnibase_infra/nodes/architecture_validator/mixins/mixin_file_path_rule.py +92 -0
- omnibase_infra/nodes/architecture_validator/models/__init__.py +36 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_request.py +56 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_result.py +311 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_violation.py +163 -0
- omnibase_infra/nodes/architecture_validator/models/model_rule_check_result.py +265 -0
- omnibase_infra/nodes/architecture_validator/models/model_validation_request.py +105 -0
- omnibase_infra/nodes/architecture_validator/models/model_validation_result.py +314 -0
- omnibase_infra/nodes/architecture_validator/node.py +262 -0
- omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +383 -0
- omnibase_infra/nodes/architecture_validator/protocols/__init__.py +9 -0
- omnibase_infra/nodes/architecture_validator/protocols/protocol_architecture_rule.py +225 -0
- omnibase_infra/nodes/architecture_validator/registry/__init__.py +28 -0
- omnibase_infra/nodes/architecture_validator/registry/registry_infra_architecture_validator.py +106 -0
- omnibase_infra/nodes/architecture_validator/validators/__init__.py +104 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_direct_dispatch.py +422 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_handler_publishing.py +481 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_orchestrator_fsm.py +491 -0
- omnibase_infra/nodes/contract_registry_reducer/__init__.py +29 -0
- omnibase_infra/nodes/contract_registry_reducer/contract.yaml +255 -0
- omnibase_infra/nodes/contract_registry_reducer/models/__init__.py +38 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_contract_registry_state.py +266 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_cleanup_topic_references.py +55 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_deactivate_contract.py +58 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_mark_stale.py +49 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_heartbeat.py +71 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_topic.py +66 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_upsert_contract.py +92 -0
- omnibase_infra/nodes/contract_registry_reducer/node.py +121 -0
- omnibase_infra/nodes/contract_registry_reducer/reducer.py +784 -0
- omnibase_infra/nodes/contract_registry_reducer/registry/__init__.py +9 -0
- omnibase_infra/nodes/contract_registry_reducer/registry/registry_infra_contract_registry_reducer.py +101 -0
- omnibase_infra/nodes/effects/README.md +358 -0
- omnibase_infra/nodes/effects/__init__.py +26 -0
- omnibase_infra/nodes/effects/contract.yaml +167 -0
- omnibase_infra/nodes/effects/models/__init__.py +32 -0
- omnibase_infra/nodes/effects/models/model_backend_result.py +190 -0
- omnibase_infra/nodes/effects/models/model_effect_idempotency_config.py +92 -0
- omnibase_infra/nodes/effects/models/model_registry_request.py +132 -0
- omnibase_infra/nodes/effects/models/model_registry_response.py +263 -0
- omnibase_infra/nodes/effects/protocol_consul_client.py +89 -0
- omnibase_infra/nodes/effects/protocol_effect_idempotency_store.py +143 -0
- omnibase_infra/nodes/effects/protocol_postgres_adapter.py +96 -0
- omnibase_infra/nodes/effects/registry_effect.py +525 -0
- omnibase_infra/nodes/effects/store_effect_idempotency_inmemory.py +425 -0
- omnibase_infra/nodes/handlers/consul/contract.yaml +85 -0
- omnibase_infra/nodes/handlers/db/contract.yaml +72 -0
- omnibase_infra/nodes/handlers/graph/contract.yaml +127 -0
- omnibase_infra/nodes/handlers/http/contract.yaml +74 -0
- omnibase_infra/nodes/handlers/intent/contract.yaml +66 -0
- omnibase_infra/nodes/handlers/mcp/contract.yaml +69 -0
- omnibase_infra/nodes/handlers/vault/contract.yaml +91 -0
- omnibase_infra/nodes/node_intent_storage_effect/__init__.py +50 -0
- omnibase_infra/nodes/node_intent_storage_effect/contract.yaml +194 -0
- omnibase_infra/nodes/node_intent_storage_effect/models/__init__.py +24 -0
- omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_input.py +141 -0
- omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_output.py +130 -0
- omnibase_infra/nodes/node_intent_storage_effect/node.py +94 -0
- omnibase_infra/nodes/node_intent_storage_effect/registry/__init__.py +35 -0
- omnibase_infra/nodes/node_intent_storage_effect/registry/registry_infra_intent_storage.py +294 -0
- omnibase_infra/nodes/node_ledger_projection_compute/__init__.py +50 -0
- omnibase_infra/nodes/node_ledger_projection_compute/contract.yaml +104 -0
- omnibase_infra/nodes/node_ledger_projection_compute/node.py +284 -0
- omnibase_infra/nodes/node_ledger_projection_compute/registry/__init__.py +29 -0
- omnibase_infra/nodes/node_ledger_projection_compute/registry/registry_infra_ledger_projection.py +118 -0
- omnibase_infra/nodes/node_ledger_write_effect/__init__.py +82 -0
- omnibase_infra/nodes/node_ledger_write_effect/contract.yaml +200 -0
- omnibase_infra/nodes/node_ledger_write_effect/handlers/__init__.py +22 -0
- omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_append.py +372 -0
- omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_query.py +597 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/__init__.py +31 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_append_result.py +54 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_entry.py +92 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query.py +53 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query_result.py +41 -0
- omnibase_infra/nodes/node_ledger_write_effect/node.py +89 -0
- omnibase_infra/nodes/node_ledger_write_effect/protocols/__init__.py +13 -0
- omnibase_infra/nodes/node_ledger_write_effect/protocols/protocol_ledger_persistence.py +127 -0
- omnibase_infra/nodes/node_ledger_write_effect/registry/__init__.py +9 -0
- omnibase_infra/nodes/node_ledger_write_effect/registry/registry_infra_ledger_write.py +121 -0
- omnibase_infra/nodes/node_registration_orchestrator/README.md +542 -0
- omnibase_infra/nodes/node_registration_orchestrator/__init__.py +120 -0
- omnibase_infra/nodes/node_registration_orchestrator/contract.yaml +482 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/__init__.py +53 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_introspected.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_registration_acked.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_runtime_tick.py +373 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/__init__.py +62 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_heartbeat.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_introspected.py +694 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_registration_acked.py +458 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_runtime_tick.py +364 -0
- omnibase_infra/nodes/node_registration_orchestrator/introspection_event_router.py +544 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/__init__.py +75 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_intent_payload.py +194 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_registration_intent.py +67 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_intent_execution_result.py +50 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_node_liveness_expired.py +107 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_config.py +67 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_input.py +41 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_output.py +166 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_intent_payload.py +235 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_upsert_intent.py +68 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_execution_result.py +384 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_state.py +60 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_registration_intent.py +177 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_registry_intent.py +247 -0
- omnibase_infra/nodes/node_registration_orchestrator/node.py +195 -0
- omnibase_infra/nodes/node_registration_orchestrator/plugin.py +909 -0
- omnibase_infra/nodes/node_registration_orchestrator/protocols.py +439 -0
- omnibase_infra/nodes/node_registration_orchestrator/registry/__init__.py +41 -0
- omnibase_infra/nodes/node_registration_orchestrator/registry/registry_infra_node_registration_orchestrator.py +528 -0
- omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +393 -0
- omnibase_infra/nodes/node_registration_orchestrator/wiring.py +743 -0
- omnibase_infra/nodes/node_registration_reducer/__init__.py +15 -0
- omnibase_infra/nodes/node_registration_reducer/contract.yaml +301 -0
- omnibase_infra/nodes/node_registration_reducer/models/__init__.py +38 -0
- omnibase_infra/nodes/node_registration_reducer/models/model_validation_result.py +113 -0
- omnibase_infra/nodes/node_registration_reducer/node.py +139 -0
- omnibase_infra/nodes/node_registration_reducer/registry/__init__.py +9 -0
- omnibase_infra/nodes/node_registration_reducer/registry/registry_infra_node_registration_reducer.py +79 -0
- omnibase_infra/nodes/node_registration_storage_effect/__init__.py +41 -0
- omnibase_infra/nodes/node_registration_storage_effect/contract.yaml +220 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/__init__.py +44 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_delete_result.py +132 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_record.py +199 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_update.py +155 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_details.py +123 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_result.py +117 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_query.py +100 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_result.py +136 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_upsert_result.py +127 -0
- omnibase_infra/nodes/node_registration_storage_effect/node.py +112 -0
- omnibase_infra/nodes/node_registration_storage_effect/protocols/__init__.py +22 -0
- omnibase_infra/nodes/node_registration_storage_effect/protocols/protocol_registration_persistence.py +333 -0
- omnibase_infra/nodes/node_registration_storage_effect/registry/__init__.py +23 -0
- omnibase_infra/nodes/node_registration_storage_effect/registry/registry_infra_registration_storage.py +215 -0
- omnibase_infra/nodes/node_registry_effect/__init__.py +85 -0
- omnibase_infra/nodes/node_registry_effect/contract.yaml +677 -0
- omnibase_infra/nodes/node_registry_effect/handlers/__init__.py +70 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_deregister.py +211 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_register.py +212 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_partial_retry.py +417 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_deactivate.py +215 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_upsert.py +208 -0
- omnibase_infra/nodes/node_registry_effect/models/__init__.py +43 -0
- omnibase_infra/nodes/node_registry_effect/models/model_partial_retry_request.py +92 -0
- omnibase_infra/nodes/node_registry_effect/node.py +165 -0
- omnibase_infra/nodes/node_registry_effect/registry/__init__.py +27 -0
- omnibase_infra/nodes/node_registry_effect/registry/registry_infra_registry_effect.py +196 -0
- omnibase_infra/nodes/node_service_discovery_effect/__init__.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/contract.yaml +246 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/__init__.py +67 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/enum_health_status.py +72 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/enum_service_discovery_operation.py +58 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_query.py +99 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_result.py +98 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_health_check_config.py +121 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_query_metadata.py +63 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_registration_result.py +130 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_details.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_result.py +119 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_info.py +106 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_registration.py +121 -0
- omnibase_infra/nodes/node_service_discovery_effect/node.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/protocols/__init__.py +14 -0
- omnibase_infra/nodes/node_service_discovery_effect/protocols/protocol_discovery_operations.py +279 -0
- omnibase_infra/nodes/node_service_discovery_effect/registry/__init__.py +13 -0
- omnibase_infra/nodes/node_service_discovery_effect/registry/registry_infra_service_discovery.py +222 -0
- omnibase_infra/nodes/reducers/__init__.py +30 -0
- omnibase_infra/nodes/reducers/models/__init__.py +37 -0
- omnibase_infra/nodes/reducers/models/model_payload_consul_register.py +87 -0
- omnibase_infra/nodes/reducers/models/model_payload_ledger_append.py +133 -0
- omnibase_infra/nodes/reducers/models/model_payload_postgres_upsert_registration.py +60 -0
- omnibase_infra/nodes/reducers/models/model_registration_confirmation.py +166 -0
- omnibase_infra/nodes/reducers/models/model_registration_state.py +433 -0
- omnibase_infra/nodes/reducers/registration_reducer.py +1138 -0
- omnibase_infra/observability/__init__.py +143 -0
- omnibase_infra/observability/constants_metrics.py +91 -0
- omnibase_infra/observability/factory_observability_sink.py +525 -0
- omnibase_infra/observability/handlers/__init__.py +118 -0
- omnibase_infra/observability/handlers/handler_logging_structured.py +967 -0
- omnibase_infra/observability/handlers/handler_metrics_prometheus.py +1120 -0
- omnibase_infra/observability/handlers/model_logging_handler_config.py +71 -0
- omnibase_infra/observability/handlers/model_logging_handler_response.py +77 -0
- omnibase_infra/observability/handlers/model_metrics_handler_config.py +172 -0
- omnibase_infra/observability/handlers/model_metrics_handler_payload.py +135 -0
- omnibase_infra/observability/handlers/model_metrics_handler_response.py +101 -0
- omnibase_infra/observability/hooks/__init__.py +74 -0
- omnibase_infra/observability/hooks/hook_observability.py +1223 -0
- omnibase_infra/observability/models/__init__.py +30 -0
- omnibase_infra/observability/models/enum_required_log_context_key.py +77 -0
- omnibase_infra/observability/models/model_buffered_log_entry.py +117 -0
- omnibase_infra/observability/models/model_logging_sink_config.py +73 -0
- omnibase_infra/observability/models/model_metrics_sink_config.py +156 -0
- omnibase_infra/observability/sinks/__init__.py +69 -0
- omnibase_infra/observability/sinks/sink_logging_structured.py +809 -0
- omnibase_infra/observability/sinks/sink_metrics_prometheus.py +710 -0
- omnibase_infra/plugins/__init__.py +27 -0
- omnibase_infra/plugins/examples/__init__.py +28 -0
- omnibase_infra/plugins/examples/plugin_json_normalizer.py +271 -0
- omnibase_infra/plugins/examples/plugin_json_normalizer_error_handling.py +210 -0
- omnibase_infra/plugins/models/__init__.py +21 -0
- omnibase_infra/plugins/models/model_plugin_context.py +76 -0
- omnibase_infra/plugins/models/model_plugin_input_data.py +58 -0
- omnibase_infra/plugins/models/model_plugin_output_data.py +62 -0
- omnibase_infra/plugins/plugin_compute_base.py +449 -0
- omnibase_infra/projectors/__init__.py +30 -0
- omnibase_infra/projectors/contracts/__init__.py +63 -0
- omnibase_infra/projectors/contracts/registration_projector.yaml +370 -0
- omnibase_infra/projectors/projection_reader_registration.py +1559 -0
- omnibase_infra/projectors/snapshot_publisher_registration.py +1329 -0
- omnibase_infra/protocols/__init__.py +104 -0
- omnibase_infra/protocols/protocol_capability_projection.py +253 -0
- omnibase_infra/protocols/protocol_capability_query.py +251 -0
- omnibase_infra/protocols/protocol_container_aware.py +200 -0
- omnibase_infra/protocols/protocol_dispatch_engine.py +152 -0
- omnibase_infra/protocols/protocol_event_bus_like.py +127 -0
- omnibase_infra/protocols/protocol_event_projector.py +96 -0
- omnibase_infra/protocols/protocol_idempotency_store.py +142 -0
- omnibase_infra/protocols/protocol_message_dispatcher.py +247 -0
- omnibase_infra/protocols/protocol_message_type_registry.py +306 -0
- omnibase_infra/protocols/protocol_plugin_compute.py +368 -0
- omnibase_infra/protocols/protocol_projector_schema_validator.py +82 -0
- omnibase_infra/protocols/protocol_registry_metrics.py +215 -0
- omnibase_infra/protocols/protocol_snapshot_publisher.py +396 -0
- omnibase_infra/protocols/protocol_snapshot_store.py +567 -0
- omnibase_infra/runtime/__init__.py +445 -0
- omnibase_infra/runtime/binding_config_resolver.py +2771 -0
- omnibase_infra/runtime/binding_resolver.py +753 -0
- omnibase_infra/runtime/chain_aware_dispatch.py +467 -0
- omnibase_infra/runtime/constants_notification.py +75 -0
- omnibase_infra/runtime/constants_security.py +70 -0
- omnibase_infra/runtime/contract_handler_discovery.py +587 -0
- omnibase_infra/runtime/contract_loaders/__init__.py +51 -0
- omnibase_infra/runtime/contract_loaders/handler_routing_loader.py +464 -0
- omnibase_infra/runtime/contract_loaders/operation_bindings_loader.py +789 -0
- omnibase_infra/runtime/dispatch_context_enforcer.py +427 -0
- omnibase_infra/runtime/emit_daemon/__init__.py +97 -0
- omnibase_infra/runtime/emit_daemon/cli.py +844 -0
- omnibase_infra/runtime/emit_daemon/client.py +811 -0
- omnibase_infra/runtime/emit_daemon/config.py +535 -0
- omnibase_infra/runtime/emit_daemon/daemon.py +812 -0
- omnibase_infra/runtime/emit_daemon/event_registry.py +477 -0
- omnibase_infra/runtime/emit_daemon/model_daemon_request.py +139 -0
- omnibase_infra/runtime/emit_daemon/model_daemon_response.py +191 -0
- omnibase_infra/runtime/emit_daemon/queue.py +618 -0
- omnibase_infra/runtime/enums/__init__.py +18 -0
- omnibase_infra/runtime/enums/enum_config_ref_scheme.py +33 -0
- omnibase_infra/runtime/enums/enum_scheduler_status.py +170 -0
- omnibase_infra/runtime/envelope_validator.py +179 -0
- omnibase_infra/runtime/event_bus_subcontract_wiring.py +466 -0
- omnibase_infra/runtime/handler_bootstrap_source.py +507 -0
- omnibase_infra/runtime/handler_contract_config_loader.py +603 -0
- omnibase_infra/runtime/handler_contract_source.py +750 -0
- omnibase_infra/runtime/handler_identity.py +81 -0
- omnibase_infra/runtime/handler_plugin_loader.py +2046 -0
- omnibase_infra/runtime/handler_registry.py +329 -0
- omnibase_infra/runtime/handler_source_resolver.py +367 -0
- omnibase_infra/runtime/invocation_security_enforcer.py +427 -0
- omnibase_infra/runtime/kafka_contract_source.py +984 -0
- omnibase_infra/runtime/kernel.py +40 -0
- omnibase_infra/runtime/mixin_policy_validation.py +522 -0
- omnibase_infra/runtime/mixin_semver_cache.py +402 -0
- omnibase_infra/runtime/mixins/__init__.py +24 -0
- omnibase_infra/runtime/mixins/mixin_projector_notification_publishing.py +566 -0
- omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +778 -0
- omnibase_infra/runtime/models/__init__.py +229 -0
- omnibase_infra/runtime/models/model_batch_lifecycle_result.py +217 -0
- omnibase_infra/runtime/models/model_binding_config.py +168 -0
- omnibase_infra/runtime/models/model_binding_config_cache_stats.py +135 -0
- omnibase_infra/runtime/models/model_binding_config_resolver_config.py +329 -0
- omnibase_infra/runtime/models/model_cached_secret.py +138 -0
- omnibase_infra/runtime/models/model_compute_key.py +138 -0
- omnibase_infra/runtime/models/model_compute_registration.py +97 -0
- omnibase_infra/runtime/models/model_config_cache_entry.py +61 -0
- omnibase_infra/runtime/models/model_config_ref.py +331 -0
- omnibase_infra/runtime/models/model_config_ref_parse_result.py +125 -0
- omnibase_infra/runtime/models/model_contract_load_result.py +224 -0
- omnibase_infra/runtime/models/model_domain_plugin_config.py +92 -0
- omnibase_infra/runtime/models/model_domain_plugin_result.py +270 -0
- omnibase_infra/runtime/models/model_duplicate_response.py +54 -0
- omnibase_infra/runtime/models/model_enabled_protocols_config.py +61 -0
- omnibase_infra/runtime/models/model_event_bus_config.py +54 -0
- omnibase_infra/runtime/models/model_failed_component.py +55 -0
- omnibase_infra/runtime/models/model_health_check_response.py +168 -0
- omnibase_infra/runtime/models/model_health_check_result.py +229 -0
- omnibase_infra/runtime/models/model_lifecycle_result.py +245 -0
- omnibase_infra/runtime/models/model_logging_config.py +42 -0
- omnibase_infra/runtime/models/model_optional_correlation_id.py +167 -0
- omnibase_infra/runtime/models/model_optional_string.py +94 -0
- omnibase_infra/runtime/models/model_optional_uuid.py +110 -0
- omnibase_infra/runtime/models/model_policy_context.py +100 -0
- omnibase_infra/runtime/models/model_policy_key.py +138 -0
- omnibase_infra/runtime/models/model_policy_registration.py +139 -0
- omnibase_infra/runtime/models/model_policy_result.py +103 -0
- omnibase_infra/runtime/models/model_policy_type_filter.py +157 -0
- omnibase_infra/runtime/models/model_projector_notification_config.py +171 -0
- omnibase_infra/runtime/models/model_projector_plugin_loader_config.py +47 -0
- omnibase_infra/runtime/models/model_protocol_registration_config.py +65 -0
- omnibase_infra/runtime/models/model_retry_policy.py +105 -0
- omnibase_infra/runtime/models/model_runtime_config.py +150 -0
- omnibase_infra/runtime/models/model_runtime_contract_config.py +268 -0
- omnibase_infra/runtime/models/model_runtime_scheduler_config.py +625 -0
- omnibase_infra/runtime/models/model_runtime_scheduler_metrics.py +233 -0
- omnibase_infra/runtime/models/model_runtime_tick.py +193 -0
- omnibase_infra/runtime/models/model_secret_cache_stats.py +82 -0
- omnibase_infra/runtime/models/model_secret_mapping.py +63 -0
- omnibase_infra/runtime/models/model_secret_resolver_config.py +107 -0
- omnibase_infra/runtime/models/model_secret_resolver_metrics.py +111 -0
- omnibase_infra/runtime/models/model_secret_source_info.py +72 -0
- omnibase_infra/runtime/models/model_secret_source_spec.py +66 -0
- omnibase_infra/runtime/models/model_security_config.py +109 -0
- omnibase_infra/runtime/models/model_shutdown_batch_result.py +75 -0
- omnibase_infra/runtime/models/model_shutdown_config.py +94 -0
- omnibase_infra/runtime/models/model_transition_notification_outbox_config.py +112 -0
- omnibase_infra/runtime/models/model_transition_notification_outbox_metrics.py +140 -0
- omnibase_infra/runtime/models/model_transition_notification_publisher_metrics.py +357 -0
- omnibase_infra/runtime/projector_plugin_loader.py +1462 -0
- omnibase_infra/runtime/projector_schema_manager.py +565 -0
- omnibase_infra/runtime/projector_shell.py +1330 -0
- omnibase_infra/runtime/protocol_contract_descriptor.py +92 -0
- omnibase_infra/runtime/protocol_contract_source.py +92 -0
- omnibase_infra/runtime/protocol_domain_plugin.py +474 -0
- omnibase_infra/runtime/protocol_handler_discovery.py +221 -0
- omnibase_infra/runtime/protocol_handler_plugin_loader.py +327 -0
- omnibase_infra/runtime/protocol_lifecycle_executor.py +435 -0
- omnibase_infra/runtime/protocol_policy.py +366 -0
- omnibase_infra/runtime/protocols/__init__.py +37 -0
- omnibase_infra/runtime/protocols/protocol_runtime_scheduler.py +468 -0
- omnibase_infra/runtime/publisher_topic_scoped.py +294 -0
- omnibase_infra/runtime/registry/__init__.py +93 -0
- omnibase_infra/runtime/registry/mixin_message_type_query.py +326 -0
- omnibase_infra/runtime/registry/mixin_message_type_registration.py +354 -0
- omnibase_infra/runtime/registry/registry_event_bus_binding.py +268 -0
- omnibase_infra/runtime/registry/registry_message_type.py +542 -0
- omnibase_infra/runtime/registry/registry_protocol_binding.py +445 -0
- omnibase_infra/runtime/registry_compute.py +1143 -0
- omnibase_infra/runtime/registry_contract_source.py +693 -0
- omnibase_infra/runtime/registry_dispatcher.py +678 -0
- omnibase_infra/runtime/registry_policy.py +1185 -0
- omnibase_infra/runtime/runtime_contract_config_loader.py +406 -0
- omnibase_infra/runtime/runtime_scheduler.py +1070 -0
- omnibase_infra/runtime/secret_resolver.py +2112 -0
- omnibase_infra/runtime/security_metadata_validator.py +776 -0
- omnibase_infra/runtime/service_kernel.py +1651 -0
- omnibase_infra/runtime/service_message_dispatch_engine.py +2350 -0
- omnibase_infra/runtime/service_runtime_host_process.py +3493 -0
- omnibase_infra/runtime/transition_notification_outbox.py +1190 -0
- omnibase_infra/runtime/transition_notification_publisher.py +765 -0
- omnibase_infra/runtime/util_container_wiring.py +1124 -0
- omnibase_infra/runtime/util_validation.py +314 -0
- omnibase_infra/runtime/util_version.py +98 -0
- omnibase_infra/runtime/util_wiring.py +723 -0
- omnibase_infra/schemas/schema_registration_projection.sql +320 -0
- omnibase_infra/schemas/schema_transition_notification_outbox.sql +245 -0
- omnibase_infra/services/__init__.py +89 -0
- omnibase_infra/services/corpus_capture.py +684 -0
- omnibase_infra/services/mcp/__init__.py +31 -0
- omnibase_infra/services/mcp/mcp_server_lifecycle.py +449 -0
- omnibase_infra/services/mcp/service_mcp_tool_discovery.py +411 -0
- omnibase_infra/services/mcp/service_mcp_tool_registry.py +329 -0
- omnibase_infra/services/mcp/service_mcp_tool_sync.py +565 -0
- omnibase_infra/services/registry_api/__init__.py +40 -0
- omnibase_infra/services/registry_api/main.py +261 -0
- omnibase_infra/services/registry_api/models/__init__.py +66 -0
- omnibase_infra/services/registry_api/models/model_capability_widget_mapping.py +38 -0
- omnibase_infra/services/registry_api/models/model_pagination_info.py +48 -0
- omnibase_infra/services/registry_api/models/model_registry_discovery_response.py +73 -0
- omnibase_infra/services/registry_api/models/model_registry_health_response.py +49 -0
- omnibase_infra/services/registry_api/models/model_registry_instance_view.py +88 -0
- omnibase_infra/services/registry_api/models/model_registry_node_view.py +88 -0
- omnibase_infra/services/registry_api/models/model_registry_summary.py +60 -0
- omnibase_infra/services/registry_api/models/model_response_list_instances.py +43 -0
- omnibase_infra/services/registry_api/models/model_response_list_nodes.py +51 -0
- omnibase_infra/services/registry_api/models/model_warning.py +49 -0
- omnibase_infra/services/registry_api/models/model_widget_defaults.py +28 -0
- omnibase_infra/services/registry_api/models/model_widget_mapping.py +51 -0
- omnibase_infra/services/registry_api/routes.py +371 -0
- omnibase_infra/services/registry_api/service.py +837 -0
- omnibase_infra/services/service_capability_query.py +945 -0
- omnibase_infra/services/service_health.py +898 -0
- omnibase_infra/services/service_node_selector.py +530 -0
- omnibase_infra/services/service_timeout_emitter.py +699 -0
- omnibase_infra/services/service_timeout_scanner.py +394 -0
- omnibase_infra/services/session/__init__.py +56 -0
- omnibase_infra/services/session/config_consumer.py +137 -0
- omnibase_infra/services/session/config_store.py +139 -0
- omnibase_infra/services/session/consumer.py +1007 -0
- omnibase_infra/services/session/protocol_session_aggregator.py +117 -0
- omnibase_infra/services/session/store.py +997 -0
- omnibase_infra/services/snapshot/__init__.py +31 -0
- omnibase_infra/services/snapshot/service_snapshot.py +647 -0
- omnibase_infra/services/snapshot/store_inmemory.py +637 -0
- omnibase_infra/services/snapshot/store_postgres.py +1279 -0
- omnibase_infra/shared/__init__.py +8 -0
- omnibase_infra/testing/__init__.py +10 -0
- omnibase_infra/testing/utils.py +23 -0
- omnibase_infra/topics/__init__.py +45 -0
- omnibase_infra/topics/platform_topic_suffixes.py +140 -0
- omnibase_infra/topics/util_topic_composition.py +95 -0
- omnibase_infra/types/__init__.py +48 -0
- omnibase_infra/types/type_cache_info.py +49 -0
- omnibase_infra/types/type_dsn.py +173 -0
- omnibase_infra/types/type_infra_aliases.py +60 -0
- omnibase_infra/types/typed_dict/__init__.py +29 -0
- omnibase_infra/types/typed_dict/typed_dict_envelope_build_params.py +115 -0
- omnibase_infra/types/typed_dict/typed_dict_introspection_cache.py +128 -0
- omnibase_infra/types/typed_dict/typed_dict_performance_metrics_cache.py +140 -0
- omnibase_infra/types/typed_dict_capabilities.py +64 -0
- omnibase_infra/utils/__init__.py +117 -0
- omnibase_infra/utils/correlation.py +208 -0
- omnibase_infra/utils/util_atomic_file.py +261 -0
- omnibase_infra/utils/util_consumer_group.py +232 -0
- omnibase_infra/utils/util_datetime.py +372 -0
- omnibase_infra/utils/util_db_transaction.py +239 -0
- omnibase_infra/utils/util_dsn_validation.py +333 -0
- omnibase_infra/utils/util_env_parsing.py +264 -0
- omnibase_infra/utils/util_error_sanitization.py +457 -0
- omnibase_infra/utils/util_pydantic_validators.py +477 -0
- omnibase_infra/utils/util_retry_optimistic.py +281 -0
- omnibase_infra/utils/util_semver.py +233 -0
- omnibase_infra/validation/__init__.py +307 -0
- omnibase_infra/validation/contracts/security.validation.yaml +114 -0
- omnibase_infra/validation/enums/__init__.py +11 -0
- omnibase_infra/validation/enums/enum_contract_violation_severity.py +13 -0
- omnibase_infra/validation/infra_validators.py +1514 -0
- omnibase_infra/validation/linter_contract.py +907 -0
- omnibase_infra/validation/mixin_any_type_classification.py +120 -0
- omnibase_infra/validation/mixin_any_type_exemption.py +580 -0
- omnibase_infra/validation/mixin_any_type_reporting.py +106 -0
- omnibase_infra/validation/mixin_execution_shape_violation_checks.py +596 -0
- omnibase_infra/validation/mixin_node_archetype_detection.py +254 -0
- omnibase_infra/validation/models/__init__.py +15 -0
- omnibase_infra/validation/models/model_contract_lint_result.py +101 -0
- omnibase_infra/validation/models/model_contract_violation.py +41 -0
- omnibase_infra/validation/service_validation_aggregator.py +395 -0
- omnibase_infra/validation/validation_exemptions.yaml +2033 -0
- omnibase_infra/validation/validator_any_type.py +715 -0
- omnibase_infra/validation/validator_chain_propagation.py +839 -0
- omnibase_infra/validation/validator_execution_shape.py +465 -0
- omnibase_infra/validation/validator_localhandler.py +261 -0
- omnibase_infra/validation/validator_registration_security.py +410 -0
- omnibase_infra/validation/validator_routing_coverage.py +1020 -0
- omnibase_infra/validation/validator_runtime_shape.py +915 -0
- omnibase_infra/validation/validator_security.py +513 -0
- omnibase_infra/validation/validator_topic_category.py +1152 -0
- omnibase_infra-0.2.6.dist-info/METADATA +197 -0
- omnibase_infra-0.2.6.dist-info/RECORD +833 -0
- omnibase_infra-0.2.6.dist-info/WHEEL +4 -0
- omnibase_infra-0.2.6.dist-info/entry_points.txt +5 -0
- omnibase_infra-0.2.6.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,710 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Prometheus metrics sink implementation for ONEX observability.
|
|
4
|
+
|
|
5
|
+
This module provides a thread-safe Prometheus metrics sink that implements
|
|
6
|
+
the ProtocolHotPathMetricsSink protocol. It enforces cardinality policies
|
|
7
|
+
to prevent high-cardinality label explosions that can overwhelm metrics backends.
|
|
8
|
+
|
|
9
|
+
Key Features:
|
|
10
|
+
- Thread-safe metric registry with lazy metric creation
|
|
11
|
+
- Cardinality enforcement via ModelMetricsPolicy
|
|
12
|
+
- Forbidden high-cardinality labels blocked (envelope_id, correlation_id, etc.)
|
|
13
|
+
- Label value length enforcement
|
|
14
|
+
- Configurable violation handling (raise, warn_and_drop, drop_silent, warn_and_strip)
|
|
15
|
+
|
|
16
|
+
Priority Metrics Support:
|
|
17
|
+
- Circuit breaker: state gauge, trip counter, rejection counter
|
|
18
|
+
- Handler execution: latency histogram, success/failure counters
|
|
19
|
+
- Retry: attempts counter, final failure counter
|
|
20
|
+
|
|
21
|
+
Thread-Safety:
|
|
22
|
+
This implementation is fully thread-safe. Metric objects are created lazily
|
|
23
|
+
and cached using a threading.Lock to prevent duplicate metric registration
|
|
24
|
+
errors that would occur with concurrent first-access to the same metric.
|
|
25
|
+
|
|
26
|
+
Usage Example:
|
|
27
|
+
>>> from omnibase_core.models.observability import ModelMetricsPolicy
|
|
28
|
+
>>> from omnibase_infra.observability.sinks import SinkMetricsPrometheus
|
|
29
|
+
>>>
|
|
30
|
+
>>> # Create with default policy (warns and drops on violation)
|
|
31
|
+
>>> sink = SinkMetricsPrometheus()
|
|
32
|
+
>>>
|
|
33
|
+
>>> # Or with custom policy
|
|
34
|
+
>>> policy = ModelMetricsPolicy(
|
|
35
|
+
... on_violation=EnumMetricsPolicyViolationAction.RAISE,
|
|
36
|
+
... )
|
|
37
|
+
>>> sink = SinkMetricsPrometheus(policy=policy)
|
|
38
|
+
>>>
|
|
39
|
+
>>> # Use in hot path code
|
|
40
|
+
>>> sink.increment_counter(
|
|
41
|
+
... "http_requests_total",
|
|
42
|
+
... {"method": "POST", "status": "200", "handler": "create_user"},
|
|
43
|
+
... )
|
|
44
|
+
|
|
45
|
+
See Also:
|
|
46
|
+
- ProtocolHotPathMetricsSink: Protocol definition in omnibase_spi
|
|
47
|
+
- ModelMetricsPolicy: Cardinality policy model in omnibase_core
|
|
48
|
+
- docs/patterns/circuit_breaker_implementation.md: Circuit breaker metrics
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
from __future__ import annotations
|
|
52
|
+
|
|
53
|
+
import logging
|
|
54
|
+
import threading
|
|
55
|
+
from typing import TYPE_CHECKING, cast
|
|
56
|
+
|
|
57
|
+
from omnibase_infra.enums import EnumInfraTransportType
|
|
58
|
+
from omnibase_infra.errors import ModelInfraErrorContext, ProtocolConfigurationError
|
|
59
|
+
|
|
60
|
+
# Dependency validation for prometheus_client with clear error message
|
|
61
|
+
_PROMETHEUS_CLIENT_AVAILABLE: bool = False
|
|
62
|
+
_PROMETHEUS_IMPORT_ERROR: str | None = None
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
from prometheus_client import Counter, Gauge, Histogram
|
|
66
|
+
|
|
67
|
+
_PROMETHEUS_CLIENT_AVAILABLE = True
|
|
68
|
+
except ImportError as e:
|
|
69
|
+
_PROMETHEUS_IMPORT_ERROR = str(e)
|
|
70
|
+
# Provide stubs for type checking when prometheus_client is not installed
|
|
71
|
+
Counter = None # type: ignore[assignment, misc]
|
|
72
|
+
Gauge = None # type: ignore[assignment, misc]
|
|
73
|
+
Histogram = None # type: ignore[assignment, misc]
|
|
74
|
+
|
|
75
|
+
if TYPE_CHECKING:
|
|
76
|
+
from omnibase_core.models.observability import ModelMetricsPolicy
|
|
77
|
+
|
|
78
|
+
_logger = logging.getLogger(__name__)
|
|
79
|
+
|
|
80
|
+
# Import constants from dedicated constants module (ONEX pattern: constants in constants_*.py)
|
|
81
|
+
# Note: DEFAULT_HISTOGRAM_BUCKETS is also re-exported from this module for backwards compatibility
|
|
82
|
+
from omnibase_infra.observability.constants_metrics import (
|
|
83
|
+
DEFAULT_HISTOGRAM_BUCKETS,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class SinkMetricsPrometheus:
|
|
88
|
+
"""Thread-safe Prometheus metrics sink with cardinality policy enforcement.
|
|
89
|
+
|
|
90
|
+
This class implements ProtocolHotPathMetricsSink for Prometheus metric collection
|
|
91
|
+
while enforcing cardinality policies to prevent metric explosion. All metrics
|
|
92
|
+
are created lazily on first access and cached for subsequent calls.
|
|
93
|
+
|
|
94
|
+
Cardinality Enforcement:
|
|
95
|
+
The sink validates all labels against the configured ModelMetricsPolicy before
|
|
96
|
+
recording any metric. By default, the following high-cardinality labels are
|
|
97
|
+
forbidden:
|
|
98
|
+
- envelope_id: Unique per-message identifier
|
|
99
|
+
- correlation_id: Request correlation identifier
|
|
100
|
+
- node_id: Node instance identifier
|
|
101
|
+
- runtime_id: Runtime instance identifier
|
|
102
|
+
|
|
103
|
+
Attempts to use these labels will be handled according to the policy's
|
|
104
|
+
on_violation setting (raise, warn_and_drop, drop_silent, warn_and_strip).
|
|
105
|
+
|
|
106
|
+
Thread-Safety:
|
|
107
|
+
All metric operations are thread-safe. The internal metric registry uses
|
|
108
|
+
a threading.Lock to ensure that metric objects are created exactly once
|
|
109
|
+
even under concurrent access. Individual metric operations (increment,
|
|
110
|
+
set, observe) are inherently thread-safe in prometheus_client.
|
|
111
|
+
|
|
112
|
+
Metric Naming:
|
|
113
|
+
Metric names should follow Prometheus naming conventions:
|
|
114
|
+
- Use lowercase with underscores (snake_case)
|
|
115
|
+
- Include units in the name (e.g., _seconds, _bytes, _total)
|
|
116
|
+
- Use _total suffix for counters
|
|
117
|
+
- Be descriptive but not too long
|
|
118
|
+
|
|
119
|
+
Attributes:
|
|
120
|
+
_policy: The cardinality policy governing label validation.
|
|
121
|
+
_counters: Cache of Counter metric objects by name.
|
|
122
|
+
_gauges: Cache of Gauge metric objects by name.
|
|
123
|
+
_histograms: Cache of Histogram metric objects by name.
|
|
124
|
+
_lock: Threading lock for thread-safe metric creation.
|
|
125
|
+
|
|
126
|
+
Example:
|
|
127
|
+
>>> sink = SinkMetricsPrometheus()
|
|
128
|
+
>>>
|
|
129
|
+
>>> # Record handler latency
|
|
130
|
+
>>> sink.observe_histogram(
|
|
131
|
+
... "handler_execution_seconds",
|
|
132
|
+
... {"handler_type": "http_rest", "operation": "create_user"},
|
|
133
|
+
... value=0.042,
|
|
134
|
+
... )
|
|
135
|
+
>>>
|
|
136
|
+
>>> # Track circuit breaker state
|
|
137
|
+
>>> sink.set_gauge(
|
|
138
|
+
... "circuit_breaker_state",
|
|
139
|
+
... {"service": "kafka", "transport": "event_bus"},
|
|
140
|
+
... value=0.0, # 0=closed, 1=half_open, 2=open
|
|
141
|
+
... )
|
|
142
|
+
>>>
|
|
143
|
+
>>> # Count retries
|
|
144
|
+
>>> sink.increment_counter(
|
|
145
|
+
... "retry_attempts_total",
|
|
146
|
+
... {"service": "postgres", "operation": "execute_query"},
|
|
147
|
+
... )
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
def __init__(
|
|
151
|
+
self,
|
|
152
|
+
policy: ModelMetricsPolicy | None = None,
|
|
153
|
+
histogram_buckets: tuple[float, ...] | None = None,
|
|
154
|
+
metric_prefix: str = "",
|
|
155
|
+
) -> None:
|
|
156
|
+
"""Initialize the Prometheus metrics sink.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
policy: Cardinality policy for label validation. If None, a default
|
|
160
|
+
policy is created that forbids high-cardinality labels and warns
|
|
161
|
+
on violations while dropping the offending metric.
|
|
162
|
+
histogram_buckets: Custom histogram bucket boundaries. If None,
|
|
163
|
+
DEFAULT_HISTOGRAM_BUCKETS are used (Prometheus conventions).
|
|
164
|
+
metric_prefix: Optional prefix to add to all metric names. Useful for
|
|
165
|
+
namespacing metrics by service or component. The prefix will be
|
|
166
|
+
joined with the metric name using an underscore.
|
|
167
|
+
|
|
168
|
+
Raises:
|
|
169
|
+
ProtocolConfigurationError: If prometheus_client is not installed.
|
|
170
|
+
Install with: pip install prometheus-client
|
|
171
|
+
|
|
172
|
+
Example:
|
|
173
|
+
>>> # Default policy - warns and drops on violation
|
|
174
|
+
>>> sink = SinkMetricsPrometheus()
|
|
175
|
+
>>>
|
|
176
|
+
>>> # Strict policy - raises on any violation
|
|
177
|
+
>>> from omnibase_core.models.observability import ModelMetricsPolicy
|
|
178
|
+
>>> from omnibase_core.enums import EnumMetricsPolicyViolationAction
|
|
179
|
+
>>> strict_policy = ModelMetricsPolicy(
|
|
180
|
+
... on_violation=EnumMetricsPolicyViolationAction.RAISE,
|
|
181
|
+
... )
|
|
182
|
+
>>> sink = SinkMetricsPrometheus(policy=strict_policy)
|
|
183
|
+
>>>
|
|
184
|
+
>>> # Namespaced metrics
|
|
185
|
+
>>> sink = SinkMetricsPrometheus(metric_prefix="onex_infra")
|
|
186
|
+
"""
|
|
187
|
+
# Validate dependency is available with clear error message
|
|
188
|
+
if not _PROMETHEUS_CLIENT_AVAILABLE:
|
|
189
|
+
context = ModelInfraErrorContext.with_correlation(
|
|
190
|
+
transport_type=EnumInfraTransportType.HTTP,
|
|
191
|
+
operation="initialize_prometheus_sink",
|
|
192
|
+
)
|
|
193
|
+
raise ProtocolConfigurationError(
|
|
194
|
+
"prometheus_client is required for SinkMetricsPrometheus but is not installed. "
|
|
195
|
+
f"Install with: pip install prometheus-client. "
|
|
196
|
+
f"Original error: {_PROMETHEUS_IMPORT_ERROR}",
|
|
197
|
+
context=context,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
# Import here to avoid circular imports and allow TYPE_CHECKING
|
|
201
|
+
from omnibase_core.models.observability import ModelMetricsPolicy as _Policy
|
|
202
|
+
|
|
203
|
+
self._policy: ModelMetricsPolicy = policy if policy is not None else _Policy()
|
|
204
|
+
self._histogram_buckets = (
|
|
205
|
+
histogram_buckets if histogram_buckets else DEFAULT_HISTOGRAM_BUCKETS
|
|
206
|
+
)
|
|
207
|
+
self._metric_prefix = metric_prefix
|
|
208
|
+
|
|
209
|
+
# Thread-safe metric caches
|
|
210
|
+
self._counters: dict[str, Counter] = {}
|
|
211
|
+
self._gauges: dict[str, Gauge] = {}
|
|
212
|
+
self._histograms: dict[str, Histogram] = {}
|
|
213
|
+
|
|
214
|
+
# Lock for thread-safe metric creation
|
|
215
|
+
self._lock = threading.Lock()
|
|
216
|
+
|
|
217
|
+
_logger.debug(
|
|
218
|
+
"SinkMetricsPrometheus initialized",
|
|
219
|
+
extra={
|
|
220
|
+
"policy_on_violation": self._policy.on_violation.value,
|
|
221
|
+
"forbidden_keys": list(self._policy.forbidden_label_keys),
|
|
222
|
+
"max_label_value_length": self._policy.max_label_value_length,
|
|
223
|
+
"metric_prefix": self._metric_prefix,
|
|
224
|
+
},
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
def _get_prefixed_name(self, name: str) -> str:
|
|
228
|
+
"""Return metric name with optional prefix.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
name: Base metric name.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
Prefixed metric name if prefix is set, otherwise original name.
|
|
235
|
+
"""
|
|
236
|
+
if self._metric_prefix:
|
|
237
|
+
return f"{self._metric_prefix}_{name}"
|
|
238
|
+
return name
|
|
239
|
+
|
|
240
|
+
def _enforce_labels(self, labels: dict[str, str]) -> dict[str, str] | None:
|
|
241
|
+
"""Validate and enforce label policy.
|
|
242
|
+
|
|
243
|
+
Delegates to ModelMetricsPolicy.enforce_labels() which handles all
|
|
244
|
+
violation actions (raise, warn_and_drop, drop_silent, warn_and_strip).
|
|
245
|
+
|
|
246
|
+
Args:
|
|
247
|
+
labels: Label key-value pairs to validate.
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
Validated/sanitized labels if allowed, None if metric should be dropped.
|
|
251
|
+
|
|
252
|
+
Raises:
|
|
253
|
+
ModelOnexError: If policy on_violation is RAISE and violations found.
|
|
254
|
+
"""
|
|
255
|
+
# enforce_labels returns dict[str, str] | None directly
|
|
256
|
+
# - Returns labels (possibly stripped) if allowed
|
|
257
|
+
# - Returns None if metric should be dropped
|
|
258
|
+
# - Raises ModelOnexError if on_violation=RAISE
|
|
259
|
+
# Cast needed because omnibase_core lacks type stubs
|
|
260
|
+
return cast("dict[str, str] | None", self._policy.enforce_labels(labels))
|
|
261
|
+
|
|
262
|
+
def _get_or_create_counter(
|
|
263
|
+
self,
|
|
264
|
+
name: str,
|
|
265
|
+
label_names: tuple[str, ...],
|
|
266
|
+
documentation: str = "",
|
|
267
|
+
) -> Counter:
|
|
268
|
+
"""Get or create a Counter metric.
|
|
269
|
+
|
|
270
|
+
Thread-safe lazy creation of Counter metrics. The counter is created
|
|
271
|
+
on first access and cached for subsequent calls.
|
|
272
|
+
|
|
273
|
+
Thread-Safety:
|
|
274
|
+
Uses double-check locking pattern for optimal performance:
|
|
275
|
+
1. Fast path: Check cache without lock (common case)
|
|
276
|
+
2. Slow path: Acquire lock and verify before creation
|
|
277
|
+
This avoids lock contention for the common cache-hit case while
|
|
278
|
+
ensuring exactly-once initialization under concurrent access.
|
|
279
|
+
|
|
280
|
+
Label Drift Protection:
|
|
281
|
+
If a metric already exists with different label names, a warning
|
|
282
|
+
is logged and the existing metric is returned. This prevents
|
|
283
|
+
Prometheus errors from label set mismatches.
|
|
284
|
+
|
|
285
|
+
Args:
|
|
286
|
+
name: Metric name (without prefix).
|
|
287
|
+
label_names: Tuple of label key names for this metric.
|
|
288
|
+
documentation: Human-readable metric description.
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
Counter metric object.
|
|
292
|
+
"""
|
|
293
|
+
prefixed_name = self._get_prefixed_name(name)
|
|
294
|
+
|
|
295
|
+
# Fast path: check cache without lock (common case)
|
|
296
|
+
if prefixed_name in self._counters:
|
|
297
|
+
existing = self._counters[prefixed_name]
|
|
298
|
+
# Validate label names match (guard against label drift)
|
|
299
|
+
existing_labels = tuple(existing._labelnames)
|
|
300
|
+
if existing_labels != label_names:
|
|
301
|
+
_logger.warning(
|
|
302
|
+
"Label set drift detected for counter metric",
|
|
303
|
+
extra={
|
|
304
|
+
"metric_name": prefixed_name,
|
|
305
|
+
"existing_labels": existing_labels,
|
|
306
|
+
"requested_labels": label_names,
|
|
307
|
+
},
|
|
308
|
+
)
|
|
309
|
+
return existing
|
|
310
|
+
|
|
311
|
+
# Slow path: acquire lock and double-check before creation
|
|
312
|
+
with self._lock:
|
|
313
|
+
# Double-check after acquiring lock
|
|
314
|
+
if prefixed_name in self._counters:
|
|
315
|
+
existing = self._counters[prefixed_name]
|
|
316
|
+
existing_labels = tuple(existing._labelnames)
|
|
317
|
+
if existing_labels != label_names:
|
|
318
|
+
_logger.warning(
|
|
319
|
+
"Label set drift detected for counter metric",
|
|
320
|
+
extra={
|
|
321
|
+
"metric_name": prefixed_name,
|
|
322
|
+
"existing_labels": existing_labels,
|
|
323
|
+
"requested_labels": label_names,
|
|
324
|
+
},
|
|
325
|
+
)
|
|
326
|
+
return existing
|
|
327
|
+
|
|
328
|
+
self._counters[prefixed_name] = Counter(
|
|
329
|
+
prefixed_name,
|
|
330
|
+
documentation or f"Counter metric: {name}",
|
|
331
|
+
labelnames=label_names,
|
|
332
|
+
)
|
|
333
|
+
_logger.debug(
|
|
334
|
+
"Created Prometheus Counter",
|
|
335
|
+
extra={"metric_name": prefixed_name, "labels": label_names},
|
|
336
|
+
)
|
|
337
|
+
return self._counters[prefixed_name]
|
|
338
|
+
|
|
339
|
+
def _get_or_create_gauge(
|
|
340
|
+
self,
|
|
341
|
+
name: str,
|
|
342
|
+
label_names: tuple[str, ...],
|
|
343
|
+
documentation: str = "",
|
|
344
|
+
) -> Gauge:
|
|
345
|
+
"""Get or create a Gauge metric.
|
|
346
|
+
|
|
347
|
+
Thread-safe lazy creation of Gauge metrics. The gauge is created
|
|
348
|
+
on first access and cached for subsequent calls.
|
|
349
|
+
|
|
350
|
+
Thread-Safety:
|
|
351
|
+
Uses double-check locking pattern for optimal performance:
|
|
352
|
+
1. Fast path: Check cache without lock (common case)
|
|
353
|
+
2. Slow path: Acquire lock and verify before creation
|
|
354
|
+
This avoids lock contention for the common cache-hit case while
|
|
355
|
+
ensuring exactly-once initialization under concurrent access.
|
|
356
|
+
|
|
357
|
+
Label Drift Protection:
|
|
358
|
+
If a metric already exists with different label names, a warning
|
|
359
|
+
is logged and the existing metric is returned. This prevents
|
|
360
|
+
Prometheus errors from label set mismatches.
|
|
361
|
+
|
|
362
|
+
Args:
|
|
363
|
+
name: Metric name (without prefix).
|
|
364
|
+
label_names: Tuple of label key names for this metric.
|
|
365
|
+
documentation: Human-readable metric description.
|
|
366
|
+
|
|
367
|
+
Returns:
|
|
368
|
+
Gauge metric object.
|
|
369
|
+
"""
|
|
370
|
+
prefixed_name = self._get_prefixed_name(name)
|
|
371
|
+
|
|
372
|
+
# Fast path: check cache without lock (common case)
|
|
373
|
+
if prefixed_name in self._gauges:
|
|
374
|
+
existing = self._gauges[prefixed_name]
|
|
375
|
+
# Validate label names match (guard against label drift)
|
|
376
|
+
existing_labels = tuple(existing._labelnames)
|
|
377
|
+
if existing_labels != label_names:
|
|
378
|
+
_logger.warning(
|
|
379
|
+
"Label set drift detected for gauge metric",
|
|
380
|
+
extra={
|
|
381
|
+
"metric_name": prefixed_name,
|
|
382
|
+
"existing_labels": existing_labels,
|
|
383
|
+
"requested_labels": label_names,
|
|
384
|
+
},
|
|
385
|
+
)
|
|
386
|
+
return existing
|
|
387
|
+
|
|
388
|
+
# Slow path: acquire lock and double-check before creation
|
|
389
|
+
with self._lock:
|
|
390
|
+
# Double-check after acquiring lock
|
|
391
|
+
if prefixed_name in self._gauges:
|
|
392
|
+
existing = self._gauges[prefixed_name]
|
|
393
|
+
existing_labels = tuple(existing._labelnames)
|
|
394
|
+
if existing_labels != label_names:
|
|
395
|
+
_logger.warning(
|
|
396
|
+
"Label set drift detected for gauge metric",
|
|
397
|
+
extra={
|
|
398
|
+
"metric_name": prefixed_name,
|
|
399
|
+
"existing_labels": existing_labels,
|
|
400
|
+
"requested_labels": label_names,
|
|
401
|
+
},
|
|
402
|
+
)
|
|
403
|
+
return existing
|
|
404
|
+
|
|
405
|
+
self._gauges[prefixed_name] = Gauge(
|
|
406
|
+
prefixed_name,
|
|
407
|
+
documentation or f"Gauge metric: {name}",
|
|
408
|
+
labelnames=label_names,
|
|
409
|
+
)
|
|
410
|
+
_logger.debug(
|
|
411
|
+
"Created Prometheus Gauge",
|
|
412
|
+
extra={"metric_name": prefixed_name, "labels": label_names},
|
|
413
|
+
)
|
|
414
|
+
return self._gauges[prefixed_name]
|
|
415
|
+
|
|
416
|
+
def _get_or_create_histogram(
|
|
417
|
+
self,
|
|
418
|
+
name: str,
|
|
419
|
+
label_names: tuple[str, ...],
|
|
420
|
+
documentation: str = "",
|
|
421
|
+
) -> Histogram:
|
|
422
|
+
"""Get or create a Histogram metric.
|
|
423
|
+
|
|
424
|
+
Thread-safe lazy creation of Histogram metrics. The histogram is created
|
|
425
|
+
on first access and cached for subsequent calls.
|
|
426
|
+
|
|
427
|
+
Thread-Safety:
|
|
428
|
+
Uses double-check locking pattern for optimal performance:
|
|
429
|
+
1. Fast path: Check cache without lock (common case)
|
|
430
|
+
2. Slow path: Acquire lock and verify before creation
|
|
431
|
+
This avoids lock contention for the common cache-hit case while
|
|
432
|
+
ensuring exactly-once initialization under concurrent access.
|
|
433
|
+
|
|
434
|
+
Label Drift Protection:
|
|
435
|
+
If a metric already exists with different label names, a warning
|
|
436
|
+
is logged and the existing metric is returned. This prevents
|
|
437
|
+
Prometheus errors from label set mismatches.
|
|
438
|
+
|
|
439
|
+
Args:
|
|
440
|
+
name: Metric name (without prefix).
|
|
441
|
+
label_names: Tuple of label key names for this metric.
|
|
442
|
+
documentation: Human-readable metric description.
|
|
443
|
+
|
|
444
|
+
Returns:
|
|
445
|
+
Histogram metric object.
|
|
446
|
+
"""
|
|
447
|
+
prefixed_name = self._get_prefixed_name(name)
|
|
448
|
+
|
|
449
|
+
# Fast path: check cache without lock (common case)
|
|
450
|
+
if prefixed_name in self._histograms:
|
|
451
|
+
existing = self._histograms[prefixed_name]
|
|
452
|
+
# Validate label names match (guard against label drift)
|
|
453
|
+
existing_labels = tuple(existing._labelnames)
|
|
454
|
+
if existing_labels != label_names:
|
|
455
|
+
_logger.warning(
|
|
456
|
+
"Label set drift detected for histogram metric",
|
|
457
|
+
extra={
|
|
458
|
+
"metric_name": prefixed_name,
|
|
459
|
+
"existing_labels": existing_labels,
|
|
460
|
+
"requested_labels": label_names,
|
|
461
|
+
},
|
|
462
|
+
)
|
|
463
|
+
return existing
|
|
464
|
+
|
|
465
|
+
# Slow path: acquire lock and double-check before creation
|
|
466
|
+
with self._lock:
|
|
467
|
+
# Double-check after acquiring lock
|
|
468
|
+
if prefixed_name in self._histograms:
|
|
469
|
+
existing = self._histograms[prefixed_name]
|
|
470
|
+
existing_labels = tuple(existing._labelnames)
|
|
471
|
+
if existing_labels != label_names:
|
|
472
|
+
_logger.warning(
|
|
473
|
+
"Label set drift detected for histogram metric",
|
|
474
|
+
extra={
|
|
475
|
+
"metric_name": prefixed_name,
|
|
476
|
+
"existing_labels": existing_labels,
|
|
477
|
+
"requested_labels": label_names,
|
|
478
|
+
},
|
|
479
|
+
)
|
|
480
|
+
return existing
|
|
481
|
+
|
|
482
|
+
self._histograms[prefixed_name] = Histogram(
|
|
483
|
+
prefixed_name,
|
|
484
|
+
documentation or f"Histogram metric: {name}",
|
|
485
|
+
labelnames=label_names,
|
|
486
|
+
buckets=self._histogram_buckets,
|
|
487
|
+
)
|
|
488
|
+
_logger.debug(
|
|
489
|
+
"Created Prometheus Histogram",
|
|
490
|
+
extra={
|
|
491
|
+
"metric_name": prefixed_name,
|
|
492
|
+
"labels": label_names,
|
|
493
|
+
"buckets": self._histogram_buckets,
|
|
494
|
+
},
|
|
495
|
+
)
|
|
496
|
+
return self._histograms[prefixed_name]
|
|
497
|
+
|
|
498
|
+
def increment_counter(
|
|
499
|
+
self,
|
|
500
|
+
name: str,
|
|
501
|
+
labels: dict[str, str],
|
|
502
|
+
increment: int = 1,
|
|
503
|
+
) -> None:
|
|
504
|
+
"""Increment a counter metric by the specified amount.
|
|
505
|
+
|
|
506
|
+
Counters are monotonically increasing values that reset only on process
|
|
507
|
+
restart. Use counters for events, requests processed, errors, etc.
|
|
508
|
+
|
|
509
|
+
Early Return Optimization:
|
|
510
|
+
Non-positive increments (<=0) result in an immediate return without
|
|
511
|
+
label validation. This avoids unnecessary policy enforcement overhead
|
|
512
|
+
for no-op operations.
|
|
513
|
+
|
|
514
|
+
Cardinality Enforcement:
|
|
515
|
+
Labels are validated against the policy before recording. If any
|
|
516
|
+
forbidden labels (envelope_id, correlation_id, node_id, runtime_id)
|
|
517
|
+
are present or values exceed max length, the behavior depends on
|
|
518
|
+
the policy's on_violation setting.
|
|
519
|
+
|
|
520
|
+
Args:
|
|
521
|
+
name: Metric name following Prometheus naming conventions.
|
|
522
|
+
Should be lowercase with underscores (e.g., "http_requests_total").
|
|
523
|
+
labels: Label key-value pairs. Keys and values must be strings.
|
|
524
|
+
Label cardinality should be bounded (avoid high-cardinality
|
|
525
|
+
values like user IDs or request IDs).
|
|
526
|
+
increment: Amount to add to the counter. Defaults to 1.
|
|
527
|
+
Must be positive; negative values are silently ignored.
|
|
528
|
+
|
|
529
|
+
Returns:
|
|
530
|
+
None. This method has no return value.
|
|
531
|
+
|
|
532
|
+
Example:
|
|
533
|
+
>>> sink.increment_counter(
|
|
534
|
+
... "http_requests_total",
|
|
535
|
+
... {"method": "POST", "status": "200", "handler": "create_user"},
|
|
536
|
+
... )
|
|
537
|
+
>>>
|
|
538
|
+
>>> # Increment by more than 1
|
|
539
|
+
>>> sink.increment_counter(
|
|
540
|
+
... "bytes_processed_total",
|
|
541
|
+
... {"stream": "events"},
|
|
542
|
+
... increment=len(payload),
|
|
543
|
+
... )
|
|
544
|
+
"""
|
|
545
|
+
# Early return for non-positive increments (skip label validation for no-op)
|
|
546
|
+
if increment < 1:
|
|
547
|
+
_logger.debug(
|
|
548
|
+
"Ignoring non-positive counter increment",
|
|
549
|
+
extra={"metric_name": name, "increment": increment},
|
|
550
|
+
)
|
|
551
|
+
return
|
|
552
|
+
|
|
553
|
+
# Validate labels against policy (only for positive increments)
|
|
554
|
+
validated_labels = self._enforce_labels(labels)
|
|
555
|
+
if validated_labels is None:
|
|
556
|
+
# Policy dropped the metric
|
|
557
|
+
return
|
|
558
|
+
|
|
559
|
+
# Get label names as sorted tuple for consistent ordering
|
|
560
|
+
label_names = tuple(sorted(validated_labels.keys()))
|
|
561
|
+
|
|
562
|
+
# Get or create counter
|
|
563
|
+
counter = self._get_or_create_counter(name, label_names)
|
|
564
|
+
|
|
565
|
+
# Increment with labels in sorted order
|
|
566
|
+
label_values = {k: validated_labels[k] for k in label_names}
|
|
567
|
+
counter.labels(**label_values).inc(increment)
|
|
568
|
+
|
|
569
|
+
def set_gauge(
|
|
570
|
+
self,
|
|
571
|
+
name: str,
|
|
572
|
+
labels: dict[str, str],
|
|
573
|
+
value: float,
|
|
574
|
+
) -> None:
|
|
575
|
+
"""Set a gauge metric to the specified value.
|
|
576
|
+
|
|
577
|
+
Gauges represent point-in-time values that can increase or decrease.
|
|
578
|
+
Use gauges for queue depths, active connections, memory usage, etc.
|
|
579
|
+
|
|
580
|
+
Cardinality Enforcement:
|
|
581
|
+
Labels are validated against the policy before recording. If any
|
|
582
|
+
forbidden labels are present or values exceed max length, the
|
|
583
|
+
behavior depends on the policy's on_violation setting.
|
|
584
|
+
|
|
585
|
+
Args:
|
|
586
|
+
name: Metric name following Prometheus naming conventions.
|
|
587
|
+
Should be lowercase with underscores (e.g., "queue_depth").
|
|
588
|
+
labels: Label key-value pairs. Keys and values must be strings.
|
|
589
|
+
value: Current value of the gauge. Can be any float including
|
|
590
|
+
negative values, zero, infinity, or NaN.
|
|
591
|
+
|
|
592
|
+
Returns:
|
|
593
|
+
None. This method has no return value.
|
|
594
|
+
|
|
595
|
+
Example:
|
|
596
|
+
>>> sink.set_gauge(
|
|
597
|
+
... "active_connections",
|
|
598
|
+
... {"pool": "database", "region": "us-west"},
|
|
599
|
+
... value=42.0,
|
|
600
|
+
... )
|
|
601
|
+
>>>
|
|
602
|
+
>>> # Circuit breaker state (0=closed, 1=half_open, 2=open)
|
|
603
|
+
>>> sink.set_gauge(
|
|
604
|
+
... "circuit_breaker_state",
|
|
605
|
+
... {"service": "kafka", "transport": "event_bus"},
|
|
606
|
+
... value=0.0,
|
|
607
|
+
... )
|
|
608
|
+
"""
|
|
609
|
+
# Validate labels against policy
|
|
610
|
+
validated_labels = self._enforce_labels(labels)
|
|
611
|
+
if validated_labels is None:
|
|
612
|
+
# Policy dropped the metric
|
|
613
|
+
return
|
|
614
|
+
|
|
615
|
+
# Get label names as sorted tuple for consistent ordering
|
|
616
|
+
label_names = tuple(sorted(validated_labels.keys()))
|
|
617
|
+
|
|
618
|
+
# Get or create gauge
|
|
619
|
+
gauge = self._get_or_create_gauge(name, label_names)
|
|
620
|
+
|
|
621
|
+
# Set with labels in sorted order
|
|
622
|
+
label_values = {k: validated_labels[k] for k in label_names}
|
|
623
|
+
gauge.labels(**label_values).set(value)
|
|
624
|
+
|
|
625
|
+
def observe_histogram(
|
|
626
|
+
self,
|
|
627
|
+
name: str,
|
|
628
|
+
labels: dict[str, str],
|
|
629
|
+
value: float,
|
|
630
|
+
) -> None:
|
|
631
|
+
"""Record an observation in a histogram metric.
|
|
632
|
+
|
|
633
|
+
Histograms track the distribution of values, typically latencies or
|
|
634
|
+
sizes. Values are bucketed for efficient storage and aggregation.
|
|
635
|
+
|
|
636
|
+
Cardinality Enforcement:
|
|
637
|
+
Labels are validated against the policy before recording. If any
|
|
638
|
+
forbidden labels are present or values exceed max length, the
|
|
639
|
+
behavior depends on the policy's on_violation setting.
|
|
640
|
+
|
|
641
|
+
Args:
|
|
642
|
+
name: Metric name following Prometheus naming conventions.
|
|
643
|
+
Should be lowercase with underscores and include units
|
|
644
|
+
(e.g., "request_duration_seconds", "response_size_bytes").
|
|
645
|
+
labels: Label key-value pairs. Keys and values must be strings.
|
|
646
|
+
value: Observed value to record. Should be non-negative for
|
|
647
|
+
most use cases (durations, sizes).
|
|
648
|
+
|
|
649
|
+
Returns:
|
|
650
|
+
None. This method has no return value.
|
|
651
|
+
|
|
652
|
+
Example:
|
|
653
|
+
>>> import time
|
|
654
|
+
>>>
|
|
655
|
+
>>> start = time.perf_counter()
|
|
656
|
+
>>> result = process_request(request)
|
|
657
|
+
>>> duration = time.perf_counter() - start
|
|
658
|
+
>>>
|
|
659
|
+
>>> sink.observe_histogram(
|
|
660
|
+
... "request_duration_seconds",
|
|
661
|
+
... {"handler": "process_request", "status": "success"},
|
|
662
|
+
... value=duration,
|
|
663
|
+
... )
|
|
664
|
+
"""
|
|
665
|
+
# Validate labels against policy
|
|
666
|
+
validated_labels = self._enforce_labels(labels)
|
|
667
|
+
if validated_labels is None:
|
|
668
|
+
# Policy dropped the metric
|
|
669
|
+
return
|
|
670
|
+
|
|
671
|
+
# Get label names as sorted tuple for consistent ordering
|
|
672
|
+
label_names = tuple(sorted(validated_labels.keys()))
|
|
673
|
+
|
|
674
|
+
# Get or create histogram
|
|
675
|
+
histogram = self._get_or_create_histogram(name, label_names)
|
|
676
|
+
|
|
677
|
+
# Observe with labels in sorted order
|
|
678
|
+
label_values = {k: validated_labels[k] for k in label_names}
|
|
679
|
+
histogram.labels(**label_values).observe(value)
|
|
680
|
+
|
|
681
|
+
def get_policy(self) -> ModelMetricsPolicy:
|
|
682
|
+
"""Retrieve the metrics policy governing this sink.
|
|
683
|
+
|
|
684
|
+
The policy defines constraints and configuration for metrics collection,
|
|
685
|
+
including forbidden label keys, maximum label value length, and
|
|
686
|
+
violation handling behavior.
|
|
687
|
+
|
|
688
|
+
Returns:
|
|
689
|
+
ModelMetricsPolicy: The active metrics policy. This is immutable
|
|
690
|
+
(frozen=True in Pydantic config) and remains consistent
|
|
691
|
+
throughout the sink's lifetime.
|
|
692
|
+
|
|
693
|
+
Thread-Safety:
|
|
694
|
+
This method is thread-safe. The policy is immutable after creation.
|
|
695
|
+
|
|
696
|
+
Example:
|
|
697
|
+
>>> policy = sink.get_policy()
|
|
698
|
+
>>>
|
|
699
|
+
>>> # Check forbidden labels
|
|
700
|
+
>>> if "correlation_id" in policy.forbidden_label_keys:
|
|
701
|
+
... logger.debug("correlation_id is forbidden as a metric label")
|
|
702
|
+
>>>
|
|
703
|
+
>>> # Check violation behavior
|
|
704
|
+
>>> if policy.on_violation == EnumMetricsPolicyViolationAction.RAISE:
|
|
705
|
+
... logger.warning("Strict policy - violations will raise errors")
|
|
706
|
+
"""
|
|
707
|
+
return self._policy
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
__all__ = ["SinkMetricsPrometheus", "DEFAULT_HISTOGRAM_BUCKETS"]
|