Index: Misc/NEWS =================================================================== --- Misc/NEWS (revision 80231) +++ Misc/NEWS (working copy) @@ -20,6 +20,10 @@ Library ------- +- 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. + - Issue #4814: timeout parameter is now applied also for connections resulting from PORT/EPRT commands. Index: Doc/library/syslog.rst =================================================================== --- Doc/library/syslog.rst (revision 80231) +++ Doc/library/syslog.rst (working copy) @@ -11,42 +11,66 @@ 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. + + .. 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 +88,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 80231) +++ Modules/syslogmodule.c (working copy) @@ -45,6 +45,7 @@ /* syslog module */ #include "Python.h" +#include "osdefs.h" #include @@ -52,25 +53,73 @@ static PyObject *S_ident_o = NULL; /* identifier, held by openlog() */ +static PyObject * +syslog_get_argv(void) +{ + /* get basename of sys.argv[0] */ + Py_ssize_t argv_len; + PyObject *scriptobj; + char *atslash; + PyObject *argv = PySys_GetObject("argv"); + + if (argv == NULL) { + return(NULL); + } + + argv_len = PyList_Size(argv); + if (argv_len == -1) { + PyErr_Clear(); + return(NULL); + } + if (argv_len == 0) { + return(NULL); + } + + scriptobj = PyList_GetItem(argv, 0); + if (!PyString_Check(scriptobj)) { + return(NULL); + } + if (PyString_GET_SIZE(scriptobj) == 0) { + return(NULL); + } + + atslash = strrchr(PyString_AsString(scriptobj), SEP); + if (atslash) { + return(PyString_FromString(atslash + 1)); + } else { + Py_INCREF(scriptobj); + return(scriptobj); + } + + return(NULL); +} + + 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]]", - &new_S_ident_o, &logopt, &facility)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "|Sll:openlog", keywords, &new_S_ident_o, &logopt, &facility)) return NULL; - /* This is needed because openlog() does NOT make a copy - * and syslog() later uses it.. cannot trash it. - */ + if (new_S_ident_o) { Py_INCREF(new_S_ident_o); } + + /* get either sys.argv[0] or use "python" otherwise */ + if (!new_S_ident_o) { new_S_ident_o = syslog_get_argv(); } + if (!new_S_ident_o) { new_S_ident_o = PyString_FromString("python"); } + Py_XDECREF(S_ident_o); S_ident_o = new_S_ident_o; - Py_INCREF(S_ident_o); + /* At this point, S_ident_o should be INCREF()ed. openlog(3) does not + * make a copy, and syslog(3) later uses it. We can't garbagecollect it + */ + openlog(PyString_AsString(S_ident_o), logopt, facility); Py_INCREF(Py_None); @@ -92,6 +141,16 @@ return NULL; } + /* call openlog if no current identifier */ + if (!S_ident_o) { + PyObject *openargs; + if ((openargs = PyTuple_New(0))) { + PyObject *openlog_ret = syslog_openlog(self, openargs, NULL); + Py_XDECREF(openlog_ret); + Py_DECREF(openargs); + } + } + Py_BEGIN_ALLOW_THREADS; syslog(priority, "%s", message); Py_END_ALLOW_THREADS; @@ -145,7 +204,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},