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
10 changes: 2 additions & 8 deletions src/instana/helpers.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
# (c) Copyright IBM Corp. 2021
# (c) Copyright Instana Inc. 2018

import os
from string import Template

from instana import eum_api_key as global_eum_api_key
from .singletons import tracer
from instana.log import logger

# Usage:
#
Expand All @@ -26,7 +20,7 @@ def eum_snippet(trace_id=None, eum_api_key=None, meta=None):

@return string
"""
return ''
return ""


def eum_test_snippet(trace_id=None, eum_api_key=None, meta=None):
Expand All @@ -40,4 +34,4 @@ def eum_test_snippet(trace_id=None, eum_api_key=None, meta=None):

@return string
"""
return ''
return ""
34 changes: 19 additions & 15 deletions src/instana/instrumentation/aio_pika.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
# (c) Copyright IBM Corp. 2025


try:
import aio_pika
import wrapt
from typing import (
TYPE_CHECKING,
Dict,
Any,
Callable,
Dict,
Optional,
Tuple,
Type,
Optional,
)

import wrapt

from instana.log import logger
from instana.propagators.format import Format
from instana.util.traceutils import get_tracer_tuple, tracing_is_off
from instana.singletons import tracer
from instana.singletons import get_tracer
from instana.util.traceutils import get_tracer_tuple

if TYPE_CHECKING:
from instana.span.span import InstanaSpan
from aio_pika.abc import AbstractMessage, ConsumerTag
from aio_pika.exchange import Exchange
from aiormq.abc import ConfirmationFrameType
from aio_pika.abc import ConsumerTag, AbstractMessage
from aio_pika.queue import Queue, QueueIterator
from aiormq.abc import ConfirmationFrameType

from instana.span.span import InstanaSpan

