Skip to content

Commit

Permalink
Merge pull request #13 from canonical/OPENG-2562
Browse files Browse the repository at this point in the history
Fix ReceiverProtocols confusion
  • Loading branch information
michaeldmitry authored Jul 30, 2024
2 parents ed6b911 + c98827d commit b114df1
Show file tree
Hide file tree
Showing 36 changed files with 1,513 additions and 2,076 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ __pycache__/
.idea
.vscode/
*.egg-info/
cos-tool-*
cos-tool-*
src/prometheus_alert_rules/consolidated_rules/**
13 changes: 13 additions & 0 deletions charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ provides:
requires:
self-tracing:
interface: tracing
description: |
Integration to enable Tempo to send its own traces to another Tempo instance.
limit: 1
s3:
interface: s3
limit: 1
Expand Down Expand Up @@ -136,3 +141,11 @@ config:
description: Force-enable the receiver for the 'otlp_http' protocol in Tempo, even if there is no integration currently requesting it.
type: boolean
default: false
always_enable_jaeger_thrift_http:
description: Force-enable the receiver for the 'jaeger_thrift_http' protocol in Tempo, even if there is no integration currently requesting it.
type: boolean
default: false
always_enable_jaeger_grpc:
description: Force-enable the receiver for the 'jaeger_grpc' protocol in Tempo, even if there is no integration currently requesting it.
type: boolean
default: false
17 changes: 7 additions & 10 deletions lib/charms/tempo_k8s/v2/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def __init__(self, *args):

# Increment this PATCH version before using `charmcraft publish-lib` or reset
# to 0 if you are raising the major API version
LIBPATCH = 7
LIBPATCH = 8

PYDEPS = ["pydantic"]

Expand All @@ -116,14 +116,13 @@ def __init__(self, *args):
DEFAULT_RELATION_NAME = "tracing"
RELATION_INTERFACE_NAME = "tracing"

# Supported list rationale https://github.com/canonical/tempo-coordinator-k8s-operator/issues/8
ReceiverProtocol = Literal[
"zipkin",
"kafka",
"opencensus",
"tempo_http",
"tempo_grpc",
"otlp_grpc",
"otlp_http",
"jaeger_grpc",
"jaeger_thrift_http",
]

RawReceiver = Tuple[ReceiverProtocol, str]
Expand All @@ -141,14 +140,12 @@ class TransportProtocolType(str, enum.Enum):
grpc = "grpc"


receiver_protocol_to_transport_protocol = {
receiver_protocol_to_transport_protocol: Dict[ReceiverProtocol, TransportProtocolType] = {
"zipkin": TransportProtocolType.http,
"kafka": TransportProtocolType.http,
"opencensus": TransportProtocolType.http,
"tempo_http": TransportProtocolType.http,
"tempo_grpc": TransportProtocolType.grpc,
"otlp_grpc": TransportProtocolType.grpc,
"otlp_http": TransportProtocolType.http,
"jaeger_thrift_http": TransportProtocolType.http,
"jaeger_grpc": TransportProtocolType.grpc,
}
"""A mapping between telemetry protocols and their corresponding transport protocol.
"""
Expand Down
87 changes: 69 additions & 18 deletions scripts/tracegen.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,98 @@
import os
import time
from pathlib import Path
from typing import Any, Literal
from typing import Any, Literal, get_args
import requests

from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter as GRPCExporter
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as HTTPExporter
from opentelemetry.exporter.zipkin.json import ZipkinExporter
from opentelemetry.exporter.jaeger.thrift import JaegerExporter as JaegerThriftHttpExporter
from opentelemetry.exporter.jaeger.proto.grpc import JaegerExporter as JaegerGRPCExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
BatchSpanProcessor,
ConsoleSpanExporter,
)

ReceiverProtocol = Literal[
"zipkin",
"otlp_grpc",
"otlp_http",
"jaeger_grpc",
"jaeger_thrift_http",
]

def set_envvars(cert: Path = None):
ca_cert_path = str(Path(cert).absolute()) if cert else ""
os.environ['OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE'] = ca_cert_path
os.environ['OTEL_EXPORTER_JAEGER_CERTIFICATE'] = ca_cert_path
# jaeger thrift http exporter does not expose a parameter to set path for CA verification
os.environ['SSL_CERT_FILE'] = ca_cert_path
os.environ["REQUESTS_CA_BUNDLE"] = ca_cert_path

def initialize_exporter(protocol: str, endpoint: str, cert: Path = None):
# ip:4317
if protocol == "otlp_grpc":
return GRPCExporter(
endpoint=endpoint,
insecure=not cert,
)
# scheme://ip:4318/v1/traces
elif protocol == "otlp_http":
return HTTPExporter(
endpoint=endpoint,
)
# scheme://ip:9411/v1/traces
elif protocol == "zipkin":
# zipkin does not expose an arg to pass certificate
session = requests.Session()
if cert:
session.verify = cert
return ZipkinExporter(
endpoint=endpoint,
session=session,
)
# scheme://ip:14268/api/traces?format=jaeger.thrift
elif protocol == "jaeger_thrift_http":
return JaegerThriftHttpExporter(
collector_endpoint=endpoint,
)
# ip:14250
elif protocol == "jaeger_grpc":
return JaegerGRPCExporter(
collector_endpoint = endpoint,
insecure=not cert,
)
else:
raise ValueError(f"Unsupported protocol: {protocol}")

def emit_trace(
endpoint: str,
log_trace_to_console: bool = False,
cert: Path = None,
protocol: Literal["grpc", "http", "ALL"] = "grpc",
protocol: ReceiverProtocol = "otlp_http",
nonce: Any = None
):
os.environ['OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE'] = str(Path(cert).absolute()) if cert else ""
if protocol == "ALL":
for proto in get_args(protocol):
emit_trace(endpoint, log_trace_to_console, cert, proto, nonce=nonce)
else:
set_envvars(cert)
span_exporter = initialize_exporter(protocol, endpoint, cert)
return _export_trace(span_exporter, log_trace_to_console=log_trace_to_console, nonce=nonce, protocol = protocol)

if protocol == "grpc":
span_exporter = GRPCExporter(
endpoint=endpoint,
insecure=not cert,
)
elif protocol == "http":
span_exporter = HTTPExporter(
endpoint=endpoint,
)
else: # ALL
return (emit_trace(endpoint, log_trace_to_console, cert, "grpc", nonce=nonce) and
emit_trace(endpoint, log_trace_to_console, cert, "http", nonce=nonce))


return _export_trace(span_exporter, log_trace_to_console=log_trace_to_console, nonce=nonce)




def _export_trace(span_exporter, log_trace_to_console: bool = False, nonce: Any = None):
def _export_trace(span_exporter, log_trace_to_console: bool = False, nonce: Any = None, protocol: ReceiverProtocol = "otlp_http"):
resource = Resource.create(attributes={
"service.name": "tracegen",
"service.name": f"tracegen-{protocol}",
"nonce": str(nonce)
}
)
Expand Down
Loading

0 comments on commit b114df1

Please sign in to comment.