Imporve monitoring 5

This commit is contained in:
Urtzi Alfaro
2026-01-09 23:14:12 +01:00
parent 22dab143ba
commit c05538cafb
23 changed files with 4737 additions and 1932 deletions

View File

@@ -1,6 +1,6 @@
"""
OpenTelemetry Logs Integration for SigNoz
Exports structured logs to SigNoz via OpenTelemetry Collector
Exports structured logs to SigNoz via OpenTelemetry Collector using HTTP protocol
"""
import os
@@ -10,14 +10,21 @@ from typing import Optional
from opentelemetry._logs import set_logger_provider
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.resources import Resource
# Try to import HTTP log exporter (logs always use HTTP)
try:
from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
HTTP_LOG_EXPORTER_AVAILABLE = True
except ImportError:
try:
from opentelemetry.exporter.otlp.proto.http.log_exporter import OTLPLogExporter
HTTP_LOG_EXPORTER_AVAILABLE = True
except ImportError:
OTLPLogExporter = None
from opentelemetry.sdk.resources import Resource, SERVICE_NAME, SERVICE_VERSION
HTTP_LOG_EXPORTER_AVAILABLE = False
from .otel_config import OTelConfig
logger = structlog.get_logger()
@@ -31,13 +38,14 @@ def setup_otel_logging(
"""
Setup OpenTelemetry logging to export logs to SigNoz.
This integrates with Python's standard logging to automatically
export all log records to SigNoz via the OTLP protocol.
Uses HTTP protocol (port 4318) for sending logs to SigNoz.
Integrates with Python's standard logging to automatically export
all log records to SigNoz via the OTLP HTTP protocol.
Args:
service_name: Name of the service (e.g., "auth-service")
service_version: Version of the service
otel_endpoint: OpenTelemetry collector endpoint (default from env)
otel_endpoint: Optional override for OTLP endpoint (HTTP format with path)
enable_console: Whether to also log to console (default: True)
Returns:
@@ -47,7 +55,7 @@ def setup_otel_logging(
from shared.monitoring.logs_exporter import setup_otel_logging
# Setup during service initialization
setup_otel_logging("auth-service", "1.0.0")
handler = setup_otel_logging("auth-service", "1.0.0")
# Now all standard logging calls will be exported to SigNoz
import logging
@@ -56,7 +64,7 @@ def setup_otel_logging(
"""
# Check if logging export is enabled
if os.getenv("OTEL_LOGS_EXPORTER", "").lower() != "otlp":
if not OTelConfig.is_enabled("logs"):
logger.info(
"OpenTelemetry logs export disabled",
service=service_name,
@@ -64,59 +72,36 @@ def setup_otel_logging(
)
return None
# Get OTLP endpoint from environment or parameter
# For logs, we need to use the HTTP endpoint (port 4318), not the gRPC endpoint (port 4317)
if otel_endpoint is None:
# Try logs-specific endpoint first, then fall back to general OTLP endpoint
otel_endpoint = os.getenv(
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT",
os.getenv("OTEL_COLLECTOR_ENDPOINT", "http://signoz-otel-collector.bakery-ia:4318")
# Check if HTTP log exporter is available
if not HTTP_LOG_EXPORTER_AVAILABLE or OTLPLogExporter is None:
logger.warning(
"OpenTelemetry HTTP log exporter not available",
service=service_name,
reason="opentelemetry-exporter-otlp-proto-http package not installed"
)
logger.info(f"Original OTLP endpoint for logs: {otel_endpoint}")
# If we got the tracing endpoint (4317), switch to logs endpoint (4318)
if otel_endpoint.endswith(":4317"):
logger.info("Converting tracing endpoint (4317) to logs endpoint (4318)")
otel_endpoint = otel_endpoint.replace(":4317", ":4318")
logger.info(f"Final OTLP endpoint for logs: {otel_endpoint}")
# Ensure endpoint has proper protocol prefix
if not otel_endpoint.startswith(("http://", "https://")):
# Default to HTTP for insecure connections
otel_endpoint = f"http://{otel_endpoint}"
# Ensure endpoint has /v1/logs path for HTTP
if not otel_endpoint.endswith("/v1/logs"):
otel_endpoint = f"{otel_endpoint}/v1/logs"
return None
try:
# Check if OTLPLogExporter is available
if OTLPLogExporter is None:
logger.warning(
"OpenTelemetry HTTP OTLP exporter not available",
service=service_name,
reason="opentelemetry-exporter-otlp-proto-http package not installed"
)
return None
# Get endpoints from centralized config
endpoints = OTelConfig.get_endpoints()
# Create resource with service information
resource = Resource(attributes={
SERVICE_NAME: service_name,
SERVICE_VERSION: service_version,
"deployment.environment": os.getenv("ENVIRONMENT", "development"),
"k8s.namespace.name": os.getenv("K8S_NAMESPACE", "bakery-ia"),
"k8s.pod.name": os.getenv("HOSTNAME", "unknown"),
})
# Use provided endpoint or get from config
if otel_endpoint:
http_endpoint = OTelConfig._ensure_http_endpoint(otel_endpoint, "/v1/logs")
else:
http_endpoint = endpoints.logs_http
# Get resource attributes
resource_attrs = OTelConfig.get_resource_attributes(service_name, service_version)
resource = Resource(attributes=resource_attrs)
# Configure logger provider
logger_provider = LoggerProvider(resource=resource)
set_logger_provider(logger_provider)
# Configure OTLP exporter for logs
# Configure OTLP HTTP exporter for logs
otlp_exporter = OTLPLogExporter(
endpoint=otel_endpoint,
endpoint=http_endpoint,
timeout=10
)
@@ -135,9 +120,10 @@ def setup_otel_logging(
root_logger.addHandler(otel_handler)
logger.info(
"OpenTelemetry logs export configured",
"OpenTelemetry logs export configured successfully",
service=service_name,
otel_endpoint=otel_endpoint,
http_endpoint=http_endpoint,
protocol="http",
console_logging=enable_console
)
@@ -147,8 +133,7 @@ def setup_otel_logging(
logger.error(
"Failed to setup OpenTelemetry logs export",
service=service_name,
error=str(e),
reason="Will continue with standard logging only"
error=str(e)
)
return None