Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry) · leksjon

Beste praksis for manuell instrumentering

Forstå når og hvordan manuell instrumentering bør brukes for detaljert kontroll over observasjonsdataene. Lær å berike spor med egendefinerte attributter.

Leksjon 2 av 411 trinn

Beste praksis for manuell instrumentering er en gratis leksjon i Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry) på CoddyKit. Dette er leksjon 2 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry), og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry) inneholder totalt 4 leksjoner.

Introduksjon til manuell instrumentering

Velkommen! I denne leksjonen skal vi gå i dybden på manuell instrumentering med OpenTelemetry. Auto-instrumentering er flott for raske resultater, men manuell kontroll gir Dem presisjon.

Manuell instrumentering gjør det mulig å registrere svært spesifikke detaljer om applikasjonens interne operasjoner. Dette er avgjørende ved feilsøking av kompleks forretningslogikk eller egendefinerte komponenter.

Hvorfor manuelt fremfor automatisk?

Auto-instrumentering samler automatisk inn data fra vanlige biblioteker og rammeverk. Den kan imidlertid ikke kjenne applikasjonens unike logikk.

  • Egendefinert logikk: Instrumenter bestemte funksjoner eller kodeblokker.
  • Forretningskontekst: Legg til attributter som er relevante for forretningsdomenet Deres.
  • Detaljert kontroll: Definer nøyaktige grenser og relasjoner mellom spans.
  • Manglende dekning: Dekk områder som auto-instrumenteringen ikke når.

Opprett Deres første span

En span representerer én enkelt operasjon i en trace. For å opprette en manuelt trenger De en Tracer, som hentes fra OpenTelemetry SDK-en.

Slik starter De en ny span. Husk alltid å avslutte spans!

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;

public class ManualSpanDemo {
  public static void main(String[] args) {
    // Setup OpenTelemetry SDK (simplified for demo)
    SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder().build();
    OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
        .setTracerProvider(sdkTracerProvider)
        .buildAndRegisterGlobal();

    Tracer tracer = openTelemetry.getTracer("my-app", "1.0.0");

    // Start a new span
    Span span = tracer.spanBuilder("MyCustomOperation").startSpan();

    try {
      System.out.println("Executing custom operation...");
      // Simulate work
      Thread.sleep(100);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    } finally {
      // Always end the span!
      span.end();
      System.out.println("Span ended.");
    }
  }
}

Aktivere spans med scope

For at en span skal være en del av den gjeldende trace-konteksten (og for at underordnede spans automatisk skal kobles til den), må den være aktiv. Den beste måten å håndtere dette på er å bruke en Scope sammen med en try-with-resources-setning.

Dette sørger for at spannen automatisk settes som aktiv og avsluttes når blokken avsluttes.

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.Scope;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;

public class ActiveSpanDemo {
  public static void main(String[] args) {
    SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder().build();
    OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
        .setTracerProvider(sdkTracerProvider)
        .buildAndRegisterGlobal();

    Tracer tracer = openTelemetry.getTracer("my-app", "1.0.0");

    Span parentSpan = tracer.spanBuilder("ParentOperation").startSpan();
    try (Scope parentScope = parentSpan.makeCurrent()) { // Parent span is active
      System.out.println("Parent operation started.");

      Span childSpan = tracer.spanBuilder("ChildOperation").startSpan(); // Automatically links to parent
      try (Scope childScope = childSpan.makeCurrent()) {
        System.out.println("Child operation executing...");
        Thread.sleep(50);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      } finally {
        childSpan.end();
        System.out.println("Child operation ended.");
      }

      Thread.sleep(50);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    } finally {
      parentSpan.end();
      System.out.println("Parent operation ended.");
    }
  }
}

Legge til egendefinerte attributter

Attributter er nøkkel-verdi-par som gir kontekstuell informasjon om en span. De er avgjørende for å gjøre tracene søkbare og forståelige.

