Was ist das Format der Android-Protokolle?

8

Ich versuche, Daten über mein Telefon zu sammeln, indem ich die Protokolldateien analysiere /dev/log. Ich schaue speziell auf /dev/log/main. Ich habe immer gedacht, dass jedes vernünftige Protokollformat einfacher Text ist, aber diese Dateien scheinen entweder binär oder in einem Zeichensatz zu sein, den weder ich noch meine Linux-Texteditoren identifizieren können.

Was ist das Format?

Hier ein paar Screenshots:

  • Hier ist zunächst ein Ausschnitt aus dem Protokoll, wie es interpretiert wird vim( ^@bezieht sich auf das Null-Byte; ich bin mir bei den anderen farbigen Kontrollsequenzen nicht sicher): vim

  • Als Nächstes sieht das Protokoll in einem Hex-Editor folgendermaßen aus: Hex-Editor

Ich benutze ein Galaxy Nexus mit Jelly Bean. Die Protokolle wurden mit root und einem Terminalemulator gesammelt, da aLogcat anscheinend nicht root verwendet und daher nicht auf alle Protokollinformationen zugreifen kann.

Scott Severance
quelle

Antworten:

6

Wenn Sie vernünftige Informationen wünschen, empfehle ich vernünftige Befehle :) (nichts für ungut, nur ein Scherz). Die Frage sollte also lauten:

Wie erhalte ich Protokollinformationen von einem Android-Gerät?

Und jetzt sind wir auf der besseren Seite. Es gibt mehrere Ansätze, die verwendet werden können:

  • Verwenden Sie Apps, um (farbcodierte) Protokollinformationen anzuzeigen
  • Verwenden Sie ADB (Teil des Android SDK), um dieselben Informationen aus der Ferne zu extrahieren
  • Verwenden Sie ssh von der Fernbedienung (oder einer lokalen Terminal-App), um die Informationen direkt vom Gerät abzurufen

