Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34facab8 authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

logd: liblog: logcat: Add Statistics

- logd add statistical collection and formatting
- liblog add android_logger_get_statistics call
- logcat add -S flag
- logcat add -b all

(cherry picked from commit 51a29c8d)

Change-Id: I521753b1969ecd4590c956aeeb1557d101059d67
parent 897d345b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -146,6 +146,9 @@ int android_logger_get_log_version(struct logger *logger);

struct logger_list;

ssize_t android_logger_get_statistics(struct logger_list *logger_list,
                                      char *buf, size_t len);

struct logger_list *android_logger_list_alloc(int mode,
                                              unsigned int tail,
                                              pid_t pid);
+26 −0
Original line number Diff line number Diff line
@@ -357,6 +357,32 @@ int android_logger_get_log_version(struct logger *logger UNUSED)
    return 3;
}

/*
 * returns statistics
 */
ssize_t android_logger_get_statistics(struct logger_list *logger_list,
                                      char *buf, size_t len)
{
    struct listnode *node;
    struct logger *logger;
    char *cp = buf;
    size_t remaining = len;
    size_t n;

    n = snprintf(cp, remaining, "getStatistics");
    n = min(n, remaining);
    remaining -= n;
    cp += n;

    logger_for_each(logger, logger_list) {
        n = snprintf(cp, remaining, " %d", logger->id);
        n = min(n, remaining);
        remaining -= n;
        cp += n;
    }
    return send_log_msg(NULL, NULL, buf, len);
}

struct logger_list *android_logger_list_alloc(int mode,
                                              unsigned int tail,
                                              pid_t pid)
+14 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ typedef char bool;
         logger != node_to_item(&(logger_list)->node, struct logger, node); \
         logger = node_to_item((logger)->node.next, struct logger, node))

#define UNUSED __attribute__((unused))

/* In the future, we would like to make this list extensible */
static const char *LOG_NAME[LOG_ID_MAX] = {
    [LOG_ID_MAIN] = "main",
@@ -248,6 +250,18 @@ int android_logger_get_log_version(struct logger *logger)
    return (ret < 0) ? 1 : ret;
}

/*
 * returns statistics
 */

ssize_t android_logger_get_statistics(struct logger_list *logger_list UNUSED,
                                      char *buf, size_t len)
{
    static const char unsupported[] = "18\nNot Supported\n\f";
    strncpy(buf, unsupported, len);
    return -ENOTSUP;
}

struct logger_list *android_logger_list_alloc(int mode,
                                              unsigned int tail,
                                              pid_t pid)
+93 −4
Original line number Diff line number Diff line
@@ -225,10 +225,11 @@ static void show_help(const char *cmd)
                    "  -t <count>      print only the most recent <count> lines (implies -d)\n"
                    "  -T <count>      print only the most recent <count> lines (does not imply -d)\n"
                    "  -g              get the size of the log's ring buffer and exit\n"
                    "  -b <buffer>     Request alternate ring buffer, 'main', 'system', 'radio'\n"
                    "                  or 'events'. Multiple -b parameters are allowed and the\n"
                    "  -b <buffer>     Request alternate ring buffer, 'main', 'system', 'radio',\n"
                    "                  'events' or 'all'. Multiple -b parameters are allowed and\n"
                    "                  results are interleaved. The default is -b main -b system.\n"
                    "  -B              output the log in binary");
                    "  -B              output the log in binary.\n"
                    "  -S              output statistics");


    fprintf(stderr,"\nfilterspecs are a series of \n"
@@ -278,6 +279,7 @@ int main(int argc, char **argv)
    int hasSetLogFormat = 0;
    int clearLog = 0;
    int getLogSize = 0;
    int printStatistics = 0;
    int mode = O_RDONLY;
    const char *forceFilters = NULL;
    log_device_t* devices = NULL;
@@ -303,7 +305,7 @@ int main(int argc, char **argv)
    for (;;) {
        int ret;

        ret = getopt(argc, argv, "cdt:T:gsQf:r::n:v:b:B");
        ret = getopt(argc, argv, "cdt:T:gsQf:r::n:v:b:BS");

        if (ret < 0) {
            break;
@@ -336,6 +338,39 @@ int main(int argc, char **argv)
            break;

            case 'b': {
                if (strcmp(optarg, "all") == 0) {
                    while (devices) {
                        dev = devices;
                        devices = dev->next;
                        delete dev;
                    }

                    dev = devices = new log_device_t("main", false, 'm');
                    android::g_devCount = 1;
                    if (android_name_to_log_id("system") == LOG_ID_SYSTEM) {
                        dev->next = new log_device_t("system", false, 's');
                        if (dev->next) {
                            dev = dev->next;
                            android::g_devCount++;
                        }
                    }
                    if (android_name_to_log_id("radio") == LOG_ID_RADIO) {
                        dev->next = new log_device_t("radio", false, 'r');
                        if (dev->next) {
                            dev = dev->next;
                            android::g_devCount++;
                        }
                    }
                    if (android_name_to_log_id("events") == LOG_ID_EVENTS) {
                        dev->next = new log_device_t("events", true, 'e');
                        if (dev->next) {
                            android::g_devCount++;
                            needBinary = true;
                        }
                    }
                    break;
                }

                bool binary = strcmp(optarg, "events") == 0;
                if (binary) {
                    needBinary = true;
@@ -470,6 +505,10 @@ int main(int argc, char **argv)
                }
                break;

            case 'S':
                printStatistics = 1;
                break;

            default:
                fprintf(stderr,"Unrecognized Option\n");
                android::show_help(argv[0]);
@@ -587,6 +626,56 @@ int main(int argc, char **argv)
        dev = dev->next;
    }

    if (printStatistics) {
        size_t len = 8192;
        char *buf;

        for(int retry = 32;
                (retry >= 0) && ((buf = new char [len]));
                delete [] buf, --retry) {
            android_logger_get_statistics(logger_list, buf, len);

            buf[len-1] = '\0';
            size_t ret = atol(buf) + 1;
            if (ret < 4) {
                delete [] buf;
                buf = NULL;
                break;
            }
            bool check = ret <= len;
            len = ret;
            if (check) {
                break;
            }
        }

        if (!buf) {
            perror("statistics read");
            exit(EXIT_FAILURE);
        }

        // remove trailing FF
        char *cp = buf + len - 1;
        *cp = '\0';
        bool truncated = *--cp != '\f';
        if (!truncated) {
            *cp = '\0';
        }

        // squash out the byte count
        cp = buf;
        if (!truncated) {
            while (isdigit(*cp) || (*cp == '\n')) {
                ++cp;
            }
        }

        printf("%s", cp);
        delete [] buf;
        exit(0);
    }


    if (getLogSize) {
        exit(0);
    }
+4 −2
Original line number Diff line number Diff line
@@ -13,12 +13,14 @@ LOCAL_SRC_FILES := \
    FlushCommand.cpp \
    LogBuffer.cpp \
    LogBufferElement.cpp \
    LogTimes.cpp
    LogTimes.cpp \
    LogStatistics.cpp

LOCAL_SHARED_LIBRARIES := \
    libsysutils \
    liblog \
    libcutils
    libcutils \
    libutils

LOCAL_MODULE_TAGS := optional

Loading