De kan legge til attributter i en span ved hjelp av span.setAttribute(). Bruk beskrivende nøkler og relevante verdier.

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.Scope;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;

public class SpanAttributesDemo {
  public static void main(String[] args) {
    SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder().build();
    OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
        .setTracerProvider(sdkTracerProvider)
        .buildAndRegisterGlobal();

    Tracer tracer = openTelemetry.getTracer("my-app", "1.0.0");

    Span span = tracer.spanBuilder("ProcessOrder").startSpan();
    try (Scope scope = span.makeCurrent()) {
      System.out.println("Processing order...");
      // Add attributes for order details
      span.setAttribute("order.id", "XYZ789");
      span.setAttribute("customer.email", "user@example.com");
      span.setAttribute(AttributeKey.longKey("item.count"), 3L);

      Thread.sleep(150);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    } finally {
      span.end();
      System.out.println("Order processed. Span ended with attributes.");
    }
  }
}

Registrere hendelser i spans

Hendelser er tidsstemplede meldinger som er knyttet til en span. De er nyttige for å markere viktige øyeblikk eller logge bestemte handlinger som skjer mens spannen er aktiv, uten å opprette nye underordnede spans.

Tenk på dem som små logger i tracen, som gir mer detaljer om en bestemt operasjon.

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.Scope;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;

public class SpanEventsDemo {
  public static void main(String[] args) {
    SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder().build();
    OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
        .setTracerProvider(sdkTracerProvider)
        .buildAndRegisterGlobal();

    Tracer tracer = openTelemetry.getTracer("my-app", "1.0.0");

    Span span = tracer.spanBuilder("UserLogin").startSpan();
    try (Scope scope = span.makeCurrent()) {
      System.out.println("User login initiated...");
      span.addEvent("AuthenticationStarted");

      Thread.sleep(80);
      // Add an event with attributes
      span.addEvent("DatabaseCheck", Attributes.of(
          AttributeKey.stringKey("db.query"), "SELECT * FROM users WHERE id=?"
      ));

      Thread.sleep(70);
      span.addEvent("AuthenticationSuccessful");

    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    } finally {
      span.end();
      System.out.println("User login span ended with events.");
    }
  }
}

Håndtere feil i spans

Det er avgjørende å merke spans som mislykkede når det oppstår en feil. Dette gjør det raskt å identifisere problematiske operasjoner i systemet.

Du kan sette statusen til en span til ERROR og registrere unntaket som forårsaket feilen. Dette gir rik kontekst ved feilsøking.

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Scope;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;

public class SpanErrorDemo {
  public static void main(String[] args) {
    SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder().build();
    OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
        .setTracerProvider(sdkTracerProvider)
        .buildAndRegisterGlobal();

    Tracer tracer = openTelemetry.getTracer("my-app", "1.0.0");

    Span span = tracer.spanBuilder("CriticalFunction").startSpan();
    try (Scope scope = span.makeCurrent()) {
      System.out.println("Executing critical function...");
      // Simulate an error condition
      if (Math.random() > 0.5) {
        throw new RuntimeException("Simulated critical failure!");
      }
      System.out.println("Critical function completed successfully.");

    } catch (Exception e) {
      System.out.println("Error caught: " + e.getMessage());
      span.setStatus(StatusCode.ERROR, "Function failed");
      span.recordException(e);
    } finally {
      span.end();
      System.out.println("Critical function span ended.");
    }
  }
}

Beste praksis for spans

Følg disse retningslinjene for å få mest mulig ut av manuell instrumentering:

  • Detaljeringsgrad: Opprett spans for meningsfulle arbeidsenheter, ikke for hver enkelt kodelinje.
  • Meningsfulle navn: Bruk tydelige navn med lav kardinalitet (for eksempel user.login, db.query).
  • Rike attributter: Legg til relevant forretningsmessig og teknisk kontekst som attributter.
  • Avslutt alltid spans: Bruk try-with-resources eller en eksplisitt span.end() i en finally-blokk.
  • Unngå overinstrumentering: For mange spans kan gi ekstra belastning. Fokuser på kritiske flyter.

Koble spans eksplisitt

Selv om makeCurrent() håndterer det meste av koblingen mellom foreldre og barn, må du noen ganger koble spans eksplisitt. Dette er vanlig i asynkrone scenarier eller ved integrasjon med systemer som ikke er instrumentert.

Du kan bruke SpanBuilder.setParent() eller setNoParent() til å styre forholdet mellom foreldre og barn.

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.TraceFlags;
import io.opentelemetry.api.trace.TraceState;
import io.opentelemetry.context.Context;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;

public class ExplicitLinkDemo {
  public static void main(String[] args) {
    SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder().build();
    OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
        .setTracerProvider(sdkTracerProvider)
        .buildAndRegisterGlobal();

    Tracer tracer = openTelemetry.getTracer("my-app", "1.0.0");

    // Imagine a span from an external system, represented by its context
    SpanContext externalContext = SpanContext.create(
        "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d", // Trace ID
        "0000000000000001", // Span ID
        TraceFlags.getDefault(), TraceState.getDefault()
    );

    // Create a new span that links to this external context
    Span linkedSpan = tracer.spanBuilder("ProcessingExternalMessage")
        .setParent(Context.current().with(Span.wrap(externalContext))) // Link to external context
        .setSpanKind(SpanKind.CONSUMER) // Indicate it's a message consumer
        .startSpan();

    try {
      System.out.println("Processing message from external system...");
      linkedSpan.setAttribute("message.id", "MSG-123");
      Thread.sleep(100);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    } finally {
      linkedSpan.end();
      System.out.println("Linked span ended.");
    }
  }
}

Sjekk av manuell instrumentering

Du implementerer en ny funksjon som beregner en brukers lojalitetspoeng. Du vil instrumentere denne spesifikke beregningen for å måle varigheten og de endelige poengene som tildeles. Hvilken av følgende metoder er mest hensiktsmessig for å registrere de endelige poengene med manuell OpenTelemetry-instrumentering?

Oppsummering: Manuell kontroll

I denne leksjonen utforsket vi manuell instrumentering med OpenTelemetry. Du lærte:

  • Når du bør velge manuell instrumentering fremfor autoinstrumentering for å få detaljert kontroll.
  • Hvordan du oppretter, aktiverer og avslutter spans.
  • Hvor nyttige attributter er for å legge til rik kontekst i sporene dine.
  • Hvordan du bruker hendelser til å markere bestemte øyeblikk i en span.
  • Beste praksis for håndtering av feil og eksplisitt kobling av spans.

Når du behersker manuell instrumentering, får du enestående innsyn i programmets unike logikk og ytelse.

Gratis å komme i gang

Lær deg Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry) med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
12
Leksjoner
48

Ofte stilte spørsmål

Er leksjonen «Beste praksis for manuell instrumentering» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry), inkludert «Beste praksis for manuell instrumentering», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry) inneholder totalt 4 leksjoner.

Hva lærer jeg i «Beste praksis for manuell instrumentering»?

Forstå når og hvordan manuell instrumentering bør brukes for detaljert kontroll over observasjonsdataene. Lær å berike spor med egendefinerte attributter. Du øver på Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry) med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry)?

Ingen tidligere erfaring er nødvendig. Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry) på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.

Hvor lang tid tar leksjonen «Beste praksis for manuell instrumentering»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry)-leksjonen?

Ja. Alle Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry)-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Teknikker for automatisk instrumentering
  2. Beste praksis for manuell instrumentering
  3. Kontekstforplantning og baggage
  4. Span-attributter, hendelser og status
← Tilbake til Systemobservabilitet: logging, metrikker og tracing (ELK + OpenTelemetry)