diff options
| author | Pierre Zurek <pierrezurek@gmail.com> | 2010-10-17 22:39:37 +0200 |
|---|---|---|
| committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2012-07-10 22:44:16 +0100 |
| commit | 076aeff4ec56b246e31ffa2c1ddf919d2c10817f (patch) | |
| tree | 2f04bf31c029a8b3d187c287e8d0979f8c59302a | |
| parent | 743c92dc05abd68b40d6d2b220eede17de7a1073 (diff) | |
| download | system_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.h | 7 | ||||
| -rw-r--r-- | liblog/logprint.c | 82 | ||||
| -rw-r--r-- | logcat/logcat.cpp | 14 |
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); |
