GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Eine Einführung in bpftrace für Linux

Bpftrace ist ein neuer Open-Source-Tracer für Linux zur Analyse von Produktionsleistungsproblemen und zur Fehlerbehebung von Software. Zu seinen Benutzern und Mitwirkenden gehören Netflix, Facebook, Red Hat, Shopify und andere, und es wurde von Alastair Robertson erstellt, einem talentierten Entwickler aus Großbritannien, der verschiedene Programmierwettbewerbe gewonnen hat.

Linux hat bereits viele Performance-Tools, aber sie sind oft zählerbasiert und haben eine begrenzte Sichtbarkeit. Beispielsweise kann Ihnen iostat(1) oder ein Überwachungsagent Ihre durchschnittliche Plattenlatenz mitteilen, aber nicht die Verteilung dieser Latenz. Verteilungen können mehrere Modi oder Ausreißer aufdecken, die beide die eigentliche Ursache Ihrer Leistungsprobleme sein können. Bpftrace ist für diese Art von Analyse geeignet:Zerlegung von Metriken in Verteilungen oder Pro-Ereignis-Protokolle und Erstellung neuer Metriken für die Sichtbarkeit blinder Flecken.

Sie können bpftrace über Einzeiler oder Skripte verwenden und es wird mit vielen vorgefertigten Tools geliefert. Hier ist ein Beispiel, das die Verteilung der Leselatenz für PID 181 nachzeichnet und als Zweierpotenz-Histogramm darstellt:

# bpftrace -e 'kprobe:vfs_read /pid == 30153/ { @start[tid] = nsecs; }
kretprobe:vfs_read /@start[tid]/ { @ns = hist(nsecs - @start[tid]); delete(@start[tid]); }'
Attaching 2 probes...
^C

@ns:
[256, 512)         10900 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                      |
[512, 1k)          18291 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[1k, 2k)            4998 |@@@@@@@@@@@@@@                                      |
[2k, 4k)              57 |                                                    |
[4k, 8k)             117 |                                                    |
[8k, 16k)             48 |                                                    |
[16k, 32k)           109 |                                                    |
[32k, 64k)             3 |                                                    |

Dieses Beispiel instrumentiert ein Ereignis von Tausenden verfügbaren. Wenn Sie ein seltsames Leistungsproblem haben, gibt es wahrscheinlich einen bpftrace-Einzeiler, der Licht ins Dunkel bringen kann. Bei großen Umgebungen kann Ihnen diese Fähigkeit dabei helfen, Millionen einzusparen. Für kleinere Umgebungen kann es hilfreicher sein, Latenzausreißer zu eliminieren.

Das Linux-Terminal

  • Die 7 besten Terminalemulatoren für Linux
  • 10 Befehlszeilentools für die Datenanalyse unter Linux
  • Jetzt herunterladen:SSH-Spickzettel
  • Spickzettel für fortgeschrittene Linux-Befehle
  • Linux-Befehlszeilen-Tutorials

Ich habe zuvor über bpftrace im Vergleich zu anderen Tracern geschrieben, einschließlich BCC (BPF Compiler Collection). BCC eignet sich hervorragend für vorgefertigte komplexe Tools und Agenten. Bpftrace eignet sich am besten für kurze Skripte und Ad-hoc-Untersuchungen. In diesem Artikel fasse ich die bpftrace-Sprache, Variablentypen, Sonden und Tools zusammen.

Bpftrace verwendet BPF (Berkeley Packet Filter), eine Kernel-Ausführungsmaschine, die einen virtuellen Befehlssatz verarbeitet. BPF wurde in den letzten Jahren erweitert (auch bekannt als eBPF), um eine sichere Möglichkeit zur Erweiterung der Kernel-Funktionalität bereitzustellen. Es ist auch ein heißes Thema in der Systemtechnik geworden, mit mindestens 24 Vorträgen über BPF auf der letzten Linux Plumber's Conference. BPF ist im Linux-Kernel enthalten, und bpftrace ist der beste Einstieg in die Verwendung von BPF für Observability.

