diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/python-systemd/_journal.c | 186 | ||||
-rw-r--r-- | src/python-systemd/journal.py | 122 |
3 files changed, 154 insertions, 155 deletions
diff --git a/Makefile.am b/Makefile.am index be97193b45..8885ab83d1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3419,6 +3419,7 @@ _journal_la_SOURCES = \ _journal_la_CFLAGS = \ $(AM_CFLAGS) \ -fvisibility=default \ + -Wno-missing-prototypes \ $(PYTHON_CFLAGS) _journal_la_LDFLAGS = \ diff --git a/src/python-systemd/_journal.c b/src/python-systemd/_journal.c index 64310a729a..c305b77ce2 100644 --- a/src/python-systemd/_journal.c +++ b/src/python-systemd/_journal.c @@ -24,135 +24,129 @@ #define SD_JOURNAL_SUPPRESS_LOCATION #include <systemd/sd-journal.h> -#include "macro.h" - PyDoc_STRVAR(journal_sendv__doc__, "sendv('FIELD=value', 'FIELD=value', ...) -> None\n\n" "Send an entry to the journal." - ); - -static PyObject * -journal_sendv(PyObject *self, PyObject *args) { - struct iovec *iov = NULL; - int argc = PyTuple_Size(args); - int i, r; - PyObject *ret = NULL; - - PyObject **encoded = calloc(argc, sizeof(PyObject*)); - if (!encoded) { - ret = PyErr_NoMemory(); - goto out1; - } - - // Allocate sufficient iovector space for the arguments. - iov = malloc(argc * sizeof(struct iovec)); - if (!iov) { - ret = PyErr_NoMemory(); - goto out; - } - - // Iterate through the Python arguments and fill the iovector. - for (i = 0; i < argc; ++i) { - PyObject *item = PyTuple_GetItem(args, i); - char *stritem; - Py_ssize_t length; - - if (PyUnicode_Check(item)) { - encoded[i] = PyUnicode_AsEncodedString(item, "utf-8", "strict"); - if (encoded[i] == NULL) - goto out; - item = encoded[i]; - } - if (PyBytes_AsStringAndSize(item, &stritem, &length)) - goto out; +); - iov[i].iov_base = stritem; - iov[i].iov_len = length; - } +static PyObject *journal_sendv(PyObject *self, PyObject *args) { + struct iovec *iov = NULL; + int argc; + int i, r; + PyObject *ret = NULL; + PyObject **encoded; - // Clear errno, because sd_journal_sendv will not set it by - // itself, unless an error occurs in one of the system calls. - errno = 0; + argc = PyTuple_Size(args); - // Send the iovector to the journal. - r = sd_journal_sendv(iov, argc); + encoded = calloc(argc, sizeof(PyObject*)); + if (!encoded) { + ret = PyErr_NoMemory(); + goto out1; + } - if (r) { - if (errno) - PyErr_SetFromErrno(PyExc_IOError); - else - PyErr_SetString(PyExc_ValueError, "invalid message format"); - goto out; - } + /* Allocate sufficient iovector space for the arguments. */ + iov = malloc(argc * sizeof(struct iovec)); + if (!iov) { + ret = PyErr_NoMemory(); + goto out; + } - // End with success. - Py_INCREF(Py_None); - ret = Py_None; + /* Iterate through the Python arguments and fill the iovector. */ + for (i = 0; i < argc; ++i) { + PyObject *item = PyTuple_GetItem(args, i); + char *stritem; + Py_ssize_t length; + + if (PyUnicode_Check(item)) { + encoded[i] = PyUnicode_AsEncodedString(item, "utf-8", "strict"); + if (encoded[i] == NULL) + goto out; + item = encoded[i]; + } + if (PyBytes_AsStringAndSize(item, &stritem, &length)) + goto out; + + iov[i].iov_base = stritem; + iov[i].iov_len = length; + } + + /* Clear errno, because sd_journal_sendv will not set it by + itself, unless an error occurs in one of the system calls. */ + errno = 0; + + /* Send the iovector to the journal. */ + r = sd_journal_sendv(iov, argc); + if (r) { + if (errno) + PyErr_SetFromErrno(PyExc_IOError); + else + PyErr_SetString(PyExc_ValueError, "invalid message format"); + goto out; + } + + /* End with success. */ + Py_INCREF(Py_None); + ret = Py_None; out: - for (i = 0; i < argc; ++i) - Py_XDECREF(encoded[i]); + for (i = 0; i < argc; ++i) + Py_XDECREF(encoded[i]); - free(encoded); + free(encoded); out1: - // Free the iovector. The actual strings - // are already managed by Python. - free(iov); + /* Free the iovector. The actual strings + are already managed by Python. */ + free(iov); - return ret; + return ret; } PyDoc_STRVAR(journal_stream_fd__doc__, "stream_fd(identifier, priority, level_prefix) -> fd\n\n" "Open a stream to journal by calling sd_journal_stream_fd(3)." - ); - -static PyObject* -journal_stream_fd(PyObject *self, PyObject *args) { - const char* identifier; - int priority, level_prefix; - int fd; - if (!PyArg_ParseTuple(args, "sii:stream_fd", - &identifier, &priority, &level_prefix)) - return NULL; - - fd = sd_journal_stream_fd(identifier, priority, level_prefix); - if (fd < 0) - return PyErr_SetFromErrno(PyExc_IOError); - - return PyLong_FromLong(fd); +); + +static PyObject* journal_stream_fd(PyObject *self, PyObject *args) { + const char* identifier; + int priority, level_prefix; + int fd; + + if (!PyArg_ParseTuple(args, "sii:stream_fd", + &identifier, &priority, &level_prefix)) + return NULL; + + fd = sd_journal_stream_fd(identifier, priority, level_prefix); + if (fd < 0) + return PyErr_SetFromErrno(PyExc_IOError); + + return PyLong_FromLong(fd); } static PyMethodDef methods[] = { - {"sendv", journal_sendv, METH_VARARGS, journal_sendv__doc__}, - {"stream_fd", journal_stream_fd, METH_VARARGS, - journal_stream_fd__doc__}, - {NULL, NULL, 0, NULL} /* Sentinel */ + { "sendv", journal_sendv, METH_VARARGS, journal_sendv__doc__ }, + { "stream_fd", journal_stream_fd, METH_VARARGS, journal_stream_fd__doc__ }, + { NULL, NULL, 0, NULL } /* Sentinel */ }; #if PY_MAJOR_VERSION < 3 -PyMODINIT_FUNC -init_journal(void) -{ - (void) Py_InitModule("_journal", methods); +PyMODINIT_FUNC init_journal(void) { + (void) Py_InitModule("_journal", methods); } #else static struct PyModuleDef module = { - PyModuleDef_HEAD_INIT, - "_journal", /* name of module */ - NULL, /* module documentation, may be NULL */ - 0, /* size of per-interpreter state of the module */ - methods + PyModuleDef_HEAD_INIT, + "_journal", /* name of module */ + NULL, /* module documentation, may be NULL */ + 0, /* size of per-interpreter state of the module */ + methods }; -PyMODINIT_FUNC -PyInit__journal(void) -{ - return PyModule_Create(&module); +PyMODINIT_FUNC PyInit__journal(void) { + return PyModule_Create(&module); } #endif diff --git a/src/python-systemd/journal.py b/src/python-systemd/journal.py index 0f8a330305..760d2db014 100644 --- a/src/python-systemd/journal.py +++ b/src/python-systemd/journal.py @@ -24,89 +24,93 @@ from syslog import (LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, from ._journal import sendv, stream_fd def _make_line(field, value): - if isinstance(value, bytes): - return field.encode('utf-8') + b'=' + value - else: - return field + '=' + value + if isinstance(value, bytes): + return field.encode('utf-8') + b'=' + value + else: + return field + '=' + value def send(MESSAGE, MESSAGE_ID=None, CODE_FILE=None, CODE_LINE=None, CODE_FUNC=None, **kwargs): - r"""Send a message to journald. + r"""Send a message to journald. - >>> journal.send('Hello world') - >>> journal.send('Hello, again, world', FIELD2='Greetings!') - >>> journal.send('Binary message', BINARY=b'\xde\xad\xbe\xef') + >>> journal.send('Hello world') + >>> journal.send('Hello, again, world', FIELD2='Greetings!') + >>> journal.send('Binary message', BINARY=b'\xde\xad\xbe\xef') - Value of the MESSAGE argument will be used for the MESSAGE= field. + Value of the MESSAGE argument will be used for the MESSAGE= + field. - MESSAGE_ID can be given to uniquely identify the type of message. + MESSAGE_ID can be given to uniquely identify the type of + message. - Other parts of the message can be specified as keyword arguments. + Other parts of the message can be specified as keyword + arguments. - Both MESSAGE and MESSAGE_ID, if present, must be strings, and will - be sent as UTF-8 to journal. Other arguments can be bytes, in - which case they will be sent as-is to journal. + Both MESSAGE and MESSAGE_ID, if present, must be strings, and + will be sent as UTF-8 to journal. Other arguments can be + bytes, in which case they will be sent as-is to journal. - CODE_LINE, CODE_FILE, and CODE_FUNC can be specified to identify - the caller. Unless at least on of the three is given, values are - extracted from the stack frame of the caller of send(). CODE_FILE - and CODE_FUNC must be strings, CODE_LINE must be an integer. + CODE_LINE, CODE_FILE, and CODE_FUNC can be specified to + identify the caller. Unless at least on of the three is given, + values are extracted from the stack frame of the caller of + send(). CODE_FILE and CODE_FUNC must be strings, CODE_LINE + must be an integer. - Other useful fields include PRIORITY, SYSLOG_FACILITY, - SYSLOG_IDENTIFIER, SYSLOG_PID. - """ + Other useful fields include PRIORITY, SYSLOG_FACILITY, + SYSLOG_IDENTIFIER, SYSLOG_PID. + """ - args = ['MESSAGE=' + MESSAGE] + args = ['MESSAGE=' + MESSAGE] - if MESSAGE_ID is not None: - args.append('MESSAGE_ID=' + MESSAGE_ID) + if MESSAGE_ID is not None: + args.append('MESSAGE_ID=' + MESSAGE_ID) - if CODE_LINE == CODE_FILE == CODE_FUNC == None: - CODE_FILE, CODE_LINE, CODE_FUNC = \ - _traceback.extract_stack(limit=2)[0][:3] - if CODE_FILE is not None: - args.append('CODE_FILE=' + CODE_FILE) - if CODE_LINE is not None: - args.append('CODE_LINE={:d}'.format(CODE_LINE)) - if CODE_FUNC is not None: - args.append('CODE_FUNC=' + CODE_FUNC) + if CODE_LINE == CODE_FILE == CODE_FUNC == None: + CODE_FILE, CODE_LINE, CODE_FUNC = \ + _traceback.extract_stack(limit=2)[0][:3] + if CODE_FILE is not None: + args.append('CODE_FILE=' + CODE_FILE) + if CODE_LINE is not None: + args.append('CODE_LINE={:d}'.format(CODE_LINE)) + if CODE_FUNC is not None: + args.append('CODE_FUNC=' + CODE_FUNC) - args.extend(_make_line(key, val) for key, val in kwargs.items()) - return sendv(*args) + args.extend(_make_line(key, val) for key, val in kwargs.items()) + return sendv(*args) def stream(identifier, priority=LOG_DEBUG, level_prefix=False): - r"""Return a file object wrapping a stream to journal. + r"""Return a file object wrapping a stream to journal. - Log messages written to this file as simple newline sepearted - text strings are written to the journal. + Log messages written to this file as simple newline sepearted + text strings are written to the journal. - The file will be line buffered, so messages are actually sent - after a newline character is written. + The file will be line buffered, so messages are actually sent + after a newline character is written. - >>> stream = journal.stream('myapp') - >>> stream - <open file '<fdopen>', mode 'w' at 0x...> - >>> stream.write('message...\n') + >>> stream = journal.stream('myapp') + >>> stream + <open file '<fdopen>', mode 'w' at 0x...> + >>> stream.write('message...\n') - will produce the following message in the journal: + will produce the following message in the journal: - PRIORITY=7 - SYSLOG_IDENTIFIER=myapp - MESSAGE=message... + PRIORITY=7 + SYSLOG_IDENTIFIER=myapp + MESSAGE=message... - Using the interface with print might be more convinient: + Using the interface with print might be more convinient: - >>> from __future__ import print_function - >>> print('message...', file=stream) + >>> from __future__ import print_function + >>> print('message...', file=stream) - priority is the syslog priority, one of LOG_EMERG, LOG_ALERT, - LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG. + priority is the syslog priority, one of LOG_EMERG, LOG_ALERT, + LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG. - level_prefix is a boolean. If true, kernel-style log priority - level prefixes (such as '<1>') are interpreted. See sd-daemon(3) - for more information. - """ + level_prefix is a boolean. If true, kernel-style log priority + level prefixes (such as '<1>') are interpreted. See + sd-daemon(3) for more information. + """ - fd = stream_fd(identifier, priority, level_prefix) - return _os.fdopen(fd, 'w', 1) + fd = stream_fd(identifier, priority, level_prefix) + return _os.fdopen(fd, 'w', 1) |