Um dieses Thema vollständig zu behandeln, ist mehr als diese einfache Antwort erforderlich (bei Interesse finden Sie z. B. detailliertere Informationen auf vielen Websites oder in Andrew Hoogs Buch Android Forensics: Untersuchung, Analyse und mobile Sicherheit für Google Android , das ich hatte Ehre, ins Deutsche zu übersetzen. Es gibt wahrscheinlich auch viele andere Quellen.

Ich werde hier nur einige Beispiele nennen, um Ihnen den Einstieg zu erleichtern:

Apps nutzen

Die wahrscheinlich bekannteste App in diesem Zusammenhang ist aLogcat , die kostenlos im Playstore erhältlich ist (und der Entwickler nimmt Ihre Spende für die andere Variante derselben App gerne entgegen). Unter 1 finden Sie einen Screenshot . Mit der App können Sie die Protokolle filtern, die Aufzeichnung von Protokollnachrichten starten / stoppen und sogar die aufgezeichneten Schnipsel auf Ihrer SD-Karte speichern - natürlich im Klartext, wie Sie es gewünscht haben.

Eine weitere App in diesem Abschnitt ist Log Collector , die einfach versucht, das gesamte verfügbare Protokoll abzurufen und über das Freigabemenü 2 zu senden .

aLogCat Protokollsammler

Die Android Debug Bridge (ADB)

Das Android Software Development Kit (SDK) enthält den adbBefehl für verschiedene Aufgaben. Unter anderem bietet es die Möglichkeit adb shell, Befehle auf dem Gerät auszuführen. Auf diese Weise können Sie auch die gewünschten Protokollinformationen erfassen: Stellen Sie den Befehlen einfach das Präfix mit voran adb shell.

Eingabeaufforderung auf dem Gerät

Mit einer Terminal-App (z. B. Android Terminal Emulator oder Terminal IDE ) können Sie direkt an der Eingabeaufforderung lokal auf Ihrem Gerät auf die Protokolle zugreifen. Etwas komfortabler können Sie einen SSH-Server (z. B. DroidSSHd oder DropBear SSH Server ) auf Ihrem Gerät ausführen und von Ihrem Computer aus darauf zugreifen. Auf diese Weise können Sie auf einem großen Bildschirm arbeiten und gleichzeitig Ihre Protokolle untersuchen.

Befehle zum Zugriff auf Ihre Protokollinformationen

Es gibt viele leistungsstarke Befehle, mit denen Sie über die Befehlszeile auf Ihre Protokollinformationen zugreifen können, und ich werde hier nur einige Beispiele nennen.

dmesg

Der dmesgBefehl extrahiert das Kernelprotokoll:

$ dmesg
<6>[82839.126586] PM: Syncing filesystems ... done.
<7>[82839.189056] PM: Preparing system for mem sleep
<4>[82839.189361] Freezing user space processes ... (elapsed 0.05 seconds) done.
<4>[82839.240661] Freezing remaining freezable tasks ... (elapsed 0.00 seconds) done.
<7>[82839.242279] PM: Entering mem sleep
<4>[82839.242889] Suspending console(s) (use no_console_suspend to debug)
<7>[82839.252410] vfp_pm_save_context: saving vfp state
<6>[82839.252716] PM: Resume timer in 26 secs (864747 ticks at 32768 ticks/sec.)
<6>[82842.091369] Successfully put all powerdomains to target state
<6>[82842.092468] wakeup wake lock: wifi_wake

logcat

Mit logcatkönnen Sie auf viele Protokollierungsinformationen zugreifen. In den meisten Fällen ist jedoch root erforderlich. Es verfügt über einige Parameter zum Filtern der Informationen, z. B. durch Auswahl des zu lesenden Protokollpuffers -b. Bitte lesen Sie die Informationen auf der Entwicklerseite von logcat für Details. Um Ihnen zwei Beispiele zu geben: logcat -b eventswürde Ereignisse oder logcat -b radioInformationen zum Funkmodul Ihres Geräts auflisten.

dumpsys und dumpstate

Die beiden Befehle dumpsysund dumpstategeben Sie detaillierte Systeminformationen:

$ dumpsys
Currently running services:
    LocationProxyService
    SurfaceFlinger
    accessibility
    account
    activity
<snip>
DUMP OF SERVICE account:
Accounts: 1
    Account {[email protected], type=com.google}
<snip>
DUMP OF SERVICE alarm:

$ dumpstate
========================================================
== dumpstate: 2012-08-18 23:39:53
========================================================
Build: Gingerbread GWK74 - CyanogenMilestone2
Bootloader: 0x0000
Radio: unknown
<snip>
------ MEMORY INFO (/proc/meminfo) ------
MemTotal: 487344 kB
MemFree:   10436 kB
Buffers:   14136 kB
Cached:    145460 kB
<snip>

Fehlerbericht

Und wenn Sie zu faul sind, um sich an alle zu erinnern, verwenden Sie einfach den bugreportBefehl - der alle oben genannten Elemente aufruft und für einen netten, summenden Fehlerbericht an den Entwickler bündelt ...

Natürlich können Sie die Ausgabe all dieser Befehle in eine Datei umleiten, um sie auf Ihren Computer zu kopieren, und in den meisten Fällen sollten Sie dies tun - da Ihr Bildschirmpuffer viel zu klein wäre, um alles zu verarbeiten: bugreport > /mnt/sdcard/bugreport.txtwäre ein Beispiel dafür dieser Teil.

Izzy
quelle
$ dmesgoder dmsg? Es muss einen Tippfehler in einem dieser geben :)
jadkik94
@ jadkik94 das ist mein Favorit, um zu überprüfen, ob jemand etwas bemerkt ... Nein, vergiss den zweiten Teil - und danke, dass du es bemerkt hast :) Behoben.
Izzy
Ich vergesse immer, welches das richtige ist :) und immer zu faul, um danach zu suchen ...: P
jadkik94
3
Alle begrüßen die Bash-Auto-Vervollständigung :) Außerdem: Ich habe die Beispiele aus meinem Buch kopiert und in ein Beispiel aus dem wirklichen Leben eingefügt, sodass ich wusste, welche die richtige Version sein musste. ..
Izzy
2
Die Änderung hatte mit einer neuen Berechtigung zu tun, die zum Lesen von Protokollen aus anderen Apps erforderlich war . Derzeit kann aLogcat nur seine eigenen Protokolle lesen. Damit es Protokolle von anderen Apps lesen kann, müssen Sie ihm diese neuen Berechtigungen wie adb shell pm grant com.nolanlawson.logcat android.permission.READ_LOGS
folgt
4