Sehen Sie sich die bpftrace INSTALL-Anleitung an, um zu erfahren, wie Sie es installieren und die neueste Version erhalten; 0.9.2 wurde gerade veröffentlicht. Für Kubernetes-Cluster gibt es auch kubectl-trace zum Ausführen.

Syntax

probe[,probe,...] /filter/ { action }

Die Sonde gibt an, welche Ereignisse instrumentiert werden sollen. Der Filter ist optional und kann die Ereignisse basierend auf einem booleschen Ausdruck herausfiltern, und die Aktion ist das Miniprogramm, das ausgeführt wird.

Hier ist Hallo Welt:

# bpftrace -e 'BEGIN { printf("Hello eBPF!\n"); }'

Der Test ist BEGIN , eine spezielle Sonde, die am Anfang des Programms ausgeführt wird (wie awk). Es gibt keinen Filter. Die Aktion ist ein printf() Aussage.

Jetzt ein echtes Beispiel:

# bpftrace -e 'kretprobe:sys_read /pid == 181/ { @bytes = hist(retval); }'

Dies verwendet eine kretprobe um die Rückgabe von sys_read() zu instrumentieren Kernel-Funktion. Wenn die PID 181 ist, eine spezielle Zuordnungsvariable @bytes wird mit einer log2-Histogrammfunktion mit dem Rückgabewert retval gefüllt von sys_read() . Dadurch wird ein Histogramm der zurückgegebenen Lesegröße für PID 181 erstellt. Führt Ihre App viele Ein-Byte-Lesevorgänge aus? Vielleicht kann das optimiert werden.

Prüfungstypen

Dies sind Bibliotheken verwandter Sonden. Die derzeit unterstützten Typen sind (weitere werden hinzugefügt):

Typ Beschreibung
Tracepoint Statische Kernel-Instrumentierungspunkte
usdt Statisch definiertes Tracing auf Benutzerebene
kprobe Dynamische Funktionsinstrumentierung des Kernels
kretprobe Dynamische Kernel-Funktionsrückgabe-Instrumentierung
Uprobe Dynamische Funktionsinstrumentierung auf Benutzerebene
Uretsonde Dynamische Funktionsrückgabeinstrumentierung auf Benutzerebene
Software Kernel-Software-basierte Ereignisse
Hardware Hardwarezähler-basierte Instrumentierung
Überwachungspunkt Memory Watchpoint Events (in Entwicklung)
Profil Zeitgesteuertes Sampling über alle CPUs
Intervall Zeitgesteuerte Berichterstattung (von einer CPU)
BEGINN Start von bpftrace
ENDE Ende von bpftrace

    Dynamische Instrumentierung (auch bekannt als dynamisches Tracing) ist die Superkraft, mit der Sie jede Softwarefunktion in einer laufenden Binärdatei verfolgen können, ohne sie neu zu starten. Damit können Sie praktisch jedem Problem auf den Grund gehen. Die bereitgestellten Funktionen gelten jedoch nicht als stabile API, da sie sich von einer Softwareversion zur anderen ändern können. Daher statische Instrumentierung, bei der Ereignispunkte fest codiert sind und zu einer stabilen API werden. Wenn Sie bpftrace-Programme schreiben, versuchen Sie zuerst die statischen Typen zu verwenden, bevor Sie die dynamischen verwenden, damit Ihre Programme stabiler sind.

    Variablentypen

    Variable Beschreibung
    @name weltweit
    @name[Schlüssel] Hash
    @name[tid] thread-lokal
    $name kratzen

      Variablen mit einem @ Präfix verwenden BPF-Zuordnungen, die sich wie assoziative Arrays verhalten können. Sie können auf zwei Arten ausgefüllt werden:

      • Variablenzuweisung:@name =x;
      • Funktionszuweisung:@name =hist(x);

      Verschiedene Funktionen zum Ausfüllen von Karten sind integriert, um Daten schnell zusammenzufassen.

      Eingebaute Variablen und Funktionen

      Hier sind einige der eingebauten Variablen und Funktionen, aber es gibt noch viel mehr.

      Integrierte Variablen:

      Variable Beschreibung
      pid Prozess-ID
      comm Prozess- oder Befehlsname
      ns Aktuelle Zeit in Nanosekunden
      kstack Kernel-Stack-Trace
      ustack Stacktrace auf Benutzerebene
      arg0...argN Funktionsargumente
      Argumente Tracepoint-Argumente
      Erhalt Funktionsrückgabewert
      Name Vollständiger Sondenname

        Integrierte Funktionen:

        Funktion Beschreibung
        printf("...") Formatierten String drucken
        Zeit("...") Formatierte Uhrzeit drucken
        system("...") Shell-Befehl ausführen
        @ =count() Ereignisse zählen
        @ =hist(x) Power-of-2-Histogramm für x
        @ =lhist(x, min, max, Schritt) Lineares Histogramm für x

          Einzelheiten finden Sie im Referenzhandbuch.

          Einzeiler-Tutorial

          Eine großartige Möglichkeit, bpftrace zu lernen, sind Einzeiler, die ich in ein Einzeiler-Tutorial umgewandelt habe, das Folgendes abdeckt:

          Prüfungen auflisten bpftrace -l 'tracepoint:syscalls:sys_enter_*'
          Hallo Welt bpftrace -e 'BEGIN { printf("hello world\n") }'
          Datei wird geöffnet bpftrace -e 'tracepoint:syscalls:sys_enter_open { printf("%s %s\n", comm, str(args->filename)) }'
          Syscall zählt nach Prozess bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] =count() }'
          Verteilung von read() Bytes bpftrace -e 'tracepoint:syscalls:sys_exit_read /pid ==18644/ { @bytes =hist(args->retval) }'
          Dynamisches Kernel-Tracing von read()-Bytes bpftrace -e 'kretprobe:vfs_read { @bytes =lhist(retval, 0, 2000, 200) }'
          Timing read()s bpftrace -e 'kprobe:vfs_read { @start[tid] =nsecs } kretprobe:vfs_read /@start[tid]/ { @ns[comm] =hist(nsecs - @start[tid]); delete(@start[tid]) }'
          Ereignisse auf Prozessebene zählen bpftrace -e 'tracepoint:sched:sched* { @[name] =count() } interval:s:5 { exit() }'
          Profilieren Sie Kernel-Stacks auf der CPU bpftrace -e 'profile:hz:99 { @[stack] =count() }'
          Scheduler-Tracing bpftrace -e 'tracepoint:sched:sched_switch { @[stack] =count() }'
          Block-E/A-Ablaufverfolgung bpftrace -e 'tracepoint:block:block_rq_issue { @ =hist(args->bytes); }
          Kernel-Strukturverfolgung (ein Skript, kein Einzeiler) Befehl: bpftrace path.bt , wo sich die path.bt-Datei befindet:



          #include

          #include




          kprobe:vfs_open { printf("open path:%s\n", str(((path *)arg0)->dentry->d_name .Name)); }

          Sehen Sie sich das Tutorial für eine Erklärung der einzelnen an.

          Bereitgestellte Tools

          Abgesehen von Einzeilern können bpftrace-Programme mehrzeilige Skripte sein. Bpftrace wird mit 28 davon als Tools ausgeliefert:

          Diese finden Sie unter /tools Verzeichnis:

          tools# ls *.bt
          bashreadline.bt  dcsnoop.bt         oomkill.bt    syncsnoop.bt   vfscount.bt
          biolatency.bt    execsnoop.bt       opensnoop.bt  syscount.bt    vfsstat.bt
          biosnoop.bt      gethostlatency.bt  pidpersec.bt  tcpaccept.bt   writeback.bt
          bitesize.bt      killsnoop.bt       runqlat.bt    tcpconnect.bt  xfsdist.bt
          capable.bt       loads.bt           runqlen.bt    tcpdrop.bt
          cpuwalk.bt       mdflush.bt         statsnoop.bt  tcpretrans.bt

          Abgesehen von ihrer Verwendung bei der Diagnose von Leistungsproblemen und der allgemeinen Fehlerbehebung bieten sie auch eine andere Möglichkeit, bpftrace zu lernen. Hier sind einige Beispiele.

          Quelle

          Hier ist der Code für biolatency.bt :

          tools# cat -n biolatency.bt
               1  /*
               2   * biolatency.bt    Block I/O latency as a histogram.
               3   *                  For Linux, uses bpftrace, eBPF.
               4   *
               5   * This is a bpftrace version of the bcc tool of the same name.
               6   *
               7   * Copyright 2018 Netflix, Inc.
               8   * Licensed under the Apache License, Version 2.0 (the "License")
               9   *
              10   * 13-Sep-2018  Brendan Gregg   Created this.
              11   */
              12
              13  BEGIN
              14  {
              15          printf("Tracing block device I/O... Hit Ctrl-C to end.\n");
              16  }
              17
              18  kprobe:blk_account_io_start
              19  {
              20          @start[arg0] = nsecs;
              21  }
              22
              23  kprobe:blk_account_io_done
              24  /@start[arg0]/
              25
              26  {
              27          @usecs = hist((nsecs - @start[arg0]) / 1000);
              28          delete(@start[arg0]);
              29  }
              30 
              31  END
              32  {
              33          clear(@start);
              34  }

          Es ist unkompliziert, leicht zu lesen und kurz genug, um es auf einer Folie einzufügen. Diese Version verwendet die dynamische Ablaufverfolgung des Kernels, um blk_account_io_start() zu instrumentieren und blk_account_io_done() Funktionen, und es übergibt einen Zeitstempel zwischen ihnen, der auf arg0 codiert ist zu jedem. arg0 auf kprobe ist das erste Argument für diese Funktion, die die Struct-Anfrage * ist , und seine Speicheradresse wird als eindeutige Kennung verwendet.

          Beispieldateien

          Sie können Screenshots und Erklärungen dieser Tools im GitHub-Repo als *_example.txt sehen Dateien. Zum Beispiel:

          tools# more biolatency_example.txt
          Demonstrations of biolatency, the Linux BPF/bpftrace version.


          This traces block I/O, and shows latency as a power-of-2 histogram. For example:

          # biolatency.bt
          Attaching 3 probes...
          Tracing block device I/O... Hit Ctrl-C to end.
          ^C

          @usecs:
          [256, 512)             2 |                                                    |
          [512, 1K)             10 |@                                                   |
          [1K, 2K)             426 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
          [2K, 4K)             230 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@                        |
          [4K, 8K)               9 |@                                                   |
          [8K, 16K)            128 |@@@@@@@@@@@@@@@                                     |
          [16K, 32K)            68 |@@@@@@@@                                            |
          [32K, 64K)             0 |                                                    |
          [64K, 128K)            0 |                                                    |
          [128K, 256K)          10 |@                                                   |

          While tracing, this shows that 426 block I/O had a latency of between 1K and 2K
          usecs (1024 and 2048 microseconds), which is between 1 and 2 milliseconds.
          There are also two modes visible, one between 1 and 2 milliseconds, and another
          between 8 and 16 milliseconds: this sounds like cache hits and cache misses.
          There were also 10 I/O with latency 128 to 256 ms: outliers. Other tools and
          instrumentation, like biosnoop.bt, can shed more light on those outliers.
          [...]

          Manchmal kann es am effektivsten sein, direkt zur Beispieldatei zu wechseln, wenn Sie versuchen, diese Tools zu verstehen, da die Ausgabe (durch Design!) selbstverständlich sein kann.

          Manpages

          Es gibt auch Manpages für jedes Tool im GitHub-Repo unter /man/man8. Sie enthalten Abschnitte zu den Ausgabefeldern und dem erwarteten Overhead des Tools.

          # nroff -man man/man8/biolatency.8
          biolatency(8)               System Manager's Manual              biolatency(8)



          NAME
                 biolatency.bt - Block I/O latency as a histogram. Uses bpftrace/eBPF.

          SYNOPSIS
                 biolatency.bt

          DESCRIPTION
                 This  tool  summarizes  time  (latency) spent in block device I/O (disk
                 I/O) as a power-of-2 histogram. This  allows  the  distribution  to  be
                 studied,  including  modes and outliers. There are often two modes, one
                 for device cache hits and one for cache misses, which can be  shown  by
                 this tool. Latency outliers will also be shown.
          [...]

          Das Schreiben all dieser Manpages hat bei der Entwicklung dieser Tools am wenigsten Spaß gemacht, und bei manchen hat das Schreiben länger gedauert als die Entwicklung des Tools, aber es ist schön, das Endergebnis zu sehen.

          bpftrace vs. BCC

          Seit eBPF in den Kernel integriert wurde, wurde die meiste Mühe auf das BCC-Frontend gelegt, das eine BPF-Bibliothek und Python-, C++- und Lua-Schnittstellen zum Schreiben von Programmen bereitstellt. Ich habe viele Tools in BCC/Python entwickelt; es funktioniert großartig, obwohl die Codierung in BCC ausführlich ist. Wenn Sie an einem Leistungsproblem herumhacken, ist bpftrace besser für Ihre einmaligen benutzerdefinierten Abfragen. Wenn Sie ein Tool mit vielen Befehlszeilenoptionen oder einen Agenten schreiben, der Python-Bibliotheken verwendet, sollten Sie die Verwendung von BCC in Betracht ziehen.

          Im Netflix-Performance-Team verwenden wir beides:BCC zum Entwickeln vorgefertigter Tools, die andere leicht verwenden können, und zum Entwickeln von Agenten; und bpftrace für Ad-hoc-Analysen. Das Netzwerk-Engineering-Team hat BCC verwendet, um einen Agenten für seine Bedürfnisse zu entwickeln. Das Sicherheitsteam ist am meisten an bpftrace für die schnelle Ad-hoc-Instrumentierung zur Erkennung von Zero-Day-Schwachstellen interessiert. Und ich gehe davon aus, dass die Entwicklerteams beides verwenden werden, ohne es zu wissen, über die Selbstbedienungs-GUIs, die wir bauen (Vector), und gelegentlich eine SSH-Verbindung zu einer Instanz herstellen und ein vorgefertigtes Tool oder einen Ad-hoc-Bpftrace-Einzeiler ausführen.

          Weitere Informationen

          • Das bpftrace-Repository auf GitHub
          • Das bpftrace-Einzeiler-Tutorial
          • Das bpftrace-Referenzhandbuch
          • Das BCC-Repository für komplexere BPF-basierte Tools

          Ich habe dieses Jahr auch ein Buch herausgebracht, das bpftrace behandelt:BPF Performance Tools:Linux System and Application Observability , das von Addison Wesley veröffentlicht werden soll und viele neue bpftrace-Tools enthält.


          Dank an Alastair Robertson für die Erstellung von bpftrace und an die bpftrace-, BCC- und BPF-Communities für all die Arbeit in den letzten fünf Jahren.


          Linux
          1. FreeDOS-Befehle für Linux-Fans

          2. Einführung in Nmap unter Kali Linux

          3. 10 Linux-Befehle für die Netzwerkdiagnose

          4. Eine Einführung in Web Application Firewalls für Linux-Systemadministratoren

          5. Eine kurze Einführung in Ansible-Rollen für die Linux-Systemverwaltung

          Beste Distributionen für Spiele unter Linux

          25 kostenlose Bücher, um Linux kostenlos zu lernen

          Einführung in die Verwaltung von Linux-Containern

          Eine schnelle Einführung in das Linux-Dateisystem für Windows-Benutzer.

          Eine Einführung in Cockpit, ein browserbasiertes Verwaltungstool für Linux

          Zorin OS für Linux-Neulinge