log.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright (C) 2008-2009 Andrej Stepanchuk
  3. * Copyright (C) 2009-2010 Howard Chu
  4. *
  5. * This file is part of librtmp.
  6. *
  7. * librtmp is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1,
  10. * or (at your option) any later version.
  11. *
  12. * librtmp is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with librtmp see the file COPYING. If not, write to
  19. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  20. * Boston, MA 02110-1301, USA.
  21. * http://www.gnu.org/copyleft/lgpl.html
  22. */
  23. #include <stdio.h>
  24. #include <stdarg.h>
  25. #include <string.h>
  26. #include <assert.h>
  27. #include <ctype.h>
  28. #include "rtmp_sys.h"
  29. #include "log.h"
  30. #define MAX_PRINT_LEN 2048
  31. RTMP_LogLevel RTMP_debuglevel = RTMP_LOGERROR;
  32. static int neednl;
  33. static FILE *fmsg;
  34. static RTMP_LogCallback rtmp_log_default, *cb = rtmp_log_default;
  35. static const char *levels[] = {
  36. "CRIT", "ERROR", "WARNING", "INFO",
  37. "DEBUG", "DEBUG2"
  38. };
  39. static void rtmp_log_default(int level, const char *format, va_list vl)
  40. {
  41. char str[MAX_PRINT_LEN]="";
  42. vsnprintf(str, MAX_PRINT_LEN-1, format, vl);
  43. /* Filter out 'no-name' */
  44. if ( RTMP_debuglevel<RTMP_LOGALL && strstr(str, "no-name" ) != NULL )
  45. return;
  46. if ( !fmsg ) fmsg = stderr;
  47. if ( level <= RTMP_debuglevel ) {
  48. if (neednl) {
  49. putc('\n', fmsg);
  50. neednl = 0;
  51. }
  52. fprintf(fmsg, "%s: %s\n", levels[level], str);
  53. #ifdef _DEBUG
  54. fflush(fmsg);
  55. #endif
  56. }
  57. }
  58. void RTMP_LogSetOutput(FILE *file)
  59. {
  60. fmsg = file;
  61. }
  62. void RTMP_LogSetLevel(RTMP_LogLevel level)
  63. {
  64. RTMP_debuglevel = level;
  65. }
  66. void RTMP_LogSetCallback(RTMP_LogCallback *cbp)
  67. {
  68. cb = cbp;
  69. }
  70. RTMP_LogLevel RTMP_LogGetLevel()
  71. {
  72. return RTMP_debuglevel;
  73. }
  74. void RTMP_Log(int level, const char *format, ...)
  75. {
  76. va_list args;
  77. if ( level > RTMP_debuglevel )
  78. return;
  79. va_start(args, format);
  80. cb(level, format, args);
  81. va_end(args);
  82. }
  83. static const char hexdig[] = "0123456789abcdef";
  84. void RTMP_LogHex(int level, const uint8_t *data, unsigned long len)
  85. {
  86. unsigned long i;
  87. char line[50], *ptr;
  88. if ( level > RTMP_debuglevel )
  89. return;
  90. ptr = line;
  91. for(i=0; i<len; i++) {
  92. *ptr++ = hexdig[0x0f & (data[i] >> 4)];
  93. *ptr++ = hexdig[0x0f & data[i]];
  94. if ((i & 0x0f) == 0x0f) {
  95. *ptr = '\0';
  96. ptr = line;
  97. RTMP_Log(level, "%s", line);
  98. } else {
  99. *ptr++ = ' ';
  100. }
  101. }
  102. if (i & 0x0f) {
  103. *ptr = '\0';
  104. RTMP_Log(level, "%s", line);
  105. }
  106. }
  107. void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len)
  108. {
  109. #define BP_OFFSET 9
  110. #define BP_GRAPH 60
  111. #define BP_LEN 80
  112. char line[BP_LEN];
  113. unsigned long i;
  114. if ( !data || level > RTMP_debuglevel )
  115. return;
  116. /* in case len is zero */
  117. line[0] = '\0';
  118. for ( i = 0 ; i < len ; i++ ) {
  119. int n = i % 16;
  120. unsigned off;
  121. if( !n ) {
  122. if( i ) RTMP_Log( level, "%s", line );
  123. memset( line, ' ', sizeof(line)-2 );
  124. line[sizeof(line)-2] = '\0';
  125. off = i % 0x0ffffU;
  126. line[2] = hexdig[0x0f & (off >> 12)];
  127. line[3] = hexdig[0x0f & (off >> 8)];
  128. line[4] = hexdig[0x0f & (off >> 4)];
  129. line[5] = hexdig[0x0f & off];
  130. line[6] = ':';
  131. }
  132. off = BP_OFFSET + n*3 + ((n >= 8)?1:0);
  133. line[off] = hexdig[0x0f & ( data[i] >> 4 )];
  134. line[off+1] = hexdig[0x0f & data[i]];
  135. off = BP_GRAPH + n + ((n >= 8)?1:0);
  136. if ( isprint( data[i] )) {
  137. line[BP_GRAPH + n] = data[i];
  138. } else {
  139. line[BP_GRAPH + n] = '.';
  140. }
  141. }
  142. RTMP_Log( level, "%s", line );
  143. }
  144. /* These should only be used by apps, never by the library itself */
  145. void RTMP_LogPrintf(const char *format, ...)
  146. {
  147. char str[MAX_PRINT_LEN]="";
  148. int len;
  149. va_list args;
  150. va_start(args, format);
  151. len = vsnprintf(str, MAX_PRINT_LEN-1, format, args);
  152. va_end(args);
  153. if ( RTMP_debuglevel==RTMP_LOGCRIT )
  154. return;
  155. if ( !fmsg ) fmsg = stderr;
  156. if (neednl) {
  157. putc('\n', fmsg);
  158. neednl = 0;
  159. }
  160. if (len > MAX_PRINT_LEN-1)
  161. len = MAX_PRINT_LEN-1;
  162. fprintf(fmsg, "%s", str);
  163. if (str[len-1] == '\n')
  164. fflush(fmsg);
  165. }
  166. void RTMP_LogStatus(const char *format, ...)
  167. {
  168. char str[MAX_PRINT_LEN]="";
  169. va_list args;
  170. va_start(args, format);
  171. vsnprintf(str, MAX_PRINT_LEN-1, format, args);
  172. va_end(args);
  173. if ( RTMP_debuglevel==RTMP_LOGCRIT )
  174. return;
  175. if ( !fmsg ) fmsg = stderr;
  176. fprintf(fmsg, "%s", str);
  177. fflush(fmsg);
  178. neednl = 1;
  179. }