log.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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 "rtmp_sys.h"
  24. #include "log.h"
  25. #define MAX_PRINT_LEN 2048
  26. RTMP_LogLevel RTMP_debuglevel = RTMP_LOGERROR;
  27. static int neednl;
  28. static FILE *fmsg;
  29. static RTMP_LogCallback rtmp_log_default, *cb = rtmp_log_default;
  30. static const char *levels[] =
  31. {
  32. "CRIT", "ERROR", "WARNING", "INFO",
  33. "DEBUG", "DEBUG2"
  34. };
  35. static void rtmp_log_default(int level, const char *format, va_list vl)
  36. {
  37. char str[MAX_PRINT_LEN]="";
  38. vsnprintf(str, MAX_PRINT_LEN-1, format, vl);
  39. /* Filter out 'no-name' */
  40. if ( RTMP_debuglevel<RTMP_LOGALL && strstr(str, "no-name" ) != NULL )
  41. return;
  42. if ( !fmsg ) fmsg = stderr;
  43. if ( level <= (int)RTMP_debuglevel )
  44. {
  45. if (neednl)
  46. {
  47. putc('\n', fmsg);
  48. neednl = 0;
  49. }
  50. fprintf(fmsg, "%s: %s\n", levels[level], str);
  51. #ifdef _DEBUG
  52. fflush(fmsg);
  53. #endif
  54. }
  55. }
  56. void RTMP_LogSetOutput(FILE *file)
  57. {
  58. fmsg = file;
  59. }
  60. void RTMP_LogSetLevel(RTMP_LogLevel level)
  61. {
  62. RTMP_debuglevel = level;
  63. }
  64. void RTMP_LogSetCallback(RTMP_LogCallback *cbp)
  65. {
  66. cb = cbp;
  67. }
  68. RTMP_LogLevel RTMP_LogGetLevel()
  69. {
  70. return RTMP_debuglevel;
  71. }
  72. void RTMP_Log(int level, const char *format, ...)
  73. {
  74. va_list args;
  75. va_start(args, format);
  76. cb(level, format, args);
  77. va_end(args);
  78. }
  79. static const char hexdig[] = "0123456789abcdef";
  80. void RTMP_LogHex(int level, const uint8_t *data, unsigned long len)
  81. {
  82. unsigned long i;
  83. char line[50], *ptr;
  84. if ( level > (int)RTMP_debuglevel )
  85. return;
  86. ptr = line;
  87. for(i=0; i<len; i++)
  88. {
  89. *ptr++ = hexdig[0x0f & (data[i] >> 4)];
  90. *ptr++ = hexdig[0x0f & data[i]];
  91. if ((i & 0x0f) == 0x0f)
  92. {
  93. *ptr = '\0';
  94. ptr = line;
  95. RTMP_Log(level, "%s", line);
  96. }
  97. else
  98. {
  99. *ptr++ = ' ';
  100. }
  101. }
  102. if (i & 0x0f)
  103. {
  104. *ptr = '\0';
  105. RTMP_Log(level, "%s", line);
  106. }
  107. }
  108. void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len)
  109. {
  110. #define BP_OFFSET 9
  111. #define BP_GRAPH 60
  112. #define BP_LEN 80
  113. char line[BP_LEN];
  114. unsigned long i;
  115. if ( !data || level > (int)RTMP_debuglevel )
  116. return;
  117. /* in case len is zero */
  118. line[0] = '\0';
  119. for ( i = 0 ; i < len ; i++ )
  120. {
  121. int n = i % 16;
  122. unsigned off;
  123. if( !n )
  124. {
  125. if( i ) RTMP_Log( level, "%s", line );
  126. memset( line, ' ', sizeof(line)-2 );
  127. line[sizeof(line)-2] = '\0';
  128. off = i % 0x0ffffU;
  129. line[2] = hexdig[0x0f & (off >> 12)];
  130. line[3] = hexdig[0x0f & (off >> 8)];
  131. line[4] = hexdig[0x0f & (off >> 4)];
  132. line[5] = hexdig[0x0f & off];
  133. line[6] = ':';
  134. }
  135. off = BP_OFFSET + n*3 + ((n >= 8)?1:0);
  136. line[off] = hexdig[0x0f & ( data[i] >> 4 )];
  137. line[off+1] = hexdig[0x0f & data[i]];
  138. off = BP_GRAPH + n + ((n >= 8)?1:0);
  139. if ( isprint( data[i] ))
  140. {
  141. line[BP_GRAPH + n] = data[i];
  142. }
  143. else
  144. {
  145. line[BP_GRAPH + n] = '.';
  146. }
  147. }
  148. RTMP_Log( level, "%s", line );
  149. }
  150. /* These should only be used by apps, never by the library itself */
  151. void RTMP_LogPrintf(const char *format, ...)
  152. {
  153. char str[MAX_PRINT_LEN]="";
  154. int len;
  155. va_list args;
  156. va_start(args, format);
  157. len = vsnprintf(str, MAX_PRINT_LEN-1, format, args);
  158. va_end(args);
  159. if ( RTMP_debuglevel==RTMP_LOGCRIT )
  160. return;
  161. if ( !fmsg ) fmsg = stderr;
  162. if (neednl)
  163. {
  164. putc('\n', fmsg);
  165. neednl = 0;
  166. }
  167. if (len > MAX_PRINT_LEN-1)
  168. len = MAX_PRINT_LEN-1;
  169. fprintf(fmsg, "%s", str);
  170. if (str[len-1] == '\n')
  171. fflush(fmsg);
  172. }
  173. void RTMP_LogStatus(const char *format, ...)
  174. {
  175. char str[MAX_PRINT_LEN]="";
  176. va_list args;
  177. va_start(args, format);
  178. vsnprintf(str, MAX_PRINT_LEN-1, format, args);
  179. va_end(args);
  180. if ( RTMP_debuglevel==RTMP_LOGCRIT )
  181. return;
  182. if ( !fmsg ) fmsg = stderr;
  183. fprintf(fmsg, "%s", str);
  184. fflush(fmsg);
  185. neednl = 1;
  186. }