Python トレース SDK
Instana によるトレースは自動的に行われますが、カスタムコード、特定のアプリケーション領域、または社内コンポーネントについてさらに詳細な可視性を確保したい場合は、 Instana Python のトレース SDK をご利用いただけます。
Instana Python Tracing SDK
Instana ( Python )モジュールは、 OpenTelemetry ( API )をベースにした API を提供し、アプリケーションの任意の部分を追跡することができます。
API を使用して、コードの一部にトレース用のインストルメンテーションを適用するには、次のようにします
from instana.singletons import tracer
try:
span = tracer.start_span("span_name")
# The code to be instrumented
id = user.find_by_name("john.smith")
span.set_attribute("user_id", id)
except Exception as e:
span.record_exception(e)
finally:
if span and span.is_recording():
span.end()
あるいは、 with-as ステートメントでコンテキスト・マネージャーを使用することもできます。これにより、以下のように、発生したすべての例外が自動的にキャプチャーされ、ログに記録されます。
from instana.singletons import tracer
with tracer.start_as_current_span("span_name") as span:
# The code to be instrumented.
id = user.find_by_name("john.smith")
span.set_attribute("user_id", id)
非同期トレース
トレースしたい操作の中には、非同期のものがあるかもしれません。つまり、即座に処理を返しますが、メインの命令シーケンスとは別個に処理が継続されるということです。 たとえば、asyncio ライブラリを使用してこれらの操作を追跡するには、以下のトレースメソッドを使用できます:
import asyncio
from instana.singletons import tracer
async def do_work(parent_span):
parent_context = parent_span.get_span_context() if parent_span else None
with tracer.start_as_current_span(
"launch_async_work",
span_context=parent_context
):
print("Work stared")
await asyncio.sleep(1)
print("Work finished!")
with tracer.start_as_current_span("launch_uvloop") as sync_span:
asyncio.run(do_work(sync_span))
分岐したプロセスにおけるスパンを追跡する
フォークされたプロセス内のスパンを追跡したい場合は、の後に time.sleep() を追加してください span.end()。 以下の例を参照してください。
from instana.singletons import tracer
def forked_process(num):
print(f"in forked process {num}")
try:
span = tracer.start_span(f"forked process {num}")
print(f"sleep 10 for forked process {num}")
time.sleep(10)
except Exception as e:
span.record_exception(e)
finally:
if span and span.is_recording():
span.end()
logger.warning(f"sleep 2 for forked process {num}")
time.sleep(2) ## < -- with a sleep after span.finish(), the span can be collected
新規スレッドへのコンテキストの伝達
トレースはスレッドに対してローカルです。 新規スレッドを作成する場合は、コンテキストをその新規スレッドに持ち込んでから、取得する必要があります。 以下のように、コンテキストを新しいスレッドに持ち込めるようにコードをインスツルメントできます。
from instana.singletons import tracer
from threading import Thread
def child_thread_function(parent_span):
parent_context = parent_span.get_span_context() if parent_span else None
with tracer.start_as_current_span(
"child_thread_span",
span_context=parent_context
) as child_span:
print("Thread offloaded work goes here")
with tracer.start_as_current_span("parent_thread_span") as parent_span:
thread = Thread(
target = child_thread_function,
args = (parent_span,)
)
thread.start()
thread.join()
後で実行されるジョブの追跡
以下のようにして、後で実行するためにキューに入れられたジョブをインスツルメンテーションすることができます。
# Python 3.8
import asyncio
import datetime
import uvloop
import aiohttp
from instana.singletons import tracer
from opentelemetry.trace import SpanKind
uvloop.install()
async def launch_async_calls(parent_span):
parent_context = parent_span.get_span_context() if parent_span else None
with tracer.start_as_current_span(
"launch_async_calls",
span_context=parent_context
):
async with aiohttp.ClientSession() as session:
async with session.get("https://wikipedia.org") as resp:
print(resp.status)
print(await resp.text())
async def run_at(dt, coro):
await asyncio.sleep((dt - datetime.datetime.now()).total_seconds())
return await coro
with tracer.start_as_current_span("launch_uvloop") as sync_span:
sync_span.set_attribute("span.kind", SpanKind.SERVER)
asyncio.run(
run_at(
datetime.datetime.now() + datetime.timedelta(seconds=5),
launch_async_calls(sync_scope.span)
)
)
Instana のスパンにカスタムタグを追加する
Instana のspan要素にカスタム属性を追加するには、` set_attribute() method` を使用して以下のコードを実装してください:
from instana.singletons import tracer
with tracer.start_as_current_span("span_name") as span:
span.set_attribute("custom_attribute", "custom_value")
カスタムタグを使用したスパン種別の設定
Instana のspan要素の型を明示的に定義するには、カスタム属性を span.kind 次のように設定します:
from instana.singletons import tracer
from opentelemetry.trace import SpanKind
with tracer.start_as_current_span("span_name") as span:
span.set_attribute("span.kind", <value>)
を、以下の有効な値のいずれかに <value> 置き換えてください:
| スパンの種類 | 許容値 |
|---|---|
| エントリの範囲 | "entry"、 "server"、 "consumer"、 SpanKind.SERVER、または SpanKind.CONSUMER |
| 出口のスパン | "exit"、 "client"、 "producer"、 SpanKind.CLIENT、または SpanKind.PRODUCER |
| 内部スパン(デフォルト) | "intermediate"またはSpanKind.INTERNAL |