Index: /eclipse-workspace/asterisk-trunk/CHANGES =================================================================== --- /eclipse-workspace/asterisk-trunk/CHANGES (revision 72113) +++ /eclipse-workspace/asterisk-trunk/CHANGES (working copy) @@ -35,6 +35,7 @@ ----------- * New CLI command "core show settings" * Added 'core show channels count' CLI command. + * Added "%#" to dateformat for displaying miliseconds SIP changes ----------- Index: /eclipse-workspace/asterisk-trunk/configs/logger.conf.sample =================================================================== --- /eclipse-workspace/asterisk-trunk/configs/logger.conf.sample (revision 72113) +++ /eclipse-workspace/asterisk-trunk/configs/logger.conf.sample (working copy) @@ -9,9 +9,10 @@ [general] ; Customize the display of debug message time stamps -; this example is the ISO 8601 date format (yyyy-mm-dd HH:MM:SS) +; this example is the ISO 8601 date format (yyyy-mm-dd HH:MM:SS.msc) ; see strftime(3) Linux manual for format specifiers -;dateformat=%F %T +; additionally you can use %# for miliseconds +;dateformat=%F %T.%# ; ; This appends the hostname to the name of the log files. ;appendhostname = yes Index: /eclipse-workspace/asterisk-trunk/include/asterisk/strings.h =================================================================== --- /eclipse-workspace/asterisk-trunk/include/asterisk/strings.h (revision 72113) +++ /eclipse-workspace/asterisk-trunk/include/asterisk/strings.h (working copy) @@ -204,6 +204,18 @@ */ int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap); +/*! + \brief Replace the occurrence of the search string within the scratchpad string with the replacement string + + \return number of successful replacements, negative on error + \param scratchpad where the replacement takes place + \param scratchpadsize limit all replacements to this maximum bufferlength + \param search the string to be searched for + \param replace the string to be replaced with + \param replacements maximum number of replacements, 0 to replace all +*/ +int ast_string_replace(char *scratchpad, size_t scratchpadsize, char * const search, char * const replace, int replacements); + /*! Make sure something is true */ /*! * Determine if a string containing a boolean value is "true". Index: /eclipse-workspace/asterisk-trunk/main/asterisk.c =================================================================== --- /eclipse-workspace/asterisk-trunk/main/asterisk.c (revision 72113) +++ /eclipse-workspace/asterisk-trunk/main/asterisk.c (working copy) @@ -2280,7 +2280,7 @@ printf(" -r Connect to Asterisk on this machine\n"); printf(" -R Connect to Asterisk, and attempt to reconnect if disconnected\n"); printf(" -t Record soundfiles in /var/tmp and move them where they belong after they are done.\n"); - printf(" -T Display the time in [Mmm dd hh:mm:ss] format for each line of output to the CLI.\n"); + printf(" -T Display a timestamp for each line of output to the CLI.\n"); printf(" -v Increase verbosity (multiple v's = more verbose)\n"); printf(" -x Execute command (only valid with -r)\n"); printf("\n"); Index: /eclipse-workspace/asterisk-trunk/main/logger.c =================================================================== --- /eclipse-workspace/asterisk-trunk/main/logger.c (revision 72113) +++ /eclipse-workspace/asterisk-trunk/main/logger.c (working copy) @@ -38,6 +38,7 @@ #include #include #include +#include #if ((defined(AST_DEVMODE)) && (defined(Linux))) #include #define MAX_BACKTRACE_FRAMES 20 @@ -867,9 +868,10 @@ struct logmsg *logmsg = NULL; struct ast_str *buf = NULL; struct tm tm; - time_t t; int res = 0; va_list ap; + struct timeval tv; + char usec[5] = ""; if (!(buf = ast_str_thread_get(&log_buf, LOG_BUF_INIT_SIZE))) return; @@ -929,9 +931,11 @@ logmsg->type = LOGMSG_NORMAL; /* Create our date/time */ - time(&t); - ast_localtime(&t, &tm, NULL); + gettimeofday(&tv, 0); + ast_localtime(&tv.tv_sec, &tm, NULL); strftime(logmsg->date, sizeof(logmsg->date), dateformat, &tm); + snprintf(usec, sizeof(usec), "%.3ld", tv.tv_usec / 1000); + ast_string_replace(logmsg->date, sizeof(logmsg->date), "%#", usec, 0); /* Copy over data */ logmsg->level = level; @@ -992,6 +996,22 @@ if (!(buf = ast_str_thread_get(&verbose_buf, VERBOSE_BUF_INIT_SIZE))) return; + if (ast_opt_timestamp) { + struct tm tm; + char date[40] = "", usec[5] = ""; + char *datefmt; + struct timeval tv; + + gettimeofday(&tv, 0); + ast_localtime(&tv.tv_sec, &tm, NULL); + strftime(date, sizeof(date), dateformat, &tm); + snprintf(usec, sizeof(usec), "%.3ld", tv.tv_usec / 1000); + ast_string_replace(date, sizeof(date), "%#", usec, 0); + datefmt = alloca(strlen(date) + 3 + strlen(fmt) + 1); + sprintf(datefmt, "[%s] %s", date, fmt); + fmt = datefmt; + } + /* Build string */ va_start(ap, fmt); res = ast_str_set_va(&buf, 0, fmt, ap); @@ -1011,20 +1031,6 @@ /* Set type */ logmsg->type = LOGMSG_VERBOSE; - if (ast_opt_timestamp) { - time_t t; - struct tm tm; - char date[40]; - char *datefmt; - - time(&t); - ast_localtime(&t, &tm, NULL); - strftime(date, sizeof(date), dateformat, &tm); - datefmt = alloca(strlen(date) + 3 + strlen(fmt) + 1); - sprintf(datefmt, "[%s] %s", date, fmt); - fmt = datefmt; - } - /* Add to the list and poke the thread if possible */ if (logthread != AST_PTHREADT_NULL) { AST_LIST_LOCK(&logmsgs); Index: /eclipse-workspace/asterisk-trunk/main/utils.c =================================================================== --- /eclipse-workspace/asterisk-trunk/main/utils.c (revision 72113) +++ /eclipse-workspace/asterisk-trunk/main/utils.c (working copy) @@ -722,6 +722,50 @@ return result; } +int ast_string_replace(char *scratchpad, size_t scratchpadsize, char * const search, char * const replace, int replacements) +{ + char *scratchpadp = scratchpad; + char *searchp = NULL; + char *replacep = NULL; + char *movep = NULL; + int searchlen = (search==NULL?0:strlen(search)); + int replacelen = (replace==NULL?0:strlen(replace)); + int shiftlen = abs(searchlen - replacelen); + int nreplaced = 0; + + if (ast_strlen_zero(scratchpad)) + return -1; /* empty scratchpad */ + if (ast_strlen_zero(search)) + return -2; /* empty searchpattern */ + if (replace == NULL) + return -3; /* replacepattern is NULL */ + + while ((replacements < 1 || replacements > nreplaced) && scratchpadp < scratchpad + scratchpadsize) { + if ((searchp = strstr(scratchpadp, search)) == NULL) + break; /* no more search strings found */ + + if (searchlen > replacelen) /* shift string left */ + for (movep = searchp + replacelen; movep < scratchpad + scratchpadsize && *(movep + shiftlen -1); movep++) + *movep = *(movep + shiftlen); + + if (searchlen < replacelen) /* shift string right */ + for (movep = scratchpad + strlen(scratchpad); movep >= searchp + searchlen; movep--) + if (movep + shiftlen < scratchpad + scratchpadsize) + *(movep + shiftlen) = *movep; + else + return -4; /* scratchpad too small for replacements */ + + movep = searchp; + replacep = replace; + while (movep < scratchpad + scratchpadsize && movep < searchp + replacelen) /* replace string */ + *movep++ = *replacep++; + + nreplaced++; + scratchpadp = searchp + replacelen; + } + return (nreplaced); +} + int ast_true(const char *s) { if (ast_strlen_zero(s))