Added MarcXchange support.
[yaz-moved-to-github.git] / doc / tools.xml
index 9385c8a..d9a57b7 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Id: tools.xml,v 1.38 2004-10-02 13:41:46 adam Exp $ -->
+<!-- $Id: tools.xml,v 1.44 2005-02-08 13:51:30 adam Exp $ -->
  <chapter id="tools"><title>Supporting Tools</title>
   
   <para>
@@ -1796,6 +1796,155 @@ typedef struct oident
 
   </sect1>
 
+  <sect1 id="tools.log"><title>Log</title>
+  <para>
+   &yaz; has evolved a fairly complex log system which should be useful both 
+   for debugging &yaz; itself, debugging applications that use &yaz;, and for
+   production use of those applications.  
+  </para>
+  <para>
+   The log functions are declared in header <filename>yaz/log.h</filename>
+    and implemented in <filename>src/log.c</filename>.
+    Due to name clash with syslog and some math utilities the logging
+    interface has been modified as of YAZ 2.0.29. The obsolete interface
+    is still available if in header file <filename>yaz/log.h</filename>.
+    The key points of the interface are:
+  </para>
+  <screen>
+   void yaz_log(int level, const char *fmt, ...)
+
+   void yaz_log_init(int level, const char *prefix, const char *name);
+   void yaz_log_init_file(const char *fname);
+   void yaz_log_init_level(int level);
+   void yaz_log_init_prefix(const char *prefix);
+   void yaz_log_time_format(const char *fmt);
+   void yaz_log_init_max_size(int mx);
+
+   int yaz_log_mask_str(const char *str);
+   int yaz_log_module_level(const char *name);
+  </screen>
+
+  <para>
+   The reason for the whole log module is the <function>yaz_log</function>
+   function. It takes a bitmask indicating the log levels, a
+   <literal>printf</literal>-like format string, and a variable number of
+   arguments to log.
+  </para>
+
+  <para>
+   The <literal>log level</literal> is a bit mask, that says on which level(s)
+   the log entry should be made, and optionally set some behaviour of the
+   logging. In the most simple cases, it can be one of <literal>YLOG_FATAL,
+   YLOG_DEBUG, YLOG_WARN, YLOG_LOG</literal>. Those can be combined with bits
+   that modify the way the log entry is written:<literal>YLOG_ERRNO,
+   YLOG_NOTIME, YLOG_FLUSH</literal>.
+   Most of the rest of the bits are deprecated, and should not be used. Use
+   the dynamic log levels instead.
+  </para>
+
+  <para>
+   Applications that use &yaz;, should not use the LOG_LOG for ordinary
+   messages, but should make use of the dynamic loglevel system. This consists
+   of two parts, defining the loglevel and checking it.
+  </para>
+
+  <para>
+   To define the log levels, the (main) program should pass a string to
+   <function>yaz_log_mask_str</function> to define which log levels are to be
+   logged. This string should be a comma-separated list of log level names,
+   and can contain both hard-coded names and dynamic ones. The log level
+   calculation starts with <literal>YLOG_DEFAULT_LEVEL</literal> and adds a bit
+   for each word it meets, unless the word starts with a '-', in which case it 
+   clears the bit. If the string <literal>'none'</literal> is found,
+   all bits are cleared. Typically this string comes from the command-line,
+   often identified by <literal>-v</literal>. The
+   <function>yaz_log_mask_str</function> returns a log level that should be
+   passed to <function>yaz_log_init_level</function> for it to take effect.
+  </para>
+
+  <para>
+   Each module should check what log bits it should be used, by calling 
+   <function>yaz_log_module_level</function> with a suitable name for the
+   module. The name is cleared from a preceding path and an extension, if any,
+   so it is quite possible to use <literal>__FILE__</literal> for it. If the
+   name has been passed to <function>yaz_log_mask_str</function>, the routine
+   returns a non-zero bitmask, which should then be used in consequent calls
+   to yaz_log. (It can also be tested, so as to avoid unnecessary calls to
+   yaz_log, in time-critical places, or when the log entry would take time 
+   to construct.) 
+  </para>
+
+  <para>
+   Yaz uses the following dynamic log levels:
+   <literal>server, session, request, requestdetail</literal> for the server
+   functionality.
+   <literal>zoom</literal> for the zoom client api.
+   <literal>ztest</literal> for the simple test server.
+   <literal>malloc, nmem, odr, eventl</literal> for internal debugging of yaz itself.
+   Of course, any program using yaz is welcome to define as many new ones, as
+   it needs.
+  </para>
+
+  <para>
+   By default the log is written to stderr, but this can be changed by a call
+   to <function>yaz_log_init_file</function> or
+   <function>yaz_log_init</function>. If the log is directed to a file, the
+   file size is checked at every write, and if it exceeds the limit given in
+   <function>yaz_log_init_max_size</function>, the log is rotated. The
+   rotation keeps one old version (with a <literal>.1</literal> appended to
+   the name). The size defaults to 1GB. Setting it to zero will disable the
+   rotation feature.
+  </para>
+
+  <screen>
+  A typical yaz-log looks like this
+  13:23:14-23/11 yaz-ztest(1) [session] Starting session from tcp:127.0.0.1 (pid=30968)
+  13:23:14-23/11 yaz-ztest(1) [request] Init from 'YAZ' (81) (ver 2.0.28) OK
+  13:23:17-23/11 yaz-ztest(1) [request] Search Z: @attrset Bib-1 foo  OK:7 hits
+  13:23:22-23/11 yaz-ztest(1) [request] Present: [1] 2+2  OK 2 records returned
+  13:24:13-23/11 yaz-ztest(1) [request] Close OK
+  </screen>
+
+  <para>
+   The log entries start with a time stamp. This can be omitted by setting the
+   <literal>YLOG_NOTIME</literal> bit in the loglevel. This way automatic tests
+   can be hoped to produce identical log files, that are easy to diff. The
+   format of the time stamp can be set with
+   <function>yaz_log_time_format</function>, which takes a format string just
+   like <function>strftime</function>.
+  </para>
+
+  <para>
+   Next in a log line comes the prefix, often the name of the program. For
+   yaz-based servers, it can also contain the session number. Then
+   comes one or more logbits in square brackets, depending on the logging
+   level set by <function>yaz_log_init_level</function> and the loglevel
+   passed to <function>yaz_log_init_level</function>. Finally comes the format
+   string and additional values passed to <function>yaz_log</function>
+  </para>
+
+  <para>
+   The log level <literal>YLOG_LOGLVL</literal>, enabled by the string
+   <literal>loglevel</literal>, will log all the log-level affecting
+   operations. This can come in handy if you need to know what other log
+   levels would be useful. Grep the logfile for <literal>[loglevel]</literal>.
+  </para>
+
+  <para>
+   The log system is almost independent of the rest of &yaz;, the only
+   important dependence is of <filename>nmem</filename>, and that only for
+   using the semaphore definition there. 
+  </para>
+
+  <para>
+   The dynamic log levels and log rotation were introduced in &yaz; 2.0.28. At
+   the same time, the log bit names were changed from
+   <literal>LOG_something</literal> to <literal>YLOG_something</literal>, 
+   to avoid collision with <filename>syslog.h</filename>.
+  </para>
+
+  </sect1>
+  
   <sect1 id="tools.marc"><title>MARC</title>
    
    <para>
@@ -1818,6 +1967,7 @@ typedef struct oident
     #define YAZ_MARC_OAIMARC   2
     #define YAZ_MARC_MARCXML   3
     #define YAZ_MARC_ISO2709   4
+    #define YAZ_MARC_XCHANGE   5
 
     /* supply iconv handle for character set conversion .. */
     void yaz_marc_iconv(yaz_marc_t mt, yaz_iconv_t cd);