카테고리 없음

OpenTelemetry: Instrumenting libraries

Roiei 2022. 10. 7. 17:06
반응형

Instrumenting libraries

automatic instrumentation은 보통 library hook 혹은 monkey-patching library code를 통해 이뤄짐

 

 

OpenTelemetry API

API, SDK

가장 최초의 stable OpenTelemetry API (1.0.*)을 사용하고 updating issue를 굳이 하지 않아도 됨

사용하는 부분만 별도 package로 만드는 방법도 있음

OpenTelemetry Trace API는 안정화 되었으나, 이것의 후속인 Semantic Versioning 2.0인 Semantic Conventions은 아직 안정화 되지 않았음

 

Getting a tracer

Libraries는 tracer를 반드시 global TracerProvider를 통해 얻어야 함

private static final Tracer tracer = GlobalOpenTelemetry.getTracer("demo", "0.0.0-beta");

획득 시 lib name과 version을 제공

 

What to instrument

public APIs

public API 호출을 위해 성생된 span들은 user가 telemetry를 application code에 map 하게 함

이로서 lib call의 duration과 결과를 이해할 수 있게 함

 

ex.

private static final Tracer tracer = GlobalOpenTelemetry.getTracer("demo", "0.1.0-beta1");

private Response selectWithTracing(Query query) {
    // check out conventions for guidance on span names and attributes
    Span span = tracer.spanBuilder(String.format("SELECT %s.%s", dbName, collectionName))
            .setSpanKind(SpanKind.CLIENT)
            .setAttribute("db.name", dbName)
            ...
            .startSpan();

    // makes span active and allows correlating logs and nest spans
    try (Scope unused = span.makeCurrent()) {
        Response response = query.runWithRetries();
        if (response.isSuccessful()) {
            span.setStatus(StatusCode.OK);
        }

        if (span.isRecording()) {
           // populate response attributes for response codes and other information
        }
    } catch (Exception e) {
        span.recordException(e);
        span.setStatus(StatusCode.ERROR, e.getClass().getSimpleName());
        throw e;
    } finally {
        span.end();
    }
}

 

Nested network and other spans

Events

뭔가 많이 찍어야 할 경우에는 event 즉 log를 사용

rule of thumb

 - 많은 데이터에 대해서는 span 대신 log를 사용

 - 항상 event를 span에 붙이기

 - active span의 사용은 피하기

 

Context Propagation

extracting context

lib, service가 web framework 혹은 message consumer처럼 upstream call을 받는다면, 들어온 request/message에서 context를 추출해야 함

OpenTelemetry는 Propagator를 제공

특정 propagation standards를 감추고 wire로부터의 trace context를 읽음

응답이 하나라면, wire 상에 context로 하나

이는 library가 만드는 span의 부모가 됨

 

span을 만들고 나면, span을 active하게 만들어 새로운 trace context를 app code로 보내야 함 (callback or handler)

// extract the context
Context extractedContext = propagator.extract(Context.current(), httpExchange, getter);
Span span = tracer.spanBuilder("receive")
            .setSpanKind(SpanKind.SERVER)
            .setParent(extractedContext)
            .startSpan();

// make span active so any nested telemetry is correlated
try (Scope unused = span.makeCurrent()) {
  userCode();
} catch (Exception e) {
  span.recordException(e);
  span.setStatus(StatusCode.ERROR);
  throw e;
} finally {
  span.end();
}

 

ex.

https://opentelemetry.io/docs/instrumentation/java/manual/#context-propagation

 

Manual Instrumentation

Libraries that want to export telemetry data using OpenTelemetry MUST only depend on the opentelemetry-api package and should never configure or depend on the OpenTelemetry SDK. The SDK configuration must be provided by Applications which should also depen

opentelemetry.io

 

Injecting context

context를  downstream service로 전달하고 싶을때

새로운 span을 만들어 나가는 call을 trace하고 

Propagator API를 사용해서 context를 message로 inject

 

e.g., 

Span span = tracer.spanBuilder("send")
            .setSpanKind(SpanKind.CLIENT)
            .startSpan();

// make span active so any nested telemetry is correlated
// even network calls might have nested layers of spans, logs or events
try (Scope unused = span.makeCurrent()) {
  // inject the context
  propagator.inject(Context.current(), transportLayer, setter);
  send();
} catch (Exception e) {
  span.recordException(e);
  span.setStatus(StatusCode.ERROR);
  throw e;
} finally {
  span.end();
}

https://opentelemetry.io/docs/instrumentation/java/manual/#context-propagation

 

 

Manual Instrumentation

Libraries that want to export telemetry data using OpenTelemetry MUST only depend on the opentelemetry-api package and should never configure or depend on the OpenTelemetry SDK. The SDK configuration must be provided by Applications which should also depen

opentelemetry.io

 

 

 

반응형