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

Commit 06e111a1 authored by Tom Cherry's avatar Tom Cherry
Browse files

Add android_logger_get_log_consumed_size() and report it in logcat

There is an existing API, android_logger_get_log_readable_size() which
historically reported the consumed amount of data for the chatty log
buffer, since consumed and readable are synonymous with that buffer
type.

With log compression, readable and consumed are not synonymous, since
the readable log size is the uncompressed log size whereas the
consumed log size is the compressed log size.

This change adds android_logger_get_log_consumed_size() which returns
the consumed log size and makes android_logger_get_log_readable_size()
return the readable log size.  Note that these values are identical if
compression is not used.

It adds both statistics to logcat:

    main: ring buffer is 1 MiB (429 KiB consumed, 817 KiB readable)
    radio: ring buffer is 1 MiB (339 KiB consumed, 715 KiB readable)
    ...

Test: logcat prints the right values with compression and chatty
Change-Id: I8b9688a987736204e2e6026e8635fbd1a5e68bb7
parent 0d847fb4
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -81,10 +81,17 @@ struct logger;

log_id_t android_logger_get_id(struct logger* logger);

/* Clears the given log buffer. */
int android_logger_clear(struct logger* logger);
/* Return the allotted size for the given log buffer. */
long android_logger_get_log_size(struct logger* logger);
/* Set the allotted size for the given log buffer. */
int android_logger_set_log_size(struct logger* logger, unsigned long size);
/* Return the actual, uncompressed size that can be read from the given log buffer. */
long android_logger_get_log_readable_size(struct logger* logger);
/* Return the actual, compressed size that the given log buffer is consuming. */
long android_logger_get_log_consumed_size(struct logger* logger);
/* Deprecated.  Always returns '4' regardless of input. */
int android_logger_get_log_version(struct logger* logger);

struct logger_list;
+35 −29
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@

#include <string>

#include <android-base/parseint.h>
#include <private/android_logger.h>

#include "logger.h"
@@ -160,63 +161,68 @@ int android_logger_clear(struct logger* logger) {
  return check_log_success(buf, SendLogdControlMessage(buf, sizeof(buf)));
}

/* returns the total size of the log's ring buffer */
long android_logger_get_log_size(struct logger* logger) {
enum class LogSizeType : uint32_t {
  kAllotted = 0,
  kReadable,
  kConsumed,
};

static long GetLogSize(struct logger* logger, LogSizeType type) {
  if (!android_logger_is_logd(logger)) {
    return -EINVAL;
  }

  uint32_t log_id = android_logger_get_id(logger);
  char buf[512];
  switch (type) {
    case LogSizeType::kAllotted:
      snprintf(buf, sizeof(buf), "getLogSize %" PRIu32, log_id);
      break;
    case LogSizeType::kReadable:
      snprintf(buf, sizeof(buf), "getLogSizeReadable %" PRIu32, log_id);
      break;
    case LogSizeType::kConsumed:
      snprintf(buf, sizeof(buf), "getLogSizeUsed %" PRIu32, log_id);
      break;
    default:
      abort();
  }

  ssize_t ret = SendLogdControlMessage(buf, sizeof(buf));
  if (ret < 0) {
    return ret;
  }

  if ((buf[0] < '0') || ('9' < buf[0])) {
  long size;
  if (!android::base::ParseInt(buf, &size)) {
    return -1;
  }

  return atol(buf);
  return size;
}

int android_logger_set_log_size(struct logger* logger, unsigned long size) {
  if (!android_logger_is_logd(logger)) {
    return -EINVAL;
long android_logger_get_log_size(struct logger* logger) {
  return GetLogSize(logger, LogSizeType::kAllotted);
}

  uint32_t log_id = android_logger_get_id(logger);
  char buf[512];
  snprintf(buf, sizeof(buf), "setLogSize %" PRIu32 " %lu", log_id, size);
long android_logger_get_log_readable_size(struct logger* logger) {
  return GetLogSize(logger, LogSizeType::kReadable);
}

  return check_log_success(buf, SendLogdControlMessage(buf, sizeof(buf)));
long android_logger_get_log_consumed_size(struct logger* logger) {
  return GetLogSize(logger, LogSizeType::kConsumed);
}

/*
 * returns the readable size of the log's ring buffer (that is, amount of the
 * log consumed)
 */
long android_logger_get_log_readable_size(struct logger* logger) {
int android_logger_set_log_size(struct logger* logger, unsigned long size) {
  if (!android_logger_is_logd(logger)) {
    return -EINVAL;
  }

  uint32_t log_id = android_logger_get_id(logger);
  char buf[512];
  snprintf(buf, sizeof(buf), "getLogSizeUsed %" PRIu32, log_id);

  ssize_t ret = SendLogdControlMessage(buf, sizeof(buf));
  if (ret < 0) {
    return ret;
  }

  if ((buf[0] < '0') || ('9' < buf[0])) {
    return -1;
  }
  snprintf(buf, sizeof(buf), "setLogSize %" PRIu32 " %lu", log_id, size);

  return atol(buf);
  return check_log_success(buf, SendLogdControlMessage(buf, sizeof(buf)));
}

int android_logger_get_log_version(struct logger*) {
+6 −4
Original line number Diff line number Diff line
@@ -1064,18 +1064,20 @@ int Logcat::Run(int argc, char** argv) {
        if (getLogSize) {
            long size = android_logger_get_log_size(logger);
            long readable = android_logger_get_log_readable_size(logger);
            long consumed = android_logger_get_log_consumed_size(logger);

            if (size < 0 || readable < 0) {
                ReportErrorName(buffer_name, security_buffer_selected, &get_size_failures);
            } else {
                auto size_format = format_of_size(size);
                auto readable_format = format_of_size(readable);
                auto consumed_format = format_of_size(consumed);
                std::string str = android::base::StringPrintf(
                        "%s: ring buffer is %lu %sB (%lu %sB consumed),"
                        "%s: ring buffer is %lu %sB (%lu %sB consumed, %lu %sB readable),"
                        " max entry is %d B, max payload is %d B\n",
                        buffer_name, size_format.first, size_format.second, readable_format.first,
                        readable_format.second, (int)LOGGER_ENTRY_MAX_LEN,
                        (int)LOGGER_ENTRY_MAX_PAYLOAD);
                        buffer_name, size_format.first, size_format.second, consumed_format.first,
                        consumed_format.second, readable_format.first, readable_format.second,
                        (int)LOGGER_ENTRY_MAX_LEN, (int)LOGGER_ENTRY_MAX_PAYLOAD);
                TEMP_FAILURE_RETRY(write(output_fd_.get(), str.data(), str.length()));
            }
        }
+21 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ CommandListener::CommandListener(LogBuffer* buf, LogTags* tags, PruneList* prune
    registerCmd(new ClearCmd(this));
    registerCmd(new GetBufSizeCmd(this));
    registerCmd(new SetBufSizeCmd(this));
    registerCmd(new GetBufSizeReadableCmd(this));
    registerCmd(new GetBufSizeUsedCmd(this));
    registerCmd(new GetStatisticsCmd(this));
    registerCmd(new SetPruneListCmd(this));
@@ -136,6 +137,26 @@ int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc,
    return 0;
}

int CommandListener::GetBufSizeReadableCmd::runCommand(SocketClient* cli, int argc, char** argv) {
    setname();
    if (argc < 2) {
        cli->sendMsg("Missing Argument");
        return 0;
    }

    int id = atoi(argv[1]);
    if (id < LOG_ID_MIN || LOG_ID_MAX <= id) {
        cli->sendMsg("Range Error");
        return 0;
    }

    unsigned long size = stats()->SizeReadable((log_id_t)id);
    char buf[512];
    snprintf(buf, sizeof(buf), "%lu", size);
    cli->sendMsg(buf);
    return 0;
}

int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient* cli, int argc,
                                                   char** argv) {
    setname();
+1 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ class CommandListener : public FrameworkListener {
    LogCmd(Clear, clear);
    LogCmd(GetBufSize, getLogSize);
    LogCmd(SetBufSize, setLogSize);
    LogCmd(GetBufSizeReadable, getLogSizeReadable);
    LogCmd(GetBufSizeUsed, getLogSizeUsed);
    LogCmd(GetStatistics, getStatistics);
    LogCmd(GetPruneList, getPruneList);
Loading