mirror of
https://github.com/hoshikawa2/agent_platform_oci.git
synced 2026-09-07 10:13:46 +00:00
Observability: PUBSUB_EXCLUDED_EVENT_TYPES
This commit is contained in:
@@ -50,6 +50,10 @@ Cada evento vira uma observation/span com `name` igual ao código:
|
||||
- `NOC.001`
|
||||
- `GRL.004`
|
||||
|
||||
No modo `LANGFUSE_TRACE_MODE=compact`, eventos `IC.*`, `AGA.*` e `NOC.*`
|
||||
continuam visíveis como spans filhos do span raiz. Eles não são substituídos por
|
||||
tags da trace. Eventos técnicos de baixo nível continuam sujeitos à compactação.
|
||||
|
||||
A metadata recebe automaticamente:
|
||||
|
||||
- `tag`
|
||||
|
||||
@@ -17,6 +17,7 @@ Esta versão corrige dois gaps da migração do `agent_framework_oci`:
|
||||
- Publica flat por padrão.
|
||||
- Mantém modo legado por configuração.
|
||||
- Exclui `NOC.*` do Pub/Sub por padrão, seguindo a lib antiga.
|
||||
- Permite excluir tipos de evento específicos do Pub/Sub por configuração.
|
||||
- Injeta `sequence` automaticamente no payload flat antes do publish.
|
||||
|
||||
- `src/agent_framework/analytics/tim_sequence.py`
|
||||
@@ -45,6 +46,10 @@ Esta versão corrige dois gaps da migração do `agent_framework_oci`:
|
||||
PUBSUB_PAYLOAD_MODE=flat
|
||||
PUBSUB_EXCLUDE_NOC=true
|
||||
|
||||
# Lista opcional, separada por vírgulas, de tipos de evento não publicados no Pub/Sub.
|
||||
# Os eventos continuam disponíveis para os demais destinos de observabilidade.
|
||||
PUBSUB_EXCLUDED_EVENT_TYPES=GRL.NATIVE_OUTPUT_GUARDRAILS
|
||||
|
||||
# Sequence automático por sessão no payload Pub/Sub flat
|
||||
PUBSUB_SEQUENCE_ENABLED=true
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
pyproject.toml
|
||||
src/agent_framework/__init__.py
|
||||
src/agent_framework/gateway_policy_context.py
|
||||
src/agent_framework/observer.py
|
||||
src/agent_framework/runtime_mcp_gateway_adapter.py
|
||||
src/agent_framework.egg-info/PKG-INFO
|
||||
src/agent_framework.egg-info/SOURCES.txt
|
||||
src/agent_framework.egg-info/dependency_links.txt
|
||||
@@ -11,6 +13,8 @@ src/agent_framework/analytics/composite_publisher.py
|
||||
src/agent_framework/analytics/event_builder.py
|
||||
src/agent_framework/analytics/factory.py
|
||||
src/agent_framework/analytics/publisher.py
|
||||
src/agent_framework/analytics/tim_payload_mapper.py
|
||||
src/agent_framework/analytics/tim_sequence.py
|
||||
src/agent_framework/analytics/providers/__init__.py
|
||||
src/agent_framework/analytics/providers/kafka.py
|
||||
src/agent_framework/analytics/providers/langfuse.py
|
||||
@@ -32,6 +36,8 @@ src/agent_framework/config/agent_registry.py
|
||||
src/agent_framework/config/settings.py
|
||||
src/agent_framework/events/__init__.py
|
||||
src/agent_framework/events/oci_streaming.py
|
||||
src/agent_framework/gateways/__init__.py
|
||||
src/agent_framework/gateways/mcp_gateway_client.py
|
||||
src/agent_framework/global_supervisor/__init__.py
|
||||
src/agent_framework/global_supervisor/client.py
|
||||
src/agent_framework/global_supervisor/config.py
|
||||
@@ -148,6 +154,7 @@ src/agent_framework/observability/langgraph_telemetry.py
|
||||
src/agent_framework/observability/llm_advisors.py
|
||||
src/agent_framework/observability/noc_contract.py
|
||||
src/agent_framework/observability/noc_events.py
|
||||
src/agent_framework/observability/noc_otel.py
|
||||
src/agent_framework/observability/observer.py
|
||||
src/agent_framework/observability/otel.py
|
||||
src/agent_framework/observability/streaming_events.py
|
||||
|
||||
@@ -328,6 +328,10 @@ class LangfuseAnalyticsPublisher(AnalyticsPublisher):
|
||||
"parent_observation_id": body.get("parent_observation_id") or metadata.get("parent_observation_id") or _current_parent_observation_id(),
|
||||
})
|
||||
|
||||
# Keep correlation metadata on the trace, but do not turn every control
|
||||
# event code into a trace tag. IC/NOC/GRL are represented by the child
|
||||
# observation below; tags are not a substitute for the event span and
|
||||
# high-cardinality event-code tags make the trace harder to inspect.
|
||||
self._update_current_trace(langfuse_metadata)
|
||||
|
||||
# Prefer current/correlated observation API. For internal/technical events,
|
||||
@@ -349,7 +353,8 @@ class LangfuseAnalyticsPublisher(AnalyticsPublisher):
|
||||
_update_observation(observation, output={"published": True})
|
||||
return
|
||||
except Exception:
|
||||
logger.debug("Falha ao publicar Langfuse observation para %s", effective_event_type, exc_info=True)
|
||||
log = logger.warning if is_internal else logger.debug
|
||||
log("Falha ao publicar Langfuse observation para %s", effective_event_type, exc_info=True)
|
||||
if is_internal or is_technical:
|
||||
return
|
||||
|
||||
@@ -388,12 +393,6 @@ class LangfuseAnalyticsPublisher(AnalyticsPublisher):
|
||||
try:
|
||||
kwargs: dict[str, Any] = {
|
||||
"metadata": {k: v for k, v in metadata.items() if v is not None},
|
||||
"tags": [tag for tag, enabled in (
|
||||
("ic", metadata.get("ic")),
|
||||
("noc", metadata.get("noc")),
|
||||
("grl", metadata.get("grl")),
|
||||
(str(metadata.get("tag")), metadata.get("tag")),
|
||||
) if enabled],
|
||||
}
|
||||
session_id = metadata.get("sessionId") or metadata.get("session_id")
|
||||
if session_id:
|
||||
|
||||
@@ -41,6 +41,11 @@ class PubSubAnalyticsPublisher(AnalyticsPublisher):
|
||||
self.timeout_seconds = float(timeout_seconds or os.getenv("GCP_PUBSUB_TIMEOUT_SECONDS") or 30)
|
||||
self.payload_mode = (os.getenv("PUBSUB_PAYLOAD_MODE") or os.getenv("ANALYTICS_PUBSUB_PAYLOAD_MODE") or "flat").strip().lower()
|
||||
self.exclude_noc = (os.getenv("PUBSUB_EXCLUDE_NOC") or "true").strip().lower() in {"1", "true", "yes", "y", "on"}
|
||||
self.excluded_event_types = {
|
||||
item.strip().upper()
|
||||
for item in os.getenv("PUBSUB_EXCLUDED_EVENT_TYPES", "").split(",")
|
||||
if item.strip()
|
||||
}
|
||||
|
||||
from google.cloud import pubsub_v1 # type: ignore
|
||||
|
||||
@@ -72,6 +77,11 @@ class PubSubAnalyticsPublisher(AnalyticsPublisher):
|
||||
raise ValueError("Configure GCP_PUBSUB_TOPIC_PATH, AGENT_PUBSUB_TOPIC ou GCP_PROJECT_ID + GCP_PUBSUB_TOPIC")
|
||||
|
||||
async def publish(self, event_type: str, payload: dict[str, Any]) -> None:
|
||||
event_key = str(event_type).upper()
|
||||
if event_key in self.excluded_event_types:
|
||||
logger.debug("analytics.pubsub.skipped_event event_type=%s", event_type)
|
||||
return
|
||||
|
||||
metadata = payload.get("metadata") if isinstance(payload, dict) else None
|
||||
is_noc = str(event_type).startswith("NOC.") or (isinstance(metadata, dict) and metadata.get("noc") is True)
|
||||
if is_noc and self.exclude_noc:
|
||||
|
||||
@@ -35,7 +35,7 @@ class Settings(BaseSettings):
|
||||
# config_file = ~/.oci/config profile (default/local development)
|
||||
# instance_principal = OCI Instance Principal signer (Compute/OKE without API key)
|
||||
# resource_principal = OCI Resource Principal signer (Functions/resource principal contexts)
|
||||
OCI_AUTH_MODE: Literal['config_file','instance_principal','resource_principal'] = 'config_file'
|
||||
OCI_AUTH_MODE: Literal['config_file','instance_principal','resource_principal', 'oke_workload_identity'] = 'config_file'
|
||||
OCI_CONFIG_FILE: str = '~/.oci/config'
|
||||
OCI_PROFILE: str = 'DEFAULT'
|
||||
OCI_COMPARTMENT_ID: str | None = None
|
||||
|
||||
@@ -77,7 +77,10 @@ _COMPACT_SUPPRESSED_SPAN_PREFIXES = (
|
||||
"workflow.routing_decision",
|
||||
"workflow.supervisor_review",
|
||||
)
|
||||
_COMPACT_VISIBLE_EVENT_PREFIXES = ("AGA.", "NOC.")
|
||||
# Control events remain first-class observations even in compact mode. Compact
|
||||
# mode suppresses low-level workflow noise, but IC/NOC payloads are operational
|
||||
# evidence and must stay inspectable as child spans in Langfuse.
|
||||
_COMPACT_VISIBLE_EVENT_PREFIXES = ("IC.", "AGA.", "NOC.")
|
||||
|
||||
|
||||
def _raw_correlation_id(attrs: dict[str, Any] | None = None) -> str | None:
|
||||
|
||||
@@ -41,6 +41,13 @@ def get_oci_config_and_signer(settings: Any) -> tuple[dict[str, Any], Any | None
|
||||
logger.info("OCI auth resolved with resource principal region=%s", config.get("region"))
|
||||
return config, signer
|
||||
|
||||
if mode in {"oke_workload_identity", "oke_workload_identity"}:
|
||||
signer = oci.auth.signers.get_oke_workload_identity_resource_principal_signer()
|
||||
config = {"region": region or getattr(signer, "region", None)}
|
||||
logger.info("OCI auth resolved with OKE workload identity region=%s", config.get("region"))
|
||||
return config, signer
|
||||
|
||||
|
||||
raise ValueError(
|
||||
"Unsupported OCI_AUTH_MODE=%r. Use config_file, instance_principal or resource_principal." % mode
|
||||
"Unsupported OCI_AUTH_MODE=%r. Use config_file, instance_principal, resource_principal or oke_workload_identity." % mode
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user