View source with formatted comments or as raw
    1/*  Part of SWI-Prolog
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        J.Wielemaker@vu.nl
    5    WWW:           http://www.swi-prolog.org
    6    Copyright (c)  2013, VU University Amsterdam
    7    All rights reserved.
    8
    9    Redistribution and use in source and binary forms, with or without
   10    modification, are permitted provided that the following conditions
   11    are met:
   12
   13    1. Redistributions of source code must retain the above copyright
   14       notice, this list of conditions and the following disclaimer.
   15
   16    2. Redistributions in binary form must reproduce the above copyright
   17       notice, this list of conditions and the following disclaimer in
   18       the documentation and/or other materials provided with the
   19       distribution.
   20
   21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   24    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   25    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   26    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   27    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   28    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   29    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   31    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   32    POSSIBILITY OF SUCH DAMAGE.
   33*/
   34
   35:- module(syslog,
   36          [ openlog/3,                  % +Ident, +Options, +Facility
   37            syslog/2,                   % +Priority, +Message
   38            syslog/3,                   % +Priority, +Format, +Args
   39            closelog/0
   40          ]).   41
   42/** <module> Unix syslog interface
   43
   44This library provides an interface to   the  Unix syslog() facility. The
   45interface is an almost direct translation of  the POSIX syslog API, with
   46two additions:
   47
   48  - syslog/3 exploits format/3 to format syslog messages
   49  - The library integrates into library(debug) using
   50    prolog:debug_print_hook/3, where debug _topics_ are mapped to
   51    syslog _priorities_ and remaining debug _topics_ are mapped
   52    to the syslog _priority_ =debug=.
   53
   54Note that this interface  makes  no   attempt  to  abstract over logging
   55facilities of operating systems. We expect   that such abstractions will
   56be implemented at the Prolog  level   using  multiple  integrations into
   57library(debug).
   58
   59@see    detach_IO/1 to detach normal I/O of the process and remove it
   60        from the process group.
   61@see    fork/1 to create a daemon process.
   62@see    library(uid) to manage user identifiers (e.g., drop root
   63        privileges).
   64*/
   65
   66:- use_foreign_library(foreign(syslog)).   67
   68:- dynamic syslog/1.   69
   70%!  openlog(+Ident:atom, +Options:list(atom), +Facility:atom) is det.
   71%
   72%   Open system log. This predicate provides a direct interface into
   73%   the openlog() library call. If the   library call is successful,
   74%   it runs at_halt(closelog) to ensure closing   the  system log on
   75%   clean exit.
   76%
   77%   @param  Ident prepended to every message, and is typically set
   78%           to the program name.
   79%   @param  Options is a list of options.  Values are corresponding
   80%           C options, after removing =LOG_= and translation to
   81%           lower case: =cons=, =ndelay=, =nowait=, =odelay=,
   82%           =perror=, =pid=.
   83%   @param  Facility is one of =auth=, =authpriv=, =cron=, =daemon=,
   84%           =ftp=, =kern=, =local0= ... =local7=, =lpr=, =mail=,
   85%           =news=, =syslog=, =user= or =uucp=.
   86
   87openlog(Ident, Options, Facility) :-
   88    '$openlog'(Ident, Options, Facility),
   89    asserta(syslog(Ident)),
   90    at_halt(closelog).
   91
   92%!  syslog(+Priority, +Message) is det.
   93%
   94%   Send a message to the system  log. Note that syslog/2 implicitly
   95%   opens a connection to the system log   if  such a connection has
   96%   not been opened explicitly using openlog/3.
   97%
   98%   @param  Priority is one of =emerg=, =alert=, =crit=, =err=,
   99%           =warning=, =notice=, =info= or =debug=.
  100
  101%!  syslog(+Priority, +Format, +Args) is det.
  102%
  103%   Send a formatted message to the system  log if system logging is
  104%   opened using openlog/3. This predicate   combined  format/3 with
  105%   syslog/2. If there is no open  syslog connection, syslog/3 calls
  106%   print_message/2.
  107
  108syslog(Priority, Format, Args) :-
  109    syslog(_),
  110    !,
  111    format(string(Msg), Format, Args),
  112    syslog(Priority, Msg).
  113syslog(Priority, Format, Args) :-
  114    syslog_priority(Priority, Kind),
  115    print_message(Kind, format(Format, Args)).
  116
  117%!  closelog is det.
  118%
  119%   Close the system log.
  120
  121closelog :-
  122    retractall(syslog(_)),
  123    '$closelog'.
  124
  125
  126                 /*******************************
  127                 *     DEBUG INTEGRATION        *
  128                 *******************************/
  129
  130:- multifile
  131    prolog:debug_print_hook/3.  132
  133%!  prolog:debug_print_hook(+Topic, +Format, +Args) is semidet.
  134%
  135%   Integration of debug/3 with the syslog   facility.  If syslog is
  136%   enabled, debug/3 is re-routed to use   the syslog facilities. If
  137%   the _topic_ of the  debug  message   matches  one  of  the sylog
  138%   _priority_ values (see syslog/2), the message   is sent with the
  139%   corresponding syslog priority. Otherwise  it   it  sent with the
  140%   =debug= priority.
  141
  142prolog:debug_print_hook(Topic, Format, Args) :-
  143    syslog(_),
  144    debug_priority(Topic, Priority),
  145    syslog(Priority, Format, Args).
  146
  147debug_priority(Topic, Priority) :-
  148    (   syslog_priority(Topic, _Kind)
  149    ->  Priority = Topic
  150    ;   Priority = debug
  151    ).
  152
  153syslog_priority(emerg,   error).
  154syslog_priority(alert,   warning).
  155syslog_priority(crit,    error).
  156syslog_priority(err,     error).
  157syslog_priority(warning, warning).
  158syslog_priority(notice,  informational).
  159syslog_priority(info,    informational).
  160syslog_priority(debug,   debug).
  161
  162
  163                 /*******************************
  164                 *      MESSAGE INTEGRATION     *
  165                 *******************************/
  166
  167user:message_hook(Term, Kind, _) :-
  168    syslog(_),
  169    kind_syslog_priority(Kind, Level),
  170    message_to_string(Term, Message),
  171    atomic_list_concat(Lines, '\n', Message),
  172    forall(member(Line, Lines),
  173           syslog(Level, Line)),
  174    fail.
  175
  176kind_syslog_priority(error,         err).
  177kind_syslog_priority(warning,       warning).
  178kind_syslog_priority(informational, info)