API Keys

Variante 1: API Key

  • Simpel
  • Keine weiteren Systeme involviert

API Variante 1

Variante 2

  • Keine Unterscheidung zwischen User und Anwendung
  • Unsichere Verbindung zur API gibt nur kurzzeitig Zugriff
  • Key Rotation, Hinzufügen, Löschen etc. unabhängig von Resource Server
  • Client ID verringert Overhead bei vielen Keys

API Variante 2

Variante 3

  • Zugriff nach außen beschränkt
  • Rate Limiting / Throttling

API Variante 3

Observability (o11y)

Observability is about understanding and debugging unknown-unknowns;
the ability to understand any inner system state just by asking questions from outside of the system.

— Carity Majors, Observability Pioneer, Co-Founder of Honeycomb.io

OpenTelemetry Protocol (otlp)

  • Von Cloud Native Computing Foundation (cncf)

Signals

  • Traces (stable)
  • Metrics (stable)
  • Logs (stable)
  • Profiles (Protocol stable)
  • Real User Monitoring "RUM" (In design)

Logs

  • "What happened?"
  • Timestamped Event
  • Message Template für Menschen
  • Beliebige Properties
  • Einfach auszugeben

Traces

  • "Where did it happen?"
  • Mehrere Spans mit gleicher Trace ID
  • Verbraucht viel Speicherplatz
  • Verschachtelung (Parent / Child)
  • Service übergreifend
  • Beliebige Properties
  • Zeigt Performance Bottlenecks
  • Braucht extra UI

Span

  • Unique ID / Span ID
  • Correlation ID / Trace ID
  • Start Time, End Time
  • Causality ID / Parent Span ID
  • Attributes

Span Event

  • Relevantes Ereignis während eines Spans
  • Wie Log, mit mehr Kontext
  • Alternative zu Parent/Child Link
  • Casual vs Causal link

Sampling

  • Um Last und Speicherplatz zu reduzieren
  • Head Sampling
  • Tail Sampling
  • Kann Sampling Threshold mitschicken

Metrics

  • "How often / how much?"
  • "Bucket": Aggregation von Werten
    • z.B. http_requests_total{method="POST", route="/checkout"}
    • Low cardinality!
  • Speichert regelmäßig den aktuellen Wert
  • Verbraucht wenig Speicherplatz
  • Uptime, Performance, Latency threshold, ...
  • Zeigt plötzliche Änderungen
  • Zeigt langzeitige Trends

Baggage

  • Headers bei ausgehenden Anfragen
  • w3c, nicht OpenTelemetry
  • Vorsichtig mit umgehen

OpenTelemetry Collector

  • Zentraler OpenTelementry Proxy
  • Konfiguration, Enrichment
  • Mapping zu Anbieter Format
  • Filterung
  • Tail Sampling

OpenTelemetry Collector

Warum OpenTelemetry nutzen?

  • Fast jeder Anbieter unterstützt es
  • Future Proof
  • Öffnet Möglichkeiten für Anbindung und Instrumentation

Kompatibilität mit .net

  • Logs
    • .net Core: Logger Extensions, wurden an OTel angepasst
    • .net Framework: Kein Standard Logger
  • Tracing
    • .net Core: "Activity", wurde an OTel angepasst
    • .net Framework: System.Diagnostics.DiagnosticSource => Activity
  • Metrics
    • Von Anfang an OTel kompatibel

Logging in .net Core

  • ILogger<T>, ILoggerFactory: Typ-spezifisches Logging
  • ILoggerProvider: Schreibt / sendet Logs
  • EventId: Zum Identifizieren von Logs
  • Scope: Objekt für zusätzlichen Kontext

Tracing in .net

  • "Activity" = "Span"
  • .net Framework: System.Diagnostics.DiagnosticSource
  • .net Core: Included

Tracing in .net

public static class Tracing
{
    public static string Name = Assembly.GetExecutingAssembly().GetName().Name;
    public static string Version = Assembly.GetExecutingAssembly().GetName().Version;
    public static readonly ActivitySource ActivitySource = new(Name, Version);

    public const string TenantId = "tenant.id";
    // weitere Konstanten
}

Tracing in .net

public void ImportUsers(ImportUsersDto dto)
{
    using (var activity = Tracing.ActivitySource.StartActivity("Import Users"))
    {
        activity?.SetTag(Tracing.TenantId, TenantId);
        activity?.SetTag("user_count", dto.Users.Length);
        // ...
    }
}
public void ImportUser(UserDto dto)
{
    // ...
    Activity.Current?.AddEvent(new ActivityEvent("User Imported"));
}

OpenTelemetry in .net Core

  • SDKs
  • Instrumentation
  • Exporter

OpenTelemetry in .net Core

builder.Services.AddOpenTelemetry()
    .ConfigureResource(resource => resource.AddService(serviceName: builder.Environment.ApplicationName))
    .WithTracing(tracing =>
    {
        tracing
            .AddAspNetCoreInstrumentation() // OpenTelemetry.Instrumentation.AspNetCore
            .AddSqlClientInstrumentation() // OpenTelemetry.Instrumentation.SqlClient
            .AddSource("Schroeder.LAD").AddSource("Enoso.Infrastructure")
            .AddOtlpExporter(otlp => // OpenTelemetry.Exporter.OpenTelemetryProtocol
            {
                otlp.Endpoint = new Uri(builder.Configuration["OpenTelemetry:TracingEndpoint"]);
                otlp.Headers = builder.Configuration["OpenTelemetry:Headers"];
                otlp.Protocol = OtlpExportProtocol.HttpProtobuf;
            });
    })
    .WithLogging(logging =>
    {
        logging.AddOtlpExporter(otlp =>
        {
            otlp.Endpoint = new Uri(builder.Configuration["OpenTelemetry:LoggingEndpoint"]);
            otlp.Headers = builder.Configuration["OpenTelemetry:Headers"];
            otlp.Protocol = OtlpExportProtocol.HttpProtobuf;
        });
    });

Sentry

  • Anzeige von Logs, Traces, (Metrics)
  • Monitoring von Fehlern, Bottlenecks, Regressions
  • Gruppierung ähnlicher Events
  • Alerts
  • Integration mit Diensten (Bitbucket, Jira)
  • Seer
  • OpenTelemetry Integration
  • SDK

Demo

Quellen

Code Review

Ziele der Code Review

  • Bugs finden
  • Patterns und Wissen kommunizieren
  • Ownership teilen
  • Bessere Lösungen finden

Be open for feedback

  • Gezielt nach Feedback fragen
  • Auf wertvolles Feedback reagieren
  • Code nicht erklären, sondern so umschreiben, dass man ihn versteht

Write PRs you would want to review

  • Lesbarer Code
  • Kleine PRs mit klarem Scope
  • PRs selbst anschauen

Style guides and CI

  • Style Diskussionen in Style Guide klären
  • Linting und Tests automatisieren
  • Fokus des Reviewers sollte sein
    • Löst es die Aufgabe?
    • Ist es die beste Lösung?

Start reviewing immediately

  • PR abarbeiten, bevor man eine neue Aufgabe anfängt
  • Wenn Backlog priorisiert ist, sind PRs wichtiger als die nächste Aufgabe

Don't overwhelm the author

  • Im ersten Durchgang auf high level Kommentare beschränken
    • wichtige Kommentare sollten nicht untergehen
    • Kleinigkeiten sind schnell outdated
  • Kommentare nicht wiederholen (Hinweis "überall anpassen" o.ä.)
  • out-of-scope Kommentare vermeiden

We don't always have to go for perfect

  • Code von "Okay" zu "Perfekt" zu kriegen ist anstrengend
  • Fokus auf Verbesserung ("Okay" → "Gut")
  • Lerneffekt: Zukünftige PRs starten bei "Gut"
  • Übrige Kommentare sind trivial → approve

Resolve stalemates proactively

Wenn Reviewer und Autor unterschiedlicher Meinung sind:

  • Anrufen und diskutieren
  • Zweite Meinung
  • Nachgeben

PR Scope

  • Funktionale und nicht-funktionale Änderungen trennen
  • "make the code more obviously correct"
  • Guter Scope → Fehler werden eher gefunden
  • "Changelists"

Hand-off Kommunizieren

  • Hat der Autor den PR vollständig bearbeitet?
  • Riskiert Zeitverschwendung oder Deadlock

Formulierung

  • Don't make it personal
    ✗ "Du hast x getan aber y wäre besser"
  • Formuliere Feedback als Fragen
    ✓ "Könnte man nicht y machen statt x?"
  • Bei mehrdeutigen Kommentaren spezifizierende Rückfragen stellen
    R: "Diese Funktion ist verwirrend"
    A: "Was könnte man verbessern?"

Weitere Tipps

  • Reinforce good Habits - Positives Feedback ist effektiver als negatives Feedback
  • Be generous with examples - Kann dem Autor Zeit sparen, kann klarer kommunizieren wie man etwas meint
  • Tie comments to principles, not opinions - Bei Kommentaren Gründe angeben
  • Avoid buddy reviews - "Ich kenn dich, du wirst das schon richtig gemacht haben"

Quellen

R: "This function is confusing" A: "What changes would be helpful?"