{"slug": "temporal-observability-monitoring-with-opentelemetry", "title": "Temporal Observability & Monitoring with OpenTelemetry", "summary": "SigNoz has released a guide for instrumenting Temporal workflow executions and AI agent patterns with OpenTelemetry, enabling real-time visibility through traces, logs, and metrics. The integration allows developers to monitor workflow activity, debug agent execution, and set alerts for failures or high latency from a single SigNoz dashboard. The setup requires Python 3.10+, a SigNoz account or self-hosted instance, and installation of OpenTelemetry and Temporal packages for automatic instrumentation.", "body_md": "What is Temporal Observability?\n\nTemporal observability gives you real-time visibility into your workflow executions and AI agent patterns by collecting traces, logs, and metrics using [OpenTelemetry](https://opentelemetry.io/). This guide shows you how to instrument your Temporal-based applications and send telemetry to SigNoz, so you can monitor workflow activity, debug agent execution, and optimize performance end-to-end.\n\nWith full Temporal observability in SigNoz, you can correlate traces, logs, and metrics in a single dashboard, set up alerts for workflow failures or high latency, and analyze agent execution patterns over time to continuously improve reliability and efficiency.\n\nPrerequisites\n\n- A\n[SigNoz Cloud account](https://signoz.io/teams/)with an active ingestion key or[Self Hosted SigNoz instance](https://signoz.io/docs/install/self-host/) - Internet access to send telemetry data to SigNoz Cloud\n- Python 3.10+ with\n`temporalio`\n\ninstalled - For Python:\n`pip`\n\ninstalled for managing Python packages\n\nMonitor Temporal Workflows with OpenTelemetry\n\nNo code auto-instrumentation is recommended for quick setup with minimal code changes. It's ideal when you want to get observability up and running without modifying your application code and are leveraging standard instrumentor libraries. For more information on getting started with Temporal in your Python environment, refer to the [Temporal Python Setup Guide](https://docs.temporal.io/develop/python/set-up-your-local-python)\n\nStep 1: Install the necessary packages in your Python environment.\n\n```\npip install \\\n  opentelemetry-distro \\\n  opentelemetry-exporter-otlp \\\n  httpx \\\n  opentelemetry-instrumentation-httpx \\\n  opentelemetry-instrumentation-system-metrics \\\n  temporalio \\\n  openinference-instrumentation-openai-agents \\\n  openai \\\n  openai-agents\n```\n\nStep 2: Add Automatic Instrumentation\n\n```\nopentelemetry-bootstrap --action=install\n```\n\nStep 3: Set up environment variables\n\nCreate a `.env`\n\nfile in your project root and add the following environment variables based on your Temporal deployment:\n\n```\nOPENAI_API_KEY=<your-openai-api-key>\nTEMPORAL_ADDRESS=<local-temporal-server>\n```\n\nis the location where your local Temporal server is hosted(default:`<local-temporal-server>`\n\n`localhost:7233`\n\n)\n\n```\nOPENAI_API_KEY=<your-openai-api-key>\nTEMPORAL_ADDRESS=<your-temporal-cloud-address>\nTEMPORAL_NAMESPACE=<your-temporal-namespace-name>\nTEMPORAL_API_KEY=<your-temporal-api-key>\nTEMPORAL_TLS=true\n```\n\nStep 4: Create an example Temporal agent workflow\n\n``` python\nfrom __future__ import annotations\nfrom dotenv import load_dotenv\nimport asyncio\nimport os\nfrom temporalio import workflow\nfrom temporalio.client import Client\nfrom temporalio.worker import Worker\nfrom temporalio.contrib.openai_agents import OpenAIAgentsPlugin\nfrom temporalio.worker import UnsandboxedWorkflowRunner\nfrom agents import Agent, Runner\n\nload_dotenv()\n\n@workflow.defn\nclass HelloWorldAgent:\n    @workflow.run\n    async def run(self, prompt: str) -> str:\n        agent = Agent(\n            name=\"Assistant\",\n            model=\"gpt-5\",\n            instructions=\"You only respond in haikus.\",\n        )\n\n        result = await Runner.run(agent, input=prompt)\n        return result.final_output\n\nasync def main():\n    tls = os.environ.get(\"TEMPORAL_TLS\", \"\").lower() in (\"1\", \"true\", \"yes\")\n    api_key = os.environ.get(\"TEMPORAL_API_KEY\")\n\n    plugin = OpenAIAgentsPlugin()\n\n    client = await Client.connect(\n        target_host=os.environ.get(\"TEMPORAL_ADDRESS\", \"localhost:7233\"),\n        namespace=os.environ.get(\"TEMPORAL_NAMESPACE\", \"default\"),\n        api_key=api_key or None,\n        tls=tls,\n        plugins=[plugin]\n    )\n\n    worker = Worker(\n        client,\n        task_queue=os.environ.get(\"TEMPORAL_TASK_QUEUE\", \"openai-agents-task-queue\"),\n        workflows=[HelloWorldAgent],\n        workflow_runner=UnsandboxedWorkflowRunner()\n    )\n\n    async with worker:\n        handle = await client.start_workflow(\n            HelloWorldAgent.run,\n            id=\"hello-world-workflow-01\",\n            task_queue=os.environ.get(\"TEMPORAL_TASK_QUEUE\", \"openai-agents-task-queue\"),\n            args=[\"Tell me about SigNoz\"],\n        )\n        result = await handle.result()\n        print(\"\\nWorkflow result:\\n\", result)\n\nasyncio.run(main())\n```\n\nStep 5: Run your application with auto-instrumentation\n\nRun your application with the following environment variables set. This configures OpenTelemetry to export traces, logs, and metrics to SigNoz Cloud and enables automatic log correlation:\n\n```\nOTEL_RESOURCE_ATTRIBUTES=\"service.name=<service_name>\" \\\nOTEL_EXPORTER_OTLP_ENDPOINT=\"https://ingest.<region>.signoz.cloud:443\" \\\nOTEL_EXPORTER_OTLP_HEADERS=\"signoz-ingestion-key=<your-ingestion-key>\" \\\nOTEL_EXPORTER_OTLP_PROTOCOL=grpc \\\nOTEL_TRACES_EXPORTER=otlp \\\nOTEL_METRICS_EXPORTER=otlp \\\nOTEL_LOGS_EXPORTER=otlp \\\nOTEL_PYTHON_LOG_CORRELATION=true \\\nOTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true \\\nopentelemetry-instrument <your_run_command>\n```\n\nis the name of your service`<service_name>`\n\n`<region>`\n\n: Your[SigNoz Cloud region](https://signoz.io/docs/ingestion/signoz-cloud/overview/#endpoint)`<your-ingestion-key>`\n\n: Your SigNoz[ingestion key](https://signoz.io/docs/ingestion/signoz-cloud/keys/)- Replace\n`<your_run_command>`\n\nwith the actual command you would use to run your application. In this case we would use:`python main.py`\n\nUsing self-hosted SigNoz? Most steps are identical. To adapt this guide, update the endpoint and remove the ingestion key header as shown in [Cloud → Self-Hosted](https://signoz.io/docs/ingestion/cloud-vs-self-hosted#cloud-to-self-hosted).\n\nCode-based manual instrumentation gives you fine-grained control over your telemetry configuration. Use this approach when you need to customize resource attributes, sampling strategies, or integrate with existing observability infrastructure.\n\nStep 1: Install additional OpenTelemetry dependencies\n\n```\npip install \\\n  opentelemetry-api \\\n  opentelemetry-sdk \\\n  opentelemetry-exporter-otlp \\\n  opentelemetry-instrumentation-httpx \\\n  opentelemetry-instrumentation-system-metrics \\\n  temporalio \\\n  openinference-instrumentation-openai-agents\n```\n\nStep 2: Import the necessary modules in your Python application\n\n**Traces:**\n\n``` python\nfrom opentelemetry import trace\nfrom opentelemetry.sdk.resources import Resource\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import BatchSpanProcessor\nfrom opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter\n```\n\n**Logs:**\n\n``` python\nfrom opentelemetry.sdk._logs import LoggerProvider, LoggingHandler\nfrom opentelemetry.sdk._logs.export import BatchLogRecordProcessor\nfrom opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter\nfrom opentelemetry._logs import set_logger_provider\nimport logging\n```\n\n**Metrics:**\n\n``` python\nfrom opentelemetry.sdk.metrics import MeterProvider\nfrom opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter\nfrom opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader\nfrom opentelemetry import metrics\nfrom opentelemetry.instrumentation.system_metrics import SystemMetricsInstrumentor\nfrom opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor\n```\n\nStep 3: Set up the OpenTelemetry Tracer Provider to send traces directly to SigNoz Cloud\n\n``` python\nfrom opentelemetry.sdk.resources import Resource\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import BatchSpanProcessor\nfrom opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter\nfrom opentelemetry import trace\nimport os\n\nfrom openinference.instrumentation.openai_agents import OpenAIAgentsInstrumentor\n\nresource = Resource.create({\"service.name\": \"<service_name>\"})\nprovider = TracerProvider(resource=resource)\nspan_exporter = OTLPSpanExporter(\n    endpoint= os.getenv(\"OTEL_EXPORTER_TRACES_ENDPOINT\"),\n    headers={\"signoz-ingestion-key\": os.getenv(\"SIGNOZ_INGESTION_KEY\")},\n)\nprocessor = BatchSpanProcessor(span_exporter)\nprovider.add_span_processor(processor)\ntrace.set_tracer_provider(provider)\n\n# Start instrumenting Temporal Agents\nOpenAIAgentsInstrumentor().instrument()\n```\n\nis the name of your service`<service_name>`\n\n→ SigNoz Cloud trace endpoint with appropriate`OTEL_EXPORTER_TRACES_ENDPOINT`\n\n[region](https://signoz.io/docs/ingestion/signoz-cloud/overview/#endpoint):`https://ingest.<region>.signoz.cloud:443/v1/traces`\n\n→ Your SigNoz`SIGNOZ_INGESTION_KEY`\n\n[ingestion key](https://signoz.io/docs/ingestion/signoz-cloud/keys/)\n\nUsing self-hosted SigNoz? Most steps are identical. To adapt this guide, update the endpoint and remove the ingestion key header as shown in [Cloud → Self-Hosted](https://signoz.io/docs/ingestion/cloud-vs-self-hosted#cloud-to-self-hosted).\n\nStep 4: Setup Logs\n\n``` python\nimport logging\nfrom opentelemetry.sdk.resources import Resource\nfrom opentelemetry._logs import set_logger_provider\nfrom opentelemetry.sdk._logs import LoggerProvider, LoggingHandler\nfrom opentelemetry.sdk._logs.export import BatchLogRecordProcessor\nfrom opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter\nimport os\n\nresource = Resource.create({\"service.name\": \"<service_name>\"})\nlogger_provider = LoggerProvider(resource=resource)\nset_logger_provider(logger_provider)\n\notlp_log_exporter = OTLPLogExporter(\n    endpoint= os.getenv(\"OTEL_EXPORTER_LOGS_ENDPOINT\"),\n    headers={\"signoz-ingestion-key\": os.getenv(\"SIGNOZ_INGESTION_KEY\")},\n)\nlogger_provider.add_log_record_processor(\n    BatchLogRecordProcessor(otlp_log_exporter)\n)\n# Attach OTel logging handler to root logger\nhandler = LoggingHandler(level=logging.INFO, logger_provider=logger_provider)\nlogging.basicConfig(level=logging.INFO, handlers=[handler])\n\nlogger = logging.getLogger(__name__)\n```\n\nis the name of your service`<service_name>`\n\n→ SigNoz Cloud endpoint with appropriate`OTEL_EXPORTER_LOGS_ENDPOINT`\n\n[region](https://signoz.io/docs/ingestion/signoz-cloud/overview/#endpoint):`https://ingest.<region>.signoz.cloud:443/v1/logs`\n\n→ Your SigNoz`SIGNOZ_INGESTION_KEY`\n\n[ingestion key](https://signoz.io/docs/ingestion/signoz-cloud/keys/)\n\nUsing self-hosted SigNoz? Most steps are identical. To adapt this guide, update the endpoint and remove the ingestion key header as shown in [Cloud → Self-Hosted](https://signoz.io/docs/ingestion/cloud-vs-self-hosted#cloud-to-self-hosted).\n\nStep 5: Setup Metrics\n\n``` python\nfrom opentelemetry.sdk.resources import Resource\nfrom opentelemetry.sdk.metrics import MeterProvider\nfrom opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter\nfrom opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader\nfrom opentelemetry import metrics\nfrom opentelemetry.instrumentation.system_metrics import SystemMetricsInstrumentor\nimport os\n\nresource = Resource.create({\"service.name\": \"<service-name>\"})\nmetric_exporter = OTLPMetricExporter(\n    endpoint= os.getenv(\"OTEL_EXPORTER_METRICS_ENDPOINT\"),\n    headers={\"signoz-ingestion-key\": os.getenv(\"SIGNOZ_INGESTION_KEY\")},\n)\nreader = PeriodicExportingMetricReader(metric_exporter)\nmetric_provider = MeterProvider(metric_readers=[reader], resource=resource)\nmetrics.set_meter_provider(metric_provider)\n\nmeter = metrics.get_meter(__name__)\n\n# turn on out-of-the-box metrics\nSystemMetricsInstrumentor().instrument()\nHTTPXClientInstrumentor().instrument()\n```\n\nis the name of your service`<service_name>`\n\n→ SigNoz Cloud endpoint with appropriate`OTEL_EXPORTER_METRICS_ENDPOINT`\n\n[region](https://signoz.io/docs/ingestion/signoz-cloud/overview/#endpoint):`https://ingest.<region>.signoz.cloud:443/v1/metrics`\n\n→ Your SigNoz`SIGNOZ_INGESTION_KEY`\n\n[ingestion key](https://signoz.io/docs/ingestion/signoz-cloud/keys/)\n\nUsing self-hosted SigNoz? Most steps are identical. To adapt this guide, update the endpoint and remove the ingestion key header as shown in [Cloud → Self-Hosted](https://signoz.io/docs/ingestion/cloud-vs-self-hosted#cloud-to-self-hosted).\n\n📌 Note: SystemMetricsInstrumentor provides system metrics (CPU, memory, etc.), and HTTPXClientInstrumentor provides outbound HTTP request metrics such as request duration. If you want to add custom metrics to your Temporal application, see\n\n[Python Custom Metrics].\n\nStep 6: Set up environment variables\n\nCreate a `.env`\n\nfile in your project root and add the following environment variables based on your Temporal deployment:\n\n```\nOPENAI_API_KEY=<your-openai-api-key>\nTEMPORAL_ADDRESS=<local-temporal-server>\n```\n\nis the location where your local Temporal server is hosted(default:`<local-temporal-server>`\n\n`localhost:7233`\n\n)\n\n```\nOPENAI_API_KEY=<your-openai-api-key>\nTEMPORAL_ADDRESS=<your-temporal-cloud-address>\nTEMPORAL_NAMESPACE=<your-temporal-namespace-name>\nTEMPORAL_API_KEY=<your-temporal-api-key>\nTEMPORAL_TLS=true\n```\n\nStep 7: Run an example Temporal agent workflow\n\nEnsure you have completed the steps above (traces, logs, and metrics configuration) before running this code. All OpenTelemetry instrumentation must be initialized first.\n\n``` python\nfrom __future__ import annotations\nfrom dotenv import load_dotenv\nimport asyncio\nimport os\nfrom temporalio import workflow\nfrom temporalio.client import Client\nfrom temporalio.worker import Worker\nfrom temporalio.contrib.openai_agents import OpenAIAgentsPlugin\nfrom temporalio.worker import UnsandboxedWorkflowRunner\nfrom agents import Agent, Runner\n\nload_dotenv()\n\n@workflow.defn\nclass HelloWorldAgent:\n    @workflow.run\n    async def run(self, prompt: str) -> str:\n        agent = Agent(\n            name=\"Assistant\",\n            model=\"gpt-5\",\n            instructions=\"You only respond in haikus.\",\n        )\n\n        result = await Runner.run(agent, input=prompt)\n        return result.final_output\n\nasync def main():\n    tls = os.environ.get(\"TEMPORAL_TLS\", \"\").lower() in (\"1\", \"true\", \"yes\")\n    api_key = os.environ.get(\"TEMPORAL_API_KEY\")\n\n    plugin = OpenAIAgentsPlugin()\n\n    client = await Client.connect(\n        target_host=os.environ.get(\"TEMPORAL_ADDRESS\", \"localhost:7233\"),\n        namespace=os.environ.get(\"TEMPORAL_NAMESPACE\", \"default\"),\n        api_key=api_key or None,\n        tls=tls,\n        plugins=[plugin]\n    )\n\n    worker = Worker(\n        client,\n        task_queue=os.environ.get(\"TEMPORAL_TASK_QUEUE\", \"openai-agents-task-queue\"),\n        workflows=[HelloWorldAgent],\n        workflow_runner=UnsandboxedWorkflowRunner()\n    )\n\n    async with worker:\n        handle = await client.start_workflow(\n            HelloWorldAgent.run,\n            id=\"hello-world-workflow-01\",\n            task_queue=os.environ.get(\"TEMPORAL_TASK_QUEUE\", \"openai-agents-task-queue\"),\n            args=[\"Tell me about SigNoz\"],\n        )\n        result = await handle.result()\n        print(\"\\nWorkflow result:\\n\", result)\n\nasyncio.run(main())\n```\n\nBefore running this code, ensure that you have set the environment variable `OPENAI_API_KEY`\n\nwith your generated API key.\n\nView Temporal Traces, Logs, and Metrics in SigNoz\n\nOnce configured, your Temporal application automatically emits traces, logs, and metrics.\n\nTemporal traces are available in SigNoz under the Traces tab:\n\nWhen you click on a trace in SigNoz, you'll see a detailed view of the trace, including all associated spans, along with their events and attributes.\n\nTemporal logs are available in SigNoz under the Logs tab. Click the Related Logs button in the trace view to see correlated logs:\n\nWhen you click on any of these logs in SigNoz, you'll see a detailed view of the log, including attributes:\n\nTemporal metrics are available in SigNoz under the Metrics tab:\n\nWhen you click on any of these metrics in SigNoz, you'll see a detailed view of the metric, including attributes:\n\nIf you're using Temporal Cloud, you can also monitor cloud-specific metrics. For detailed information on setting up Temporal Cloud metrics monitoring, see the [Temporal Cloud Metrics integration guide](https://signoz.io/docs/integrations/temporal-cloud-metrics/).\n\nTemporal Cloud metrics are available in SigNoz under the Metrics tab:\n\nWhen you click on any of these Temporal Cloud metrics in SigNoz, you'll see a detailed view of the metric, including attributes:\n\nTroubleshooting Temporal Observability\n\n[Troubleshooting Temporal Observability](#troubleshooting-temporal-observability)\n\nIf you don't see your telemetry data:\n\n**Verify network connectivity**- Ensure your application can reach SigNoz Cloud endpoints** Check ingestion key**- Verify your SigNoz ingestion key is correct** Wait for data**- OpenTelemetry batches data before sending, so wait 10-30 seconds after making API calls** Try a console exporter**- Enable a console exporter locally to confirm that your application is generating telemetry data before it’s sent to SigNoz\n\nTemporal Observability Dashboard\n\nThe [Temporal dashboard template](https://signoz.io/docs/dashboards/dashboard-templates/temporal-dashboard/) provides pre-built visualizations for monitoring Temporal workflow performance, agent execution patterns, and resource usage in SigNoz. Import it directly to get started without manual chart configuration.\n\nAdditional resources:\n\n- Set up\n[alerts](https://signoz.io/docs/product-features/alert-management)for high latency or error rates - Learn more about\n[querying traces](https://signoz.io/docs/product-features/trace-explorer) - Explore\n[log correlation](https://signoz.io/docs/product-features/logs-explorer)", "url": "https://wpnews.pro/news/temporal-observability-monitoring-with-opentelemetry", "canonical_source": "https://signoz.io/docs/temporal-observability", "published_at": "2026-05-27 00:00:00+00:00", "updated_at": "2026-05-29 16:26:11.355173+00:00", "lang": "en", "topics": ["ai-infrastructure", "ai-tools", "ai-agents", "mlops"], "entities": ["Temporal", "OpenTelemetry", "SigNoz", "SigNoz Cloud"], "alternates": {"html": "https://wpnews.pro/news/temporal-observability-monitoring-with-opentelemetry", "markdown": "https://wpnews.pro/news/temporal-observability-monitoring-with-opentelemetry.md", "text": "https://wpnews.pro/news/temporal-observability-monitoring-with-opentelemetry.txt", "jsonld": "https://wpnews.pro/news/temporal-observability-monitoring-with-opentelemetry.jsonld"}}