Für Entwickler (oder andere interessierte Parteien), die diese Rohdatei analysieren müssen, sind hier einige Ressourcen aufgeführt:

Das tatsächliche Format des Protokollformats ist detailliert unter:

Eine Kopie der relevanten Teile, leicht kommentiert und für Ihre Bequemlichkeit nachbestellt:

#define LOGGER_ENTRY_MAX_LEN (5*1024)

struct log_msg {
    union {
        /* Maximum size of entry: 5121 bytes */
        unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];

        struct logger_entry_v3 entry;
        struct logger_entry_v3 entry_v3;
        struct logger_entry_v2 entry_v2;
        struct logger_entry entry_v1;
    } __attribute__((aligned(4)));
}
/*
 * The userspace structure for version 1 of the logger_entry ABI.
 * This structure is returned to userspace by the kernel logger
 * driver unless an upgrade to a newer ABI version is requested.
 */
struct logger_entry {
    uint16_t    len;    /* length of the payload */
    uint16_t    __pad;  /* no matter what, we get 2 bytes of padding */
    int32_t     pid;    /* generating process's pid */
    int32_t     tid;    /* generating process's tid */
    int32_t     sec;    /* seconds since Epoch */
    int32_t     nsec;   /* nanoseconds */
    char        msg[0]; /* the entry's payload */
} __attribute__((__packed__));

/*
 * The userspace structure for version 2 of the logger_entry ABI.
 * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION)
 * is called with version==2; or used with the user space log daemon.
 */
struct logger_entry_v2 {
    uint16_t    len;    /* length of the payload */
    uint16_t    hdr_size; /* sizeof(struct logger_entry_v2) */
    int32_t     pid;    /* generating process's pid */
    int32_t     tid;    /* generating process's tid */
    int32_t     sec;    /* seconds since Epoch */
    int32_t     nsec;   /* nanoseconds */
    uint32_t    euid;   /* effective UID of logger */
    char        msg[0]; /* the entry's payload */
} __attribute__((__packed__));

struct logger_entry_v3 {
    uint16_t    len;    /* length of the payload */
    uint16_t    hdr_size; /* sizeof(struct logger_entry_v3) */
    int32_t     pid;    /* generating process's pid */
    int32_t     tid;    /* generating process's tid */
    int32_t     sec;    /* seconds since Epoch */
    int32_t     nsec;   /* nanoseconds */
    uint32_t    lid;    /* log id of the payload */
    char        msg[0]; /* the entry's payload */
} __attribute__((__packed__));

Sie können die unterschiedlichen Versionen anhand des dritten und des vier Bytes unterscheiden. Das Format hängt offenbar auch von der Endianness Ihrer Plattform ab. Für v1 Nachrichten, __padgleich zu 0. v2 (und v3) Nachrichten verwenden 24 ( 0x18).

Für main, radiound systemlogs msgFeld wird wie folgt interpretiert ( Quelle ):

  • Priorität: 1 Byte
  • Tag: 0 oder mehr Bytes
  • wörtlich \0als Trennzeichen
  • Nachricht: 0 oder mehr Bytes
  • wörtlich \0als Terminator

Wenn diese Nachricht abgeschnitten wird, \0fehlt möglicherweise das Trailing .

Für das eventsProtokoll msgenthält das Feld jedoch die folgenden Binärdaten:

  • Tag: 4-Byte-Integer-Schlüssel aus der Datei "/ system / etc / event-log-tags".
  • Nachricht: serialisierter Baum ausgehend vom Stammknoten. Jeder Baumknoten beginnt mit einem 1-Byte-Wert aus der AndroidEventLogType-Enumeration:
    • EVENT_TYPE_INT - Der Knotenwert ist eine 4-Byte-Ganzzahl
    • EVENT_TYPE_LONG - Der Knotenwert beträgt 8 Byte Integer
    • EVENT_TYPE_STRING - Der Knotenwert ist eine 4-Byte-Ganzzahl length, gefolgt von den lengthBytes, die eine UTF8-codierte Zeichenfolge enthalten
    • EVENT_TYPE_LIST - Der Knotenwert ist ein Einzelbyte length, gefolgt von den lengthjeweils eigenen Baumknoten AndroidEventLogType.
Lekensteyn
quelle