Configuration
Tracing & Telemetry

Tracing & Telemetry

dealcloud-sdk does not embed OpenTelemetry APIs. It performs HTTP through HTTPX (via intapp-rest-client), so you enable distributed tracing by installing OpenTelemetry and instrumenting HTTPX—then every RestClient request from the SDK can emit spans. That gives you visibility into API calls, latency, and errors.

📊

How it works: opentelemetry-instrumentation-httpx patches HTTPX. Configure a tracer provider and exporters in your process, call HTTPXClientInstrumentation().instrument() before you construct DealCloud, then use the SDK as usual.

⚠️

dealcloud-sdk[telemetry] only installs dependencies (opentelemetry-sdk and opentelemetry-instrumentation-httpx). It does not enable tracing by itself—you still need the setup code in Basic Setup. For a full install of all optional extras, use dealcloud-sdk[all] (includes telemetry).

Quick Start

Installation

Use the telemetry optional extra to pull the same OpenTelemetry packages the docs use, or install them by name.

pip install "dealcloud-sdk[telemetry]"

Production exporters (e.g. OTLP, Jaeger) are not included in the telemetry extra—add opentelemetry-exporter-otlp or the exporter you need separately.

Basic Setup

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, BatchSpanProcessor
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentation
 
# 1. Set up tracer provider
trace.set_tracer_provider(TracerProvider())
 
# 2. Add span processor (console output for demo)
trace.get_tracer_provider().add_span_processor(
    BatchSpanProcessor(ConsoleSpanExporter())
)
 
# 3. Instrument HTTPX (used by DealCloud SDK)
HTTPXClientInstrumentation().instrument()
 
# 4. Create SDK client normally
from dealcloud_sdk import DealCloud, DealCloudConfig
 
config = DealCloudConfig(
    siteUrl="yoursite.dealcloud.com",
    clientId=12345,
    clientSecret="your-secret",
)
dc = DealCloud.from_config_object(config)
 
# All HTTP calls are now traced
data = dc.read_data("Company", output="pandas")

Production Configuration

Export to Jaeger

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentation
 
# Configure Jaeger exporter
jaeger_exporter = JaegerExporter(
    agent_host_name="jaeger.internal",
    agent_port=6831,
)
 
# Set up provider with Jaeger
provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(jaeger_exporter))
trace.set_tracer_provider(provider)
 
# Instrument HTTPX
HTTPXClientInstrumentation().instrument()

Export to OTLP (OpenTelemetry Collector)

Install an OTLP exporter package, for example:

pip install opentelemetry-exporter-otlp
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentation
 
# Configure OTLP exporter
otlp_exporter = OTLPSpanExporter(
    endpoint="http://otel-collector:4317",
    insecure=True  # Use False with TLS
)
 
# Set up provider
provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(otlp_exporter))
trace.set_tracer_provider(provider)
 
# Instrument HTTPX
HTTPXClientInstrumentation().instrument()

Adding Custom Spans

Create additional spans for application-level tracing:

from opentelemetry import trace
from dealcloud_sdk import DealCloud, DealCloudConfig
 
tracer = trace.get_tracer("my-app")
config = DealCloudConfig(
    siteUrl="yoursite.dealcloud.com",
    clientId=12345,
    clientSecret="your-secret",
)
dc = DealCloud.from_config_object(config)
 
def sync_companies():
    with tracer.start_as_current_span("sync_companies") as span:
        span.set_attribute("operation", "full_sync")
        
        # This will create child spans for HTTP calls
        companies = dc.read_data("Company", output="list")
        
        span.set_attribute("company_count", len(companies))
        
        for company in companies:
            with tracer.start_as_current_span("process_company") as child:
                child.set_attribute("entry_id", company["EntryId"])
                process_company(company)

Span Attributes

The HTTPX instrumentation automatically captures:

AttributeExampleDescription
http.methodGET, POSTHTTP method
http.urlhttps://site.dealcloud.com/...Full URL
http.status_code200, 429Response status
http.request_content_length1234Request body size
http.response_content_length56789Response body size

Application metrics (OpenTelemetry)

The SDK does not emit built-in OpenTelemetry metrics. You can record your own business or sync metrics with the OpenTelemetry Metrics API—for example, counting rows after read_data:

from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import ConsoleMetricExporter, PeriodicExportingMetricReader
 
# Set up metrics pipeline (your application)
reader = PeriodicExportingMetricReader(ConsoleMetricExporter())
provider = MeterProvider(metric_readers=[reader])
metrics.set_meter_provider(provider)
 
meter = metrics.get_meter("dealcloud-sync")
 
records_synced = meter.create_counter(
    "records_synced",
    description="Number of records synchronized"
)
 
# Example: increment after a read
from dealcloud_sdk import DealCloud, DealCloudConfig
 
config = DealCloudConfig(
    siteUrl="yoursite.dealcloud.com",
    clientId=12345,
    clientSecret="your-secret",
)
dc = DealCloud.from_config_object(config)
companies = dc.read_data("Company", output="list")
records_synced.add(len(companies), {"object": "Company"})

Trace Context Propagation

For distributed systems, propagate trace context:

from opentelemetry import trace
from opentelemetry.propagate import inject, extract
 
# Inject context into outgoing requests (automatic with HTTPX instrumentation)
 
# Extract context from incoming requests (e.g., in a web framework)
from flask import request
from dealcloud_sdk import DealCloud, DealCloudConfig
 
@app.route("/sync")
def sync_endpoint():
    # Extract trace context from incoming request
    ctx = extract(request.headers)
    
    with trace.get_tracer("my-app").start_as_current_span(
        "handle_sync", 
        context=ctx
    ):
        config = DealCloudConfig(
            siteUrl="yoursite.dealcloud.com",
            clientId=12345,
            clientSecret="your-secret",
        )
        dc = DealCloud.from_config_object(config)
        # This span will be linked to the incoming trace
        return dc.read_data("Company", output="list")

Configuration via Environment

Configure OpenTelemetry via environment variables:

# Service name
export OTEL_SERVICE_NAME=dealcloud-integration
 
# OTLP endpoint
export OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4317
 
# Sampling (1.0 = 100%, 0.1 = 10%)
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.1

Disabling Tracing

To disable tracing in specific environments:

import os
 
if os.getenv("ENVIRONMENT") == "development":
    # Skip instrumentation
    pass
else:
    from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentation
    HTTPXClientInstrumentation().instrument()

Troubleshooting

No Spans Appearing

  1. Verify instrumentation is called before creating DealCloud client
  2. Check exporter configuration (endpoint, network access)
  3. Enable debug logging:
import logging
logging.getLogger("opentelemetry").setLevel(logging.DEBUG)

Missing HTTP Details

Ensure you're using the HTTPX instrumentation, not requests:

# Correct - instruments the SDK's HTTP client
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentation
HTTPXClientInstrumentation().instrument()
 
# Wrong - won't capture SDK calls
from opentelemetry.instrumentation.requests import RequestsInstrumentation

Related Resources