mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Port of issue8451 to python3: Syslog use sys.argv[0] for ident.
This commit is contained in:
		
							parent
							
								
									2c4f98b3c5
								
							
						
					
					
						commit
						13daf12b47
					
				
					 3 changed files with 159 additions and 35 deletions
				
			
		| 
						 | 
				
			
			@ -10,42 +10,66 @@ This module provides an interface to the Unix ``syslog`` library routines.
 | 
			
		|||
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]])
 | 
			
		||||
.. 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.
 | 
			
		||||
   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:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -63,3 +87,24 @@ Log options:
 | 
			
		|||
   :const:`LOG_PID`, :const:`LOG_CONS`, :const:`LOG_NDELAY`, :const:`LOG_NOWAIT`
 | 
			
		||||
   and :const:`LOG_PERROR` if defined in ``<syslog.h>``.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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...')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -329,6 +329,10 @@ C-API
 | 
			
		|||
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 #8108: Fix the unwrap() method of SSL objects when the socket has
 | 
			
		||||
  a non-infinite timeout.  Also make that method friendlier with applications
 | 
			
		||||
  wanting to continue using the socket in clear-text mode, by disabling
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,11 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		|||
 | 
			
		||||
Revision history:
 | 
			
		||||
 | 
			
		||||
2010/04/20 (Sean Reifschneider)
 | 
			
		||||
  - Use basename(sys.argv[0]) for the default "ident".
 | 
			
		||||
  - Arguments to openlog() are now keyword args and are all optional.
 | 
			
		||||
  - syslog() calls openlog() if it hasn't already been called.
 | 
			
		||||
 | 
			
		||||
1998/04/28 (Sean Reifschneider)
 | 
			
		||||
  - When facility not specified to syslog() method, use default from openlog()
 | 
			
		||||
    (This is how it was claimed to work in the documentation)
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +50,7 @@ Revision history:
 | 
			
		|||
/* syslog module */
 | 
			
		||||
 | 
			
		||||
#include "Python.h"
 | 
			
		||||
#include "osdefs.h"
 | 
			
		||||
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -52,30 +58,83 @@ Revision history:
 | 
			
		|||
static PyObject *S_ident_o = NULL;			/*  identifier, held by openlog()  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static PyObject *
 | 
			
		||||
syslog_get_argv(void)
 | 
			
		||||
{
 | 
			
		||||
	/* Figure out what to use for as the program "ident" for openlog().
 | 
			
		||||
	 * This swallows exceptions and continues rather than failing out,
 | 
			
		||||
	 * because the syslog module can still be used because openlog(3)
 | 
			
		||||
	 * is optional.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	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 (!PyUnicode_Check(scriptobj)) {
 | 
			
		||||
		return(NULL);
 | 
			
		||||
	}
 | 
			
		||||
	if (PyUnicode_GET_SIZE(scriptobj) == 0) {
 | 
			
		||||
		return(NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	atslash = strrchr(_PyUnicode_AsString(scriptobj), SEP);
 | 
			
		||||
	if (atslash) {
 | 
			
		||||
		return(PyUnicode_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;
 | 
			
		||||
	const char *ident;
 | 
			
		||||
	PyObject *new_S_ident_o = NULL;
 | 
			
		||||
	static char *keywords[] = {"ident", "logoption", "facility", 0};
 | 
			
		||||
 | 
			
		||||
	if (!PyArg_ParseTuple(args,
 | 
			
		||||
			      "U|ll;ident string [, logoption [, facility]]",
 | 
			
		||||
			      &new_S_ident_o, &logopt, &facility))
 | 
			
		||||
	if (!PyArg_ParseTupleAndKeywords(args, kwds,
 | 
			
		||||
			      "|Ull: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 sys.argv[0] or NULL if we can't for some reason  */
 | 
			
		||||
	if (!new_S_ident_o) {
 | 
			
		||||
		new_S_ident_o = syslog_get_argv();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	Py_XDECREF(S_ident_o);
 | 
			
		||||
	S_ident_o = new_S_ident_o;
 | 
			
		||||
	Py_INCREF(S_ident_o);
 | 
			
		||||
 | 
			
		||||
	ident = _PyUnicode_AsString(S_ident_o);
 | 
			
		||||
	if (ident == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	openlog(ident, logopt, facility);
 | 
			
		||||
	/* 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
 | 
			
		||||
	 * If NULL, just let openlog figure it out (probably using C argv[0]).
 | 
			
		||||
	 */
 | 
			
		||||
 
 | 
			
		||||
	openlog(S_ident_o ? _PyUnicode_AsString(S_ident_o) : NULL, logopt, facility);
 | 
			
		||||
 | 
			
		||||
	Py_INCREF(Py_None);
 | 
			
		||||
	return Py_None;
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +159,22 @@ syslog_syslog(PyObject * self, PyObject * args)
 | 
			
		|||
	message = _PyUnicode_AsString(message_object);
 | 
			
		||||
	if (message == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	/*  call openlog if no current identifier  */
 | 
			
		||||
	if (!S_ident_o) {
 | 
			
		||||
		PyObject *openargs;
 | 
			
		||||
 | 
			
		||||
		/* Continue even if PyTuple_New fails, because openlog(3) is optional.
 | 
			
		||||
		 * So, we can still do loggin in the unlikely event things are so hosed
 | 
			
		||||
		 * that we can't do this tuple.
 | 
			
		||||
		 */
 | 
			
		||||
		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;
 | 
			
		||||
| 
						 | 
				
			
			@ -152,7 +227,7 @@ syslog_log_upto(PyObject *self, PyObject *args)
 | 
			
		|||
/* 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},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue