logger.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:11k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * logger.c : file logging plugin for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2002-2008 the VideoLAN team
  5.  * $Id: 88d49624b89f64015f220b89adee23cfa1458083 $
  6.  *
  7.  * Authors: Samuel Hocevar <sam@zoy.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <vlc_common.h>
  30. #include <vlc_plugin.h>
  31. #include <vlc_interface.h>
  32. #include <vlc_playlist.h>
  33. #include <vlc_charset.h>
  34. #include <assert.h>
  35. #ifdef UNDER_CE
  36. #   define _IONBF 0x0004
  37. #endif
  38. #define MODE_TEXT 0
  39. #define MODE_HTML 1
  40. #define MODE_SYSLOG 2
  41. #ifdef __APPLE__
  42. #define LOG_DIR "Library/Logs/"
  43. #endif
  44. #define LOG_FILE_TEXT "vlc-log.txt"
  45. #define LOG_FILE_HTML "vlc-log.html"
  46. #define TEXT_HEADER "-- logger module started --n"
  47. #define TEXT_FOOTER "-- logger module stopped --n"
  48. #define HTML_HEADER 
  49.     "<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"n" 
  50.     "  "http://www.w3.org/TR/html4/strict.dtd">n" 
  51.     "<html>n" 
  52.     "  <head>n" 
  53.     "    <title>vlc log</title>n" 
  54.     "    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">n" 
  55.     "  </head>n" 
  56.     "  <body style="background-color: #000000; color: #aaaaaa;">n" 
  57.     "    <pre>n" 
  58.     "      <b>-- logger module started --</b>n"
  59. #define HTML_FOOTER 
  60.     "      <b>-- logger module stopped --</b>n" 
  61.     "    </pre>n" 
  62.     "  </body>n" 
  63.     "</html>n"
  64. #if HAVE_SYSLOG_H
  65. #include <syslog.h>
  66. #endif
  67. struct msg_cb_data_t
  68. {
  69.     intf_thread_t *p_intf;
  70.     FILE *p_file;
  71.     int   i_mode;
  72. };
  73. /*****************************************************************************
  74.  * intf_sys_t: description and status of log interface
  75.  *****************************************************************************/
  76. struct intf_sys_t
  77. {
  78.     msg_subscription_t *p_sub;
  79.     msg_cb_data_t msg;
  80. };
  81. /*****************************************************************************
  82.  * Local prototypes
  83.  *****************************************************************************/
  84. static int  Open    ( vlc_object_t * );
  85. static void Close   ( vlc_object_t * );
  86. static void Overflow (msg_cb_data_t *p_sys, msg_item_t *p_item, unsigned overruns);
  87. static void TextPrint         ( const msg_item_t *, FILE * );
  88. static void HtmlPrint         ( const msg_item_t *, FILE * );
  89. #ifdef HAVE_SYSLOG_H
  90. static void SyslogPrint       ( const msg_item_t *);
  91. #endif
  92. /*****************************************************************************
  93.  * Module descriptor
  94.  *****************************************************************************/
  95. static const char *const mode_list[] = { "text", "html"
  96. #ifdef HAVE_SYSLOG_H
  97. ,"syslog"
  98. #endif
  99. };
  100. static const char *const mode_list_text[] = { N_("Text"), "HTML"
  101. #ifdef HAVE_SYSLOG_H
  102. , "syslog"
  103. #endif
  104. };
  105. #define LOGMODE_TEXT N_("Log format")
  106. #ifdef HAVE_SYSLOG_H
  107. #define LOGMODE_LONGTEXT N_("Specify the log format. Available choices are " 
  108.   ""text" (default), "html", and "syslog" (special mode to send to " 
  109.   "syslog instead of file.")
  110. #else
  111. #define LOGMODE_LONGTEXT N_("Specify the log format. Available choices are " 
  112.   ""text" (default) and "html".")
  113. #endif
  114. vlc_module_begin ()
  115.     set_shortname( N_( "Logging" ) )
  116.     set_description( N_("File logging") )
  117.     set_category( CAT_ADVANCED )
  118.     set_subcategory( SUBCAT_ADVANCED_MISC )
  119.     add_file( "logfile", NULL, NULL,
  120.              N_("Log filename"), N_("Specify the log filename."), false )
  121.     add_string( "logmode", "text", NULL, LOGMODE_TEXT, LOGMODE_LONGTEXT,
  122.                 false )
  123.         change_string_list( mode_list, mode_list_text, 0 )
  124.     add_obsolete_string( "rrd-file" )
  125.     set_capability( "interface", 0 )
  126.     set_callbacks( Open, Close )
  127. vlc_module_end ()
  128. /*****************************************************************************
  129.  * Open: initialize and create stuff
  130.  *****************************************************************************/
  131. static int Open( vlc_object_t *p_this )
  132. {
  133.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  134.     intf_sys_t *p_sys;
  135.     char *psz_mode;
  136.     CONSOLE_INTRO_MSG;
  137.     msg_Info( p_intf, "using logger..." );
  138.     /* Allocate instance and initialize some members */
  139.     p_sys = p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
  140.     if( p_sys == NULL )
  141.         return VLC_ENOMEM;
  142.     p_sys->msg.p_intf = p_intf;
  143.     p_sys->msg.i_mode = MODE_TEXT;
  144.     psz_mode = var_CreateGetString( p_intf, "logmode" );
  145.     if( psz_mode )
  146.     {
  147.         if( !strcmp( psz_mode, "text" ) )
  148.             ;
  149.         else if( !strcmp( psz_mode, "html" ) )
  150.         {
  151.             p_sys->msg.i_mode = MODE_HTML;
  152.         }
  153. #ifdef HAVE_SYSLOG_H
  154.         else if( !strcmp( psz_mode, "syslog" ) )
  155.         {
  156.             p_sys->msg.i_mode = MODE_SYSLOG;
  157.         }
  158. #endif
  159.         else
  160.         {
  161.             msg_Warn( p_intf, "invalid log mode `%s', using `text'", psz_mode );
  162.             p_sys->msg.i_mode = MODE_TEXT;
  163.         }
  164.         free( psz_mode );
  165.     }
  166.     else
  167.     {
  168.         msg_Warn( p_intf, "no log mode specified, using `text'" );
  169.     }
  170.     if( p_sys->msg.i_mode != MODE_SYSLOG )
  171.     {
  172.         char *psz_file = config_GetPsz( p_intf, "logfile" );
  173.         if( !psz_file )
  174.         {
  175. #ifdef __APPLE__
  176.             if( asprintf( &psz_file, "%s/"LOG_DIR"/%s", config_GetHomeDir(),
  177.                 (p_sys->msg.i_mode == MODE_HTML) ? LOG_FILE_HTML
  178.                                              : LOG_FILE_TEXT ) == -1 )
  179.                 psz_file = NULL;
  180. #else
  181.             switch( p_sys->msg.i_mode )
  182.             {
  183.             case MODE_HTML:
  184.                 psz_file = strdup( LOG_FILE_HTML );
  185.                 break;
  186.             case MODE_TEXT:
  187.             default:
  188.                 psz_file = strdup( LOG_FILE_TEXT );
  189.                 break;
  190.             }
  191. #endif
  192.             msg_Warn( p_intf, "no log filename provided, using `%s'",
  193.                                psz_file );
  194.         }
  195.         /* Open the log file and remove any buffering for the stream */
  196.         msg_Dbg( p_intf, "opening logfile `%s'", psz_file );
  197.         p_sys->msg.p_file = utf8_fopen( psz_file, "at" );
  198.         if( p_sys->msg.p_file == NULL )
  199.         {
  200.             msg_Err( p_intf, "error opening logfile `%s'", psz_file );
  201.             free( p_sys );
  202.             free( psz_file );
  203.             return -1;
  204.         }
  205.         setvbuf( p_sys->msg.p_file, NULL, _IONBF, 0 );
  206.         free( psz_file );
  207.         switch( p_sys->msg.i_mode )
  208.         {
  209.         case MODE_HTML:
  210.             fputs( HTML_HEADER, p_sys->msg.p_file );
  211.             break;
  212.         case MODE_TEXT:
  213.         default:
  214.             fputs( TEXT_HEADER, p_sys->msg.p_file );
  215.             break;
  216.         }
  217.     }
  218.     else
  219.     {
  220.         p_sys->msg.p_file = NULL;
  221. #ifdef HAVE_SYSLOG_H
  222.         openlog( "vlc", LOG_PID|LOG_NDELAY, LOG_DAEMON );
  223. #endif
  224.     }
  225.     p_sys->p_sub = msg_Subscribe( p_intf->p_libvlc, Overflow, &p_sys->msg );
  226.     return 0;
  227. }
  228. /*****************************************************************************
  229.  * Close: destroy interface stuff
  230.  *****************************************************************************/
  231. static void Close( vlc_object_t *p_this )
  232. {
  233.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  234.     intf_sys_t *p_sys = p_intf->p_sys;
  235.     /* Flush the queue and unsubscribe from the message queue */
  236.     /* FIXME: flush */
  237.     msg_Unsubscribe( p_sys->p_sub );
  238.     switch( p_sys->msg.i_mode )
  239.     {
  240.     case MODE_HTML:
  241.         fputs( HTML_FOOTER, p_sys->msg.p_file );
  242.         break;
  243. #ifdef HAVE_SYSLOG_H
  244.     case MODE_SYSLOG:
  245.         closelog();
  246.         break;
  247. #endif
  248.     case MODE_TEXT:
  249.     default:
  250.         fputs( TEXT_FOOTER, p_sys->msg.p_file );
  251.         break;
  252.     }
  253.     /* Close the log file */
  254.     if( p_sys->msg.p_file )
  255.         fclose( p_sys->msg.p_file );
  256.     /* Destroy structure */
  257.     free( p_sys );
  258. }
  259. /**
  260.  * Log a message
  261.  */
  262. static void Overflow (msg_cb_data_t *p_sys, msg_item_t *p_item, unsigned overruns)
  263. {
  264.     int verbosity = var_CreateGetInteger( p_sys->p_intf, "verbose" );
  265.     int priority = 0;
  266.     switch( p_item->i_type )
  267.     {
  268.         case VLC_MSG_WARN: priority = 1; break;
  269.         case VLC_MSG_DBG:  priority = 2; break;
  270.     }
  271.     if (verbosity < priority)
  272.         return;
  273.     switch( p_sys->i_mode )
  274.     {
  275.         case MODE_HTML:
  276.             HtmlPrint( p_item, p_sys->p_file );
  277.             break;
  278. #ifdef HAVE_SYSLOG_H
  279.         case MODE_SYSLOG:
  280.             SyslogPrint( p_item );
  281.             break;
  282. #endif
  283.         case MODE_TEXT:
  284.         default:
  285.             TextPrint( p_item, p_sys->p_file );
  286.             break;
  287.     }
  288. }
  289. static const char ppsz_type[4][11] = {
  290.     ": ",
  291.     " error: ",
  292.     " warning: ",
  293.     " debug: ",
  294. };
  295. static void TextPrint( const msg_item_t *p_msg, FILE *p_file )
  296. {
  297.     fprintf( p_file, "%s%s%sn", p_msg->psz_module, ppsz_type[p_msg->i_type],
  298.              p_msg->psz_msg );
  299. }
  300. #ifdef HAVE_SYSLOG_H
  301. static void SyslogPrint( const msg_item_t *p_msg )
  302. {
  303.     static const int i_prio[4] = { LOG_INFO, LOG_ERR, LOG_WARNING, LOG_DEBUG };
  304.     int i_priority = i_prio[p_msg->i_type];
  305.     if( p_msg->psz_header )
  306.         syslog( i_priority, "%s %s%s%s", p_msg->psz_header, p_msg->psz_module,
  307.                 ppsz_type[p_msg->i_type], p_msg->psz_msg );
  308.     else
  309.         syslog( i_priority, "%s%s%s", p_msg->psz_module, 
  310.                 ppsz_type[p_msg->i_type], p_msg->psz_msg );
  311.  
  312. }
  313. #endif
  314. static void HtmlPrint( const msg_item_t *p_msg, FILE *p_file )
  315. {
  316.     static const char ppsz_color[4][30] = {
  317.         "<span style="color: #ffffff">",
  318.         "<span style="color: #ff6666">",
  319.         "<span style="color: #ffff66">",
  320.         "<span style="color: #aaaaaa">",
  321.     };
  322.     fprintf( p_file, "%s%s%s%s</span>n", p_msg->psz_module,
  323.              ppsz_type[p_msg->i_type], ppsz_color[p_msg->i_type],
  324.              p_msg->psz_msg );
  325. }