1117397Skan// Copyright 2016 The Fuchsia Authors. All rights reserved. 2117397Skan// Use of this source code is governed by a BSD-style license that can be 3169691Skan// found in the LICENSE file. 4169691Skan 5117397Skan#include <errno.h> 6117397Skan#include <stdio.h> 7117397Skan#include <stdlib.h> 8117397Skan#include <string.h> 9117397Skan#include <unistd.h> 10117397Skan 11117397Skan#include <zircon/syscalls.h> 12117397Skan#include <zircon/syscalls/log.h> 13117397Skan 14117397Skanvoid usage(void) { 15117397Skan fprintf(stderr, 16117397Skan "usage: dlog dump the zircon debug log\n" 17117397Skan "\n" 18117397Skan "options: -f don't exit, keep waiting for new messages\n" 19169691Skan " -p <pid> only show messages from specified pid\n" 20117397Skan " -t only show the text of messages (no metadata)\n" 21117397Skan " -h show help\n" 22117397Skan ); 23117397Skan} 24117397Skan 25117397Skanint main(int argc, char** argv) { 26117397Skan bool tail = false; 27117397Skan bool filter_pid = false; 28117397Skan bool plain = false; 29117397Skan zx_koid_t pid = 0; 30117397Skan zx_handle_t h; 31169691Skan 32117397Skan while (argc > 1) { 33169691Skan if (!strcmp(argv[1], "-h")) { 34169691Skan usage(); 35117397Skan return 0; 36132720Skan } else if (!strcmp(argv[1], "-f")) { 37132720Skan tail = true; 38132720Skan } else if (!strcmp(argv[1], "-t")) { 39132720Skan plain = true; 40132720Skan } else if (!strcmp(argv[1], "-p")) { 41132720Skan argc--; 42117397Skan argv++; 43132720Skan if (argc < 2) { 44132720Skan usage(); 45132720Skan return -1; 46132720Skan } 47132720Skan errno = 0; 48132720Skan pid = strtoull(argv[1], NULL, 0); 49132720Skan if (errno) { 50132720Skan fprintf(stderr, "dlog: invalid pid\n"); 51132720Skan return -1; 52132720Skan } 53132720Skan filter_pid = true; 54132720Skan } else { 55132720Skan usage(); 56132720Skan return -1; 57132720Skan } 58132720Skan argc--; 59132720Skan argv++; 60132720Skan } 61132720Skan 62132720Skan if (zx_debuglog_create(ZX_HANDLE_INVALID, ZX_LOG_FLAG_READABLE, &h) < 0) { 63132720Skan fprintf(stderr, "dlog: cannot open debug log\n"); 64132720Skan return -1; 65132720Skan } 66132720Skan 67132720Skan char buf[ZX_LOG_RECORD_MAX]; 68132720Skan zx_log_record_t* rec = (zx_log_record_t*)buf; 69132720Skan for (;;) { 70132720Skan zx_status_t status; 71117397Skan if ((status = zx_debuglog_read(h, 0, rec, ZX_LOG_RECORD_MAX)) < 0) { 72117397Skan if ((status == ZX_ERR_SHOULD_WAIT) && tail) { 73132720Skan zx_object_wait_one(h, ZX_LOG_READABLE, ZX_TIME_INFINITE, NULL); 74132720Skan continue; 75132720Skan } 76132720Skan break; 77132720Skan } 78117397Skan if (filter_pid && (pid != rec->pid)) { 79132720Skan continue; 80132720Skan } 81132720Skan if (!plain) { 82132720Skan char tmp[32]; 83132720Skan size_t len = snprintf(tmp, sizeof(tmp), "[%05d.%03d] ", 84132720Skan (int)(rec->timestamp / 1000000000ULL), 85132720Skan (int)((rec->timestamp / 1000000ULL) % 1000ULL)); 86132720Skan write(1, tmp, (len > sizeof(tmp) ? sizeof(tmp) : len)); 87132720Skan } 88132720Skan write(1, rec->data, rec->datalen); 89132720Skan if ((rec->datalen == 0) || (rec->data[rec->datalen - 1] != '\n')) { 90132720Skan write(1, "\n", 1); 91132720Skan } 92132720Skan } 93132720Skan return 0; 94132720Skan} 95132720Skan