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 142prologdebug_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)