Skip to content

Instantly share code, notes, and snippets.

@pavlovmilen
Created July 27, 2025 11:48
Show Gist options
  • Select an option

  • Save pavlovmilen/49b40ee0b529192a4c7acb8d5e27baf5 to your computer and use it in GitHub Desktop.

Select an option

Save pavlovmilen/49b40ee0b529192a4c7acb8d5e27baf5 to your computer and use it in GitHub Desktop.
Jaeger Service
import subprocess
import time
import socket
import logging
import os
logger = logging.getLogger(__name__)
class JaegerService:
"""Manages local Jaeger container for development"""
def __init__(self):
self.container_name = "jaeger-local"
self.image = "jaegertracing/all-in-one:latest"
self.ports = {
"16686": "16686", # UI
"4317": "4317", # OTLP gRPC
"4318": "4318" # OTLP HTTP
}
def is_port_available(self, port):
"""Check if a port is available"""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex(('localhost', port)) != 0
def is_container_running(self):
"""Check if Jaeger container is already running"""
try:
result = subprocess.run(
["docker", "ps", "--format", "{{.Names}}"],
capture_output=True, text=True, check=True
)
return self.container_name in result.stdout
except subprocess.CalledProcessError:
return False
def start_jaeger(self):
"""Start Jaeger container if not already running"""
if self.is_container_running():
logger.info(f"Jaeger container '{self.container_name}' is already running")
return True
for port in ["16686", "4317", "4318"]:
if not self.is_port_available(int(port)):
logger.warning(f"Port {port} is already in use, skipping Jaeger startup")
return False
try:
subprocess.run(
["docker", "rm", "-f", self.container_name],
capture_output=True, check=False
)
cmd = [
"docker", "run", "-d",
"--name", self.container_name,
"-e", "COLLECTOR_OTLP_ENABLED=true",
"-p", f"{self.ports['16686']}:16686",
"-p", f"{self.ports['4317']}:4317",
"-p", f"{self.ports['4318']}:4318",
self.image
]
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
logger.info(f"Started Jaeger container: {result.stdout.strip()}")
time.sleep(2)
if self.is_container_running():
logger.info("Jaeger is available at:")
logger.info(f" UI: http://localhost:{self.ports['16686']}")
logger.info(f" OTLP gRPC: localhost:{self.ports['4317']}")
logger.info(f" OTLP HTTP: localhost:{self.ports['4318']}")
return True
else:
logger.error("Jaeger container failed to start properly")
return False
except subprocess.CalledProcessError as e:
logger.error(f"Failed to start Jaeger: {e.stderr}")
return False
except FileNotFoundError:
logger.warning("Docker not found - Jaeger will not be started locally")
return False
def stop_jaeger(self):
"""Stop and remove Jaeger container"""
try:
subprocess.run(
["docker", "stop", self.container_name],
capture_output=True, check=True
)
subprocess.run(
["docker", "rm", self.container_name],
capture_output=True, check=True
)
logger.info(f"Stopped Jaeger container '{self.container_name}'")
return True
except subprocess.CalledProcessError:
logger.warning(f"Failed to stop Jaeger container '{self.container_name}'")
return False
def start_local_jaeger():
"""Convenience function to start Jaeger locally"""
if os.getenv('KUBERNETES_SERVICE_HOST') is None:
jaeger = JaegerService()
return jaeger.start_jaeger()
return False
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment