Merge changes I2dd4ec10,I8b9688a9

* changes:
  logcat: replace write() calls with WriteFully()
  Add android_logger_get_log_consumed_size() and report it in logcat
This commit is contained in:
Tom Cherry 2020-08-05 23:27:03 +00:00 committed by Gerrit Code Review
commit 539f5e3880
6 changed files with 90 additions and 40 deletions

View file

@ -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;

View file

@ -35,6 +35,7 @@
#include <string>
#include <android-base/parseint.h>
#include <private/android_logger.h>
#include "logger.h"
@ -160,26 +161,56 @@ 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];
snprintf(buf, sizeof(buf), "getLogSize %" PRIu32, log_id);
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;
}
long android_logger_get_log_size(struct logger* logger) {
return GetLogSize(logger, LogSizeType::kAllotted);
}
long android_logger_get_log_readable_size(struct logger* logger) {
return GetLogSize(logger, LogSizeType::kReadable);
}
long android_logger_get_log_consumed_size(struct logger* logger) {
return GetLogSize(logger, LogSizeType::kConsumed);
}
int android_logger_set_log_size(struct logger* logger, unsigned long size) {
@ -194,31 +225,6 @@ int android_logger_set_log_size(struct logger* logger, unsigned long size) {
return check_log_success(buf, SendLogdControlMessage(buf, sizeof(buf)));
}
/*
* 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) {
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;
}
return atol(buf);
}
int android_logger_get_log_version(struct logger*) {
return 4;
}

View file

@ -64,6 +64,7 @@ using android::base::ParseByteCount;
using android::base::ParseUint;
using android::base::Split;
using android::base::StringPrintf;
using android::base::WriteFully;
class Logcat {
public:
@ -864,8 +865,7 @@ int Logcat::Run(int argc, char** argv) {
if (consolePipe) {
// need the trailing '\0'
if (!android::base::WriteFully(fd, pipePurpose.c_str(),
pipePurpose.size() + 1)) {
if (!WriteFully(fd, pipePurpose.c_str(), pipePurpose.size() + 1)) {
close(fd);
return EXIT_FAILURE;
}
@ -1064,19 +1064,23 @@ 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);
TEMP_FAILURE_RETRY(write(output_fd_.get(), str.data(), str.length()));
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);
if (!WriteFully(output_fd_, str.data(), str.length())) {
error(EXIT_FAILURE, errno, "Failed to write to output fd");
}
}
}
}
@ -1146,7 +1150,9 @@ int Logcat::Run(int argc, char** argv) {
if (*cp == '\n') ++cp;
size_t len = strlen(cp);
TEMP_FAILURE_RETRY(write(output_fd_.get(), cp, len));
if (!WriteFully(output_fd_, cp, len)) {
error(EXIT_FAILURE, errno, "Failed to write to output fd");
}
return EXIT_SUCCESS;
}
@ -1190,7 +1196,9 @@ If you have enabled significant logging, look into using the -G option to increa
PrintDividers(log_msg.id(), printDividers);
if (print_binary_) {
TEMP_FAILURE_RETRY(write(output_fd_.get(), &log_msg, log_msg.len()));
if (!WriteFully(output_fd_, &log_msg, log_msg.len())) {
error(EXIT_FAILURE, errno, "Failed to write to output fd");
}
} else {
ProcessBuffer(&log_msg);
}

View file

@ -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();

View file

@ -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);

View file

@ -544,7 +544,7 @@ class LogStatistics {
bool ShouldPrune(log_id id, unsigned long max_size, unsigned long* prune_rows) const
EXCLUDES(lock_);
// Snapshot of the sizes for a given log buffer.
// Return the consumed size of the given buffer.
size_t Sizes(log_id_t id) const EXCLUDES(lock_) {
auto lock = std::lock_guard{lock_};
if (overhead_[id]) {
@ -552,6 +552,13 @@ class LogStatistics {
}
return mSizes[id];
}
// Return the uncompressed size of the contents of the given buffer.
size_t SizeReadable(log_id_t id) const EXCLUDES(lock_) {
auto lock = std::lock_guard{lock_};
return mSizes[id];
}
// TODO: Get rid of this entirely.
static size_t sizesTotal() {
return SizesTotal;