def _extract_span_attributes(
span: "InstanaSpan", connection, sort: str, routing_key: str, exchange: str
Expand All @@ -41,10 +43,10 @@ async def publish_with_instana(
args: Tuple[object],
kwargs: Dict[str, Any],
) -> Optional["ConfirmationFrameType"]:
if tracing_is_off():
tracer, parent_span, _ = get_tracer_tuple()
if not tracer:
return await wrapped(*args, **kwargs)

tracer, parent_span, _ = get_tracer_tuple()
parent_context = parent_span.get_span_context() if parent_span else None

def _bind_args(
Expand All @@ -54,10 +56,8 @@ def _bind_args(
**kwargs: object,
) -> Tuple[object, ...]:
return (message, routing_key, args, kwargs)

(message, routing_key, args, kwargs) = _bind_args(
*args, **kwargs
)

(message, routing_key, args, kwargs) = _bind_args(*args, **kwargs)

with tracer.start_as_current_span(
"rabbitmq", span_context=parent_context
Expand Down Expand Up @@ -91,6 +91,10 @@ async def consume_with_instana(
args: Tuple[object],
kwargs: Dict[str, Any],
) -> "ConsumerTag":
tracer = get_tracer()
if not tracer:
return await wrapped(*args, **kwargs)

connection = instance.channel._connection
callback = kwargs["callback"] if kwargs.get("callback") else args[0]

Expand Down
12 changes: 6 additions & 6 deletions src/instana/instrumentation/aioamqp.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# (c) Copyright IBM Corp. 2025

try:
import aioamqp
from typing import Any, Callable, Dict, Tuple

import aioamqp
import wrapt
from opentelemetry.trace.status import StatusCode

from instana.log import logger
from instana.util.traceutils import get_tracer_tuple, tracing_is_off
from instana.util.traceutils import get_tracer_tuple

@wrapt.patch_function_wrapper("aioamqp.channel", "Channel.basic_publish")
async def basic_publish_with_instana(
Expand All @@ -17,10 +17,10 @@ async def basic_publish_with_instana(
argv: Tuple[object, Tuple[object, ...]],
kwargs: Dict[str, Any],
) -> object:
if tracing_is_off():
tracer, parent_span, _ = get_tracer_tuple()
if not tracer:
return await wrapped(*argv, **kwargs)

tracer, parent_span, _ = get_tracer_tuple()
parent_context = parent_span.get_span_context() if parent_span else None
with tracer.start_as_current_span(
"aioamqp-publisher", span_context=parent_context
Expand Down Expand Up @@ -57,11 +57,11 @@ async def basic_consume_with_instana(
argv: Tuple[object, Tuple[object, ...]],
kwargs: Dict[str, Any],
) -> object:
if tracing_is_off():
tracer, parent_span, _ = get_tracer_tuple()
if not tracer:
return await wrapped(*argv, **kwargs)

callback = argv[0]
tracer, parent_span, _ = get_tracer_tuple()
parent_context = parent_span.get_span_context() if parent_span else None

@wrapt.decorator
Expand Down
32 changes: 17 additions & 15 deletions src/instana/instrumentation/aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,38 @@
# (c) Copyright Instana Inc. 2019


from types import SimpleNamespace
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, Tuple
import wrapt

from opentelemetry.semconv.trace import SpanAttributes

from instana.log import logger
from instana.propagators.format import Format
from instana.singletons import agent
from instana.util.secrets import strip_secrets_from_query
from instana.util.traceutils import get_tracer_tuple, tracing_is_off, extract_custom_headers

try:
from types import SimpleNamespace
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, Tuple

import aiohttp
import wrapt
from opentelemetry.semconv.trace import SpanAttributes

from instana.log import logger
from instana.propagators.format import Format
from instana.singletons import agent
from instana.util.secrets import strip_secrets_from_query
from instana.util.traceutils import (
extract_custom_headers,
get_tracer_tuple,
)

if TYPE_CHECKING:
from aiohttp.client import ClientSession
from instana.span.span import InstanaSpan

from instana.span.span import InstanaSpan

async def stan_request_start(
session: "ClientSession", trace_config_ctx: SimpleNamespace, params
) -> Awaitable[None]:
try:
tracer, parent_span, _ = get_tracer_tuple()
# If we're not tracing, just return
if tracing_is_off():
if not tracer:
trace_config_ctx.span_context = None
return

tracer, parent_span, _ = get_tracer_tuple()
parent_context = parent_span.get_span_context() if parent_span else None

span = tracer.start_span("aiohttp-client", span_context=parent_context)
Expand Down
46 changes: 23 additions & 23 deletions src/instana/instrumentation/asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@
# (c) Copyright Instana Inc. 2019


import time
from contextlib import contextmanager
from typing import Any, Callable, Dict, Iterator, Tuple
try:
import time
from contextlib import contextmanager
from typing import TYPE_CHECKING, Any, Callable, Dict, Iterator, Tuple

import wrapt
from opentelemetry.trace import use_span
from opentelemetry.trace.status import StatusCode
import wrapt
from opentelemetry.trace import use_span
from opentelemetry.trace.status import StatusCode

from instana.configurator import config
from instana.log import logger
from instana.span.span import InstanaSpan
from instana.util.traceutils import get_tracer_tuple, tracing_is_off
from instana.configurator import config
from instana.log import logger
from instana.span.span import InstanaSpan
from instana.util.traceutils import get_tracer_tuple

try:
if TYPE_CHECKING:
from instana.tracer import InstanaTracer
import asyncio

@wrapt.patch_function_wrapper("asyncio", "ensure_future")
Expand All @@ -25,13 +27,11 @@ def ensure_future_with_instana(
argv: Tuple[object, Tuple[object, ...]],
kwargs: Dict[str, Any],
) -> object:
if (
not config["asyncio_task_context_propagation"]["enabled"]
or tracing_is_off()
):
tracer, parent_span, _ = get_tracer_tuple()
if not config["asyncio_task_context_propagation"]["enabled"] or not tracer:
return wrapped(*argv, **kwargs)

with _start_as_current_async_span() as span:
with _start_as_current_async_span(tracer, parent_span) as span:
try:
span.set_status(StatusCode.OK)
return wrapped(*argv, **kwargs)
Expand All @@ -47,26 +47,26 @@ def create_task_with_instana(
argv: Tuple[object, Tuple[object, ...]],
kwargs: Dict[str, Any],
) -> object:
if (
not config["asyncio_task_context_propagation"]["enabled"]
or tracing_is_off()
):
tracer, parent_span, _ = get_tracer_tuple()
if not config["asyncio_task_context_propagation"]["enabled"] or not tracer:
return wrapped(*argv, **kwargs)

with _start_as_current_async_span() as span:
with _start_as_current_async_span(tracer, parent_span) as span:
try:
span.set_status(StatusCode.OK)
return wrapped(*argv, **kwargs)
except Exception as exc:
logger.debug(f"asyncio create_task_with_instana error: {exc}")

@contextmanager
def _start_as_current_async_span() -> Iterator[InstanaSpan]:
def _start_as_current_async_span(
tracer: "InstanaTracer",
parent_span: "InstanaSpan",
) -> Iterator[InstanaSpan]:
"""
Creates and yield a special InstanaSpan to only propagate the Asyncio
context.
"""
tracer, parent_span, _ = get_tracer_tuple()
parent_context = parent_span.get_span_context() if parent_span else None

_time = time.time_ns()
Expand Down
31 changes: 18 additions & 13 deletions src/instana/instrumentation/aws/boto3.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# (c) Copyright IBM Corp. 2025


try:
from typing import TYPE_CHECKING, Any, Callable, Dict, Sequence, Tuple, Type

Expand All @@ -12,22 +14,24 @@
from botocore.client import BaseClient

from instana.span.span import InstanaSpan
from instana.tracer import InstanaTracer

import json

import wrapt

from instana.log import logger
from instana.propagators.format import Format
from instana.singletons import tracer
from instana.span.span import get_current_span
from instana.util.traceutils import (
extract_custom_headers,
get_tracer_tuple,
tracing_is_off,
)

def lambda_inject_context(payload: Dict[str, Any], span: "InstanaSpan") -> None:
def lambda_inject_context(
tracer: "InstanaTracer",
payload: Dict[str, Any],
span: "InstanaSpan",
) -> None:
"""
When boto3 lambda client 'Invoke' is called, we want to inject the tracing context.
boto3/botocore has specific requirements:
Expand All @@ -51,9 +55,9 @@ def emit_add_auth_with_instana(
args: Tuple[object],
kwargs: Dict[str, Any],
) -> Callable[..., None]:
current_span = get_current_span()
if not tracing_is_off() and current_span and current_span.is_recording():
extract_custom_headers(current_span, args[0].headers)
_, parent_span, _ = get_tracer_tuple()
if parent_span:
extract_custom_headers(parent_span, args[0].headers)
return wrapped(*args, **kwargs)

@wrapt.patch_function_wrapper("botocore.client", "BaseClient._make_api_call")
Expand All @@ -63,18 +67,19 @@ def make_api_call_with_instana(
args: Sequence[Dict[str, Any]],
kwargs: Dict[str, Any],
) -> Dict[str, Any]:
tracer, parent_span, _ = get_tracer_tuple()
# If we're not tracing, just return
if tracing_is_off():
if not tracer:
return wrapped(*args, **kwargs)

tracer, parent_span, _ = get_tracer_tuple()

parent_context = parent_span.get_span_context() if parent_span else None

if instance.meta.service_model.service_name == "dynamodb":
create_dynamodb_span(wrapped, instance, args, kwargs, parent_context)
create_dynamodb_span(
wrapped, instance, args, kwargs, parent_context, tracer
)
elif instance.meta.service_model.service_name == "s3":
create_s3_span(wrapped, instance, args, kwargs, parent_context)
create_s3_span(wrapped, instance, args, kwargs, parent_context, tracer)
else:
with tracer.start_as_current_span(
"boto3", span_context=parent_context
Expand All @@ -98,7 +103,7 @@ def make_api_call_with_instana(

# Inject context when invoking lambdas
if "lambda" in instance._endpoint.host and operation == "Invoke":
lambda_inject_context(payload, span)
lambda_inject_context(tracer, payload, span)

try:
result = wrapped(*args, **kwargs)
Expand Down
Loading
Loading