Index: Misc/NEWS =================================================================== --- Misc/NEWS (revision 80195) +++ Misc/NEWS (working copy) @@ -44,7 +44,11 @@ - Issue #8374: Update the internal alias table in the :mod:`locale` module to cover recent locale changes and additions. +- Issue #8451: Syslog module now uses basename(sys.argv[0]) instead of + the string "python" as the *ident*. openlog() arguments are all optional + and keywords. + What's New in Python 2.7 beta 1? ================================ Index: Doc/library/syslog.rst =================================================================== --- Doc/library/syslog.rst (revision 80195) +++ Doc/library/syslog.rst (working copy) @@ -11,42 +11,69 @@ Refer to the Unix manual pages for a detailed description of the ``syslog`` facility. +This module wraps the system ``syslog`` module. A pure Python +library that can speak to a syslog server is available in +the :mod:`logging.handlers` module as :class:`SysLogHandler`. + The module defines the following functions: .. function:: syslog([priority,] message) - Send the string *message* to the system logger. A trailing newline is added if - necessary. Each message is tagged with a priority composed of a *facility* and - a *level*. The optional *priority* argument, which defaults to - :const:`LOG_INFO`, determines the message priority. If the facility is not - encoded in *priority* using logical-or (``LOG_INFO | LOG_USER``), the value - given in the :func:`openlog` call is used. + Send the string *message* to the system logger. A trailing newline is + added if necessary. Each message is tagged with a priority composed + of a *facility* and a *level*. The optional *priority* argument, which + defaults to :const:`LOG_INFO`, determines the message priority. If the + facility is not encoded in *priority* using logical-or (``LOG_INFO | + LOG_USER``), the value given in the :func:`openlog` call is used. + If :func:`openlog` has not been called prior to the call to + :func:'syslog', ``openlog()`` will be called with no arguments. -.. function:: openlog(ident[, logopt[, facility]]) - Logging options other than the defaults can be set by explicitly opening the log - file with :func:`openlog` prior to calling :func:`syslog`. The defaults are - (usually) *ident* = ``'syslog'``, *logopt* = ``0``, *facility* = - :const:`LOG_USER`. The *ident* argument is a string which is prepended to every - message. The optional *logopt* argument is a bit field - see below for possible - values to combine. The optional *facility* argument sets the default facility - for messages which do not have a facility explicitly encoded. +.. function:: openlog([ident[, logopt[, facility]]]) + Logging options of subsequent :func:`syslog` calls can be set by + calling :func:`openlog`. :func:`syslog` will call :func:`openlog` + with no arguments if the log is not currently open. + The optional *ident* keyword argument is a string which is prepended + to every message, and defaults to ''sys.argv[0]'' with leading path + components stripped. The optional *logopt* keyword argument (default + = 0) is a bit field - see below for possible values to combine. + The optional *facility* keyword argument (default = :const:`LOG_USER`) + sets the default facility for messages which do not have a facility + explicitly encoded. + + .. versionchanged::3.2 + In previous versions, keyword arguments were not allowed, and *ident* + was required. The default for *ident* was dependent on the system + libraries, and often was ''python'' instead of the name of the + python program file. + + .. versionchanged::2.7 + The 3.2 changes mentioned above are included in 2.7. + + .. function:: closelog() - Close the log file. + Reset the syslog module values and call the system library + ''closelog()''. + This causes the module to behave as it does when initially imported. + For example, :func:'openlog' will be called on the first :func:'syslog' + call (if :func:'openlog' hasn't already been called), and *ident* + and other :func:'openlog' parameters are reset to defaults. + .. function:: setlogmask(maskpri) - Set the priority mask to *maskpri* and return the previous mask value. Calls to - :func:`syslog` with a priority level not set in *maskpri* are ignored. The - default is to log all priorities. The function ``LOG_MASK(pri)`` calculates the - mask for the individual priority *pri*. The function ``LOG_UPTO(pri)`` - calculates the mask for all priorities up to and including *pri*. + Set the priority mask to *maskpri* and return the previous mask value. + Calls to :func:`syslog` with a priority level not set in *maskpri* + are ignored. The default is to log all priorities. The function + ``LOG_MASK(pri)`` calculates the mask for the individual priority + *pri*. The function ``LOG_UPTO(pri)`` calculates the mask for all + priorities up to and including *pri*. The module defines the following constants: @@ -64,3 +91,24 @@ :const:`LOG_PID`, :const:`LOG_CONS`, :const:`LOG_NDELAY`, :const:`LOG_NOWAIT` and :const:`LOG_PERROR` if defined in ````. + +Examples +-------- + +Simple example +~~~~~~~~~~~~~~ + +A simple set of examples:: + + import syslog + + syslog.syslog('Processing started') + if error: + syslog.syslog(syslog.LOG_ERR, 'Processing started') + +An example of setting some log options, these would include the process ID +in logged messages, and write the messages to the destination facility +used for mail logging:: + + syslog.openlog(logopt = syslog.LOG_PID, facility = syslog.LOG_MAIL) + syslog.syslog('E-mail processing initiated...') Index: Modules/syslogmodule.c =================================================================== --- Modules/syslogmodule.c (revision 80195) +++ Modules/syslogmodule.c (working copy) @@ -45,6 +45,7 @@ /* syslog module */ #include "Python.h" +#include "osdefs.h" #include @@ -53,17 +54,40 @@ static PyObject * -syslog_openlog(PyObject * self, PyObject * args) +syslog_openlog(PyObject * self, PyObject * args, PyObject *kwds) { long logopt = 0; long facility = LOG_USER; - PyObject *new_S_ident_o; + PyObject *new_S_ident_o = NULL; + static char *keywords[] = {"ident", "logoption", "facility", 0}; - if (!PyArg_ParseTuple(args, - "S|ll;ident string [, logoption [, facility]]", + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "|Sll;[ident string [, logoption [, facility]]]", keywords, &new_S_ident_o, &logopt, &facility)) return NULL; + /* if no identifier specified, use basename of sys.argv[0] */ + if (!new_S_ident_o) { + PyObject *argv = PySys_GetObject("argv"); + if (argv != NULL && PyList_Size(argv) > 0) { + PyObject *scriptobj = PyList_GetItem(argv, 0); + Py_INCREF(scriptobj); + if (PyObject_IsTrue(scriptobj) > 0) { + char *script = PyString_AsString(scriptobj); + char *atslash = strrchr(script, SEP); + if (atslash) { + new_S_ident_o = PyString_FromString(atslash + 1); + } else { + new_S_ident_o = scriptobj; + } + } + Py_DECREF(scriptobj); + } + } + if (!new_S_ident_o) { + new_S_ident_o = PyString_FromString("python"); + } + /* This is needed because openlog() does NOT make a copy * and syslog() later uses it.. cannot trash it. */ @@ -92,6 +116,16 @@ return NULL; } + /* call openlog if no current identifier */ + if (!S_ident_o) { + PyObject *openargs; + if ((openargs = PyTuple_New(0))) { + Py_INCREF(openargs); + syslog_openlog(self, openargs, NULL); + Py_DECREF(openargs); + } + } + Py_BEGIN_ALLOW_THREADS; syslog(priority, "%s", message); Py_END_ALLOW_THREADS; @@ -145,7 +179,7 @@ /* List of functions defined in the module */ static PyMethodDef syslog_methods[] = { - {"openlog", syslog_openlog, METH_VARARGS}, + {"openlog", (PyCFunction) syslog_openlog, METH_VARARGS | METH_KEYWORDS}, {"closelog", syslog_closelog, METH_NOARGS}, {"syslog", syslog_syslog, METH_VARARGS}, {"setlogmask", syslog_setlogmask, METH_VARARGS},