aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Zurek <pierrezurek@gmail.com>2010-10-17 22:39:37 +0200
committerRicardo Cerqueira <cyanogenmod@cerqueira.org>2012-07-10 22:44:16 +0100
commit076aeff4ec56b246e31ffa2c1ddf919d2c10817f (patch)
tree2f04bf31c029a8b3d187c287e8d0979f8c59302a
parent743c92dc05abd68b40d6d2b220eede17de7a1073 (diff)
downloadsystem_core-076aeff4ec56b246e31ffa2c1ddf919d2c10817f.tar.gz
system_core-076aeff4ec56b246e31ffa2c1ddf919d2c10817f.tar.bz2
system_core-076aeff4ec56b246e31ffa2c1ddf919d2c10817f.zip
ADB Logcat colored output.
This patch adds a new '-C' option to logcat so that the output is colored with colors similar to the ones in DDMS. Simply type "adb logcat -C" to use it. Works well with bash in gnome-terminal. Change-Id: Ie72199ecca0e04f2082c993f5763646bb09da61ea
-rw-r--r--include/cutils/logprint.h7
-rw-r--r--liblog/logprint.c82
-rw-r--r--logcat/logcat.cpp14
3 files changed, 87 insertions, 16 deletions
diff --git a/include/cutils/logprint.h b/include/cutils/logprint.h
index 2b1e1c51..d92faa5e 100644
--- a/include/cutils/logprint.h
+++ b/include/cutils/logprint.h
@@ -38,6 +38,11 @@ typedef enum {
FORMAT_LONG,
} AndroidLogPrintFormat;
+typedef enum {
+ OUTPUT_COLOR_ON = 0,
+ OUTPUT_COLOR_OFF,
+} AndroidLogColoredOutput;
+
typedef struct AndroidLogFormat_t AndroidLogFormat;
typedef struct AndroidLogEntry_t {
@@ -58,6 +63,8 @@ void android_log_format_free(AndroidLogFormat *p_format);
void android_log_setPrintFormat(AndroidLogFormat *p_format,
AndroidLogPrintFormat format);
+void android_log_setColoredOutput(AndroidLogFormat *p_format);
+
/**
* Returns FORMAT_OFF on invalid string
*/
diff --git a/liblog/logprint.c b/liblog/logprint.c
index 6fac84b4..a3d81a9a 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -17,6 +17,13 @@
#define _GNU_SOURCE /* for asprintf */
+#define COLOR_BLUE 75
+#define COLOR_DEFAULT 231
+#define COLOR_GREEN 40
+#define COLOR_ORANGE 166
+#define COLOR_RED 196
+#define COLOR_YELLOW 226
+
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
@@ -39,6 +46,7 @@ struct AndroidLogFormat_t {
android_LogPriority global_pri;
FilterInfo *filters;
AndroidLogPrintFormat format;
+ AndroidLogColoredOutput colored_output;
};
static FilterInfo * filterinfo_new(const char * tag, android_LogPriority pri)
@@ -118,6 +126,23 @@ static char filterPriToChar (android_LogPriority pri)
}
}
+static int colorFromPri (android_LogPriority pri)
+{
+ switch (pri) {
+ case ANDROID_LOG_VERBOSE: return COLOR_DEFAULT;
+ case ANDROID_LOG_DEBUG: return COLOR_BLUE;
+ case ANDROID_LOG_INFO: return COLOR_GREEN;
+ case ANDROID_LOG_WARN: return COLOR_ORANGE;
+ case ANDROID_LOG_ERROR: return COLOR_RED;
+ case ANDROID_LOG_FATAL: return COLOR_RED;
+ case ANDROID_LOG_SILENT: return COLOR_DEFAULT;
+
+ case ANDROID_LOG_DEFAULT:
+ case ANDROID_LOG_UNKNOWN:
+ default: return COLOR_DEFAULT;
+ }
+}
+
static android_LogPriority filterPriForTag(
AndroidLogFormat *p_format, const char *tag)
{
@@ -174,6 +199,7 @@ AndroidLogFormat *android_log_format_new()
p_ret->global_pri = ANDROID_LOG_VERBOSE;
p_ret->format = FORMAT_BRIEF;
+ p_ret->colored_output = OUTPUT_COLOR_OFF;
return p_ret;
}
@@ -202,6 +228,11 @@ void android_log_setPrintFormat(AndroidLogFormat *p_format,
p_format->format=format;
}
+void android_log_setColoredOutput(AndroidLogFormat *p_format)
+{
+ p_format->colored_output = OUTPUT_COLOR_ON;
+}
+
/**
* Returns FORMAT_OFF on invalid string
*/
@@ -739,20 +770,32 @@ char *android_log_formatLogLine (
*/
size_t prefixLen, suffixLen;
+ size_t prefixColorLen = 0;
+ char * prefixBufTmp = prefixBuf;
+ size_t prefixBufTmpRemainLen = sizeof(prefixBuf);
+
+ if (p_format->colored_output == OUTPUT_COLOR_ON) {
+ prefixColorLen = snprintf(prefixBufTmp, prefixBufTmpRemainLen, "%c[%d;%d;%dm", 0x1B, 38, 5, colorFromPri(entry->priority));
+ if(prefixColorLen >= prefixBufTmpRemainLen)
+ prefixColorLen = prefixBufTmpRemainLen - 1;
+ prefixBufTmp += prefixColorLen;
+ prefixBufTmpRemainLen -= prefixColorLen;
+ }
+
switch (p_format->format) {
case FORMAT_TAG:
- prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
+ prefixLen = snprintf(prefixBufTmp, prefixBufTmpRemainLen,
"%c/%-8s: ", priChar, entry->tag);
strcpy(suffixBuf, "\n"); suffixLen = 1;
break;
case FORMAT_PROCESS:
- prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
+ prefixLen = snprintf(prefixBufTmp, prefixBufTmpRemainLen,
"%c(%5d) ", priChar, entry->pid);
suffixLen = snprintf(suffixBuf, sizeof(suffixBuf),
" (%s)\n", entry->tag);
break;
case FORMAT_THREAD:
- prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
+ prefixLen = snprintf(prefixBufTmp, prefixBufTmpRemainLen,
"%c(%5d:%5d) ", priChar, entry->pid, entry->tid);
strcpy(suffixBuf, "\n");
suffixLen = 1;
@@ -764,21 +807,21 @@ char *android_log_formatLogLine (
suffixLen = 1;
break;
case FORMAT_TIME:
- prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
+ prefixLen = snprintf(prefixBufTmp, prefixBufTmpRemainLen,
"%s.%03ld %c/%-8s(%5d): ", timeBuf, entry->tv_nsec / 1000000,
priChar, entry->tag, entry->pid);
strcpy(suffixBuf, "\n");
suffixLen = 1;
break;
case FORMAT_THREADTIME:
- prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
+ prefixLen = snprintf(prefixBufTmp, prefixBufTmpRemainLen,
"%s.%03ld %5d %5d %c %-8s: ", timeBuf, entry->tv_nsec / 1000000,
entry->pid, entry->tid, priChar, entry->tag);
strcpy(suffixBuf, "\n");
suffixLen = 1;
break;
case FORMAT_LONG:
- prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
+ prefixLen = snprintf(prefixBufTmp, prefixBufTmpRemainLen,
"[ %s.%03ld %5d:%5d %c/%-8s ]\n",
timeBuf, entry->tv_nsec / 1000000, entry->pid,
entry->tid, priChar, entry->tag);
@@ -788,7 +831,7 @@ char *android_log_formatLogLine (
break;
case FORMAT_BRIEF:
default:
- prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
+ prefixLen = snprintf(prefixBufTmp, prefixBufTmpRemainLen,
"%c/%-8s(%5d): ", priChar, entry->tag, entry->pid);
strcpy(suffixBuf, "\n");
suffixLen = 1;
@@ -800,11 +843,22 @@ char *android_log_formatLogLine (
* possibly causing heap corruption. To avoid this we double check and
* set the length at the maximum (size minus null byte)
*/
- if(prefixLen >= sizeof(prefixBuf))
- prefixLen = sizeof(prefixBuf) - 1;
+ if(prefixLen >= prefixBufTmpRemainLen)
+ prefixLen = prefixBufTmpRemainLen - 1;
if(suffixLen >= sizeof(suffixBuf))
suffixLen = sizeof(suffixBuf) - 1;
+ size_t suffixColorLen = 0;
+ char * suffixBufTmp = suffixBuf + suffixLen;
+ size_t suffixBufTmpRemainLen = sizeof(suffixBuf) - suffixLen;
+
+ if (p_format->colored_output == OUTPUT_COLOR_ON) {
+ suffixColorLen = snprintf(suffixBufTmp, suffixBufTmpRemainLen, "%c[%dm", 0x1B, 0);
+ if(suffixColorLen >= suffixBufTmpRemainLen)
+ suffixColorLen = suffixBufTmpRemainLen - 1;
+ }
+
+
/* the following code is tragically unreadable */
size_t numLines;
@@ -831,7 +885,7 @@ char *android_log_formatLogLine (
// this is an upper bound--newlines in message may be counted
// extraneously
- bufferSize = (numLines * (prefixLen + suffixLen)) + entry->messageLen + 1;
+ bufferSize = (numLines * (prefixColorLen + prefixLen + suffixLen + suffixColorLen)) + entry->messageLen + 1;
if (defaultBufferSize >= bufferSize) {
ret = defaultBuffer;
@@ -850,11 +904,11 @@ char *android_log_formatLogLine (
if (prefixSuffixIsHeaderFooter) {
strcat(p, prefixBuf);
- p += prefixLen;
+ p += prefixColorLen + prefixLen;
strncat(p, entry->message, entry->messageLen);
p += entry->messageLen;
strcat(p, suffixBuf);
- p += suffixLen;
+ p += suffixLen + suffixColorLen;
} else {
while(pm < (entry->message + entry->messageLen)) {
const char *lineStart;
@@ -867,11 +921,11 @@ char *android_log_formatLogLine (
lineLen = pm - lineStart;
strcat(p, prefixBuf);
- p += prefixLen;
+ p += prefixColorLen + prefixLen;
strncat(p, lineStart, lineLen);
p += lineLen;
strcat(p, suffixBuf);
- p += suffixLen;
+ p += suffixLen + suffixColorLen;
if (*pm == '\n') pm++;
}
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index b71ce86a..ef637c47 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -410,7 +410,8 @@ static void show_help(const char *cmd)
" -b <buffer> Request alternate ring buffer, 'main', 'system', 'radio'\n"
" or 'events'. Multiple -b parameters are allowed and the\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"
+ " -C colored output");
fprintf(stderr,"\nfilterspecs are a series of \n"
@@ -452,6 +453,11 @@ static int setLogFormat(const char * formatString)
return 0;
}
+static void setColoredOutput()
+{
+ android_log_setColoredOutput(g_logformat);
+}
+
extern "C" void logprint_run_tests(void);
int main(int argc, char **argv)
@@ -481,7 +487,7 @@ int main(int argc, char **argv)
for (;;) {
int ret;
- ret = getopt(argc, argv, "cdt:gsQf:r::n:v:b:B");
+ ret = getopt(argc, argv, "cdt:gsQf:r::n:v:b:BC");
if (ret < 0) {
break;
@@ -511,6 +517,10 @@ int main(int argc, char **argv)
getLogSize = 1;
break;
+ case 'C':
+ setColoredOutput();
+ break;
+
case 'b': {
char* buf = (char*) malloc(strlen(LOG_FILE_DIR) + strlen(optarg) + 1);
strcpy(buf, LOG_FILE_DIR);