Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion agentex/src/temporal/run_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,37 @@
# Task queue name for agentex server operations
AGENTEX_SERVER_TASK_QUEUE = "agentex-server"


OTLP_METRICS_DEFAULT_PORT = 4317


def build_metrics_url(host_url: str | None) -> str | None:
"""Build the OTLP metrics endpoint URL from a ``host`` or ``host:port`` value.

Accepts a bare hostname/IPv4, an IPv6 literal (bracketed or not), or any of
those with an explicit ``:port`` suffix. Per RFC 3986 only IPv6 literals are
wrapped in brackets, and the default OTLP gRPC port is appended only when the
value does not already carry one. Returns None when no host is configured.
"""
if not host_url:
return None

host = host_url.strip()
port: str | None = None

if host.startswith("["):
bracket_end = host.find("]")
if bracket_end != -1:
rest = host[bracket_end + 1 :]
port = rest[1:] if rest.startswith(":") else None
host = host[1:bracket_end]
elif host.count(":") == 1:
host, port = host.split(":", 1)

bracketed = f"[{host}]" if ":" in host else host
return f"http://{bracketed}:{port or OTLP_METRICS_DEFAULT_PORT}"


# Global worker instance
health_check_worker: Worker | None = None

Expand Down Expand Up @@ -84,7 +115,7 @@ async def run_worker(

# Check for metrics configuration
host_url = os.environ.get("DD_AGENT_HOST")
metrics_url = f"http://[{host_url}]:4317" if host_url else None
metrics_url = build_metrics_url(host_url)
if metrics_url:
logger.info(f"Configuring worker with metrics URL: {metrics_url}")

Expand Down
49 changes: 49 additions & 0 deletions agentex/tests/unit/temporal/test_run_worker_metrics_url.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import pytest
from src.temporal.run_worker import build_metrics_url


@pytest.mark.unit
def test_metrics_url_is_none_when_host_unset():
assert build_metrics_url(None) is None
assert build_metrics_url("") is None


@pytest.mark.unit
@pytest.mark.parametrize("host", ["localhost", "datadog-agent", "10.0.0.5"])
def test_hostname_and_ipv4_are_not_bracketed(host):
assert build_metrics_url(host) == f"http://{host}:4317"


@pytest.mark.unit
@pytest.mark.parametrize(
"host,expected",
[("::1", "http://[::1]:4317"), ("fe80::1", "http://[fe80::1]:4317")],
)
def test_ipv6_literal_is_bracketed(host, expected):
assert build_metrics_url(host) == expected


@pytest.mark.unit
@pytest.mark.parametrize(
"host,expected",
[
("datadog-agent:4317", "http://datadog-agent:4317"),
("10.0.0.5:4317", "http://10.0.0.5:4317"),
("datadog-agent:5555", "http://datadog-agent:5555"),
],
)
def test_hostname_with_explicit_port_is_not_bracketed(host, expected):
assert build_metrics_url(host) == expected


@pytest.mark.unit
@pytest.mark.parametrize(
"host,expected",
[
("[::1]", "http://[::1]:4317"),
("[fe80::1]", "http://[fe80::1]:4317"),
("[::1]:5555", "http://[::1]:5555"),
],
)
def test_already_bracketed_ipv6_literal(host, expected):
assert build_metrics_url(host